zoukankan      html  css  js  c++  java
  • maven+selenium+java+testng+jenkins自动化测试

    最近在公司搭建了一套基于maven+selenium+java+testng+jenkins的自动化测试框架,免得以后重写记录下

    工程目录

    pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>Realinsight4.0</groupId>
        <artifactId>Realinsight4.0</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>Realinsight4.0</name>
    
        <dependencies>
            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-java</artifactId>
                <version>3.141.59</version>
            </dependency>
            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-server</artifactId>
                <version>3.141.59</version>
            </dependency>
            <dependency>
                <groupId>org.testng</groupId>
                <artifactId>testng</artifactId>
                <version>6.14.3</version>
        
            </dependency>
            <dependency>
                <groupId>org.uncommons</groupId>
                <artifactId>reportng</artifactId>
                <version>1.1.4</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.testng</groupId>
                        <artifactId>testng</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>com.google.inject</groupId>
                <artifactId>guice</artifactId>
                <version>3.0</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.6</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
            <dependency>
                <groupId>com.aventstack</groupId>
                <artifactId>extentreports</artifactId>
                <version>3.1.2</version>
            </dependency>
            <dependency>
                <groupId>com.relevantcodes</groupId>
                <artifactId>extentreports</artifactId>
                <version>2.40.2</version>
            </dependency>
            <dependency>
                <groupId>com.vimalselvam</groupId>
                <artifactId>testng-extentsreport</artifactId>
                <version>1.3.1</version>
            </dependency>
        </dependencies>
    
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.17</version>
                    <configuration>
                        <suiteXmlFiles>
                            <suiteXmlFile>testng.xml</suiteXmlFile>
                        </suiteXmlFiles>
                    </configuration>
                </plugin>
            <!--    
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.5</version>
                    <configuration>
                        <properties>
                            <property>
                                <name>usedefaultlisteners</name>
                                <value>false</value>
                            </property>
                            <property>
                                <name>listener</name>
                                <value>org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter</value>
                            </property>
                        </properties>
                        <workingDirectory></workingDirectory>
                        
                    </configuration>
                </plugin>
    -->
            </plugins>
        </build>
    
    
    </project>
    View Code

    testng.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="Realinsight4.0">
    <listeners>    
    <listener class-name="utils.RetryListener" />
    <listener class-name="utils.TestngListener" />
    <listener class-name="utils.ExtentReporterListener" />
    </listeners>
      <test name="登陆测试" verbose="10" preserve-order="true">
        <classes>
          <class name="testcase.login.login"/>
          <class name="testcase.login.loginWithParas"/>
          <class name="testcase.login.createAccount"/>
          <class name="testcase.login.lockAccount"/>
          <class name="testcase.login.resetPwd"/>
          <class name="testcase.login.logout"/>
        </classes>
      </test>     
    <test name="数据集测试" verbose="10" preserve-order="true">
        <classes>
          <class name="testcase.boardsheet.UploadData"/>
          <class name="testcase.boardsheet.AggRegate"/>
          <class name="testcase.boardsheet.AppendData"/>
          <class name="testcase.boardsheet.CreatBySQL"/>
          <class name="testcase.boardsheet.AppendMerge"/>
          <class name="testcase.boardsheet.DimensionalityReduction"/>
          <class name="testcase.boardsheet.ReplaceData"/>
        </classes>
      </test> 
       <test name="仪表板测试" verbose="10" preserve-order="true">
        <classes>
          <class name="testcase.dashboard.CreateDashBoard"/>
          <class name="testcase.dashboard.CreateChart"/>
          <class name="testcase.dashboard.ChartOperation"/>
          <class name="testcase.dashboard.TextOperation"/>
        </classes>
      </test> 
       <test name="刪除数据" verbose="10" preserve-order="true">
        <classes>
          <class name="testcase.boardsheet.Deleteboardsheet"/>
        </classes>
      </test> 
    </suite> <!-- Suite -->
    View Code

    log4j.properties

    log4j.rootCategory=INFO, stdout , R   
     
    log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppenderu00A0
    log4j.appender.Threshold = DEBUGu00A0
    log4j.appender.CONSOLE.Target = System.outu00A0
    log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayoutu00A0
    log4j.appender.CONSOLE.layout.ConversionPattern = [framework] % d - % c -%- 4r [ % t] %- 5p % c % x - % m % nu00A0
    
    --------------------- 
    u4F5Cu8005uFF1AJXNUleo 
    u6765u6E90uFF1ACSDN 
    u539Fu6587uFF1Ahttps://blog.csdn.net/m0_37874657/article/details/80536086 
    u7248u6743u58F0u660EuFF1Au672Cu6587u4E3Au535Au4E3Bu539Fu521Bu6587u7AE0uFF0Cu8F6Cu8F7Du8BF7u9644u4E0Au535Au6587u94FEu63A5uFF01  
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender   
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout   
    log4j.appender.stdout.layout.ConversionPattern=[YG] %p [%t] %C.%M(%L) | %m%n   
        
    log4j.appender.R=org.apache.log4j.DailyRollingFileAppender   
    log4j.appender.R.File=${project}/WEB-INF/logs/app.log  
    log4j.appender.R.layout=org.apache.log4j.PatternLayout   
    1log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n   
       
    log4j.logger.com.neusoft=DEBUG   
    log4j.logger.com.opensymphony.oscache=ERROR   
    log4j.logger.net.sf.navigator=ERROR   
    log4j.logger.org.apache.commons=ERROR   
    log4j.logger.org.apache.struts=WARN   
    log4j.logger.org.displaytag=ERROR   
    log4j.logger.org.springframework=DEBUG   
    log4j.logger.com.ibatis.db=WARN   
    log4j.logger.org.apache.velocity=FATAL   
       
    log4j.logger.com.canoo.webtest=WARN   
       
    log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN   
    log4j.logger.org.hibernate=DEBUG   
    log4j.logger.org.logicalcobwebs=WARN  
    
    log4j.rootCategory=INFO, stdout , R
    
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n
     
    log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.R.File=D:\logs\YG.log 
    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    1log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
    
    log4j.logger.com.neusoft=DEBUG
    log4j.logger.com.opensymphony.oscache=ERROR
    log4j.logger.net.sf.navigator=ERROR
    log4j.logger.org.apache.commons=ERROR
    log4j.logger.org.apache.struts=WARN
    log4j.logger.org.displaytag=ERROR
    log4j.logger.org.springframework=DEBUG
    log4j.logger.com.ibatis.db=WARN
    log4j.logger.org.apache.velocity=FATAL
    
    log4j.logger.com.canoo.webtest=WARN
    
    log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN
    log4j.logger.org.hibernate=DEBUG
    log4j.logger.org.logicalcobwebs=WARN
    View Code

    ExtentReporterListener.java

    package utils;
    
    import com.aventstack.extentreports.ExtentReports;
    import com.aventstack.extentreports.ExtentTest;
    import com.aventstack.extentreports.ResourceCDN;
    import com.aventstack.extentreports.Status;
    import com.aventstack.extentreports.model.TestAttribute;
    import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
    import com.aventstack.extentreports.reporter.configuration.ChartLocation;
    import com.aventstack.extentreports.reporter.configuration.Theme;
    import org.testng.*;
    import org.testng.xml.XmlSuite;
    
    import java.io.File;
    import java.util.*;
    
    public class ExtentReporterListener implements IReporter {
        //生成的路径以及文件名
        private static final String OUTPUT_FOLDER = "test-output/";
        private static final String FILE_NAME = "index.html";
    
        private ExtentReports extent;
    
        @Override
        public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
            init();
            boolean createSuiteNode = false;
            if(suites.size()>1){
                createSuiteNode=true;
            }
            for (ISuite suite : suites) {
                Map<String, ISuiteResult> result = suite.getResults();
                //如果suite里面没有任何用例,直接跳过,不在报告里生成
                if(result.size()==0){
                    continue;
                }
                //统计suite下的成功、失败、跳过的总用例数
                int suiteFailSize=0;
                int suitePassSize=0;
                int suiteSkipSize=0;
                ExtentTest suiteTest=null;
                //存在多个suite的情况下,在报告中将同一个一个suite的测试结果归为一类,创建一级节点。
                if(createSuiteNode){
                    suiteTest = extent.createTest(suite.getName()).assignCategory(suite.getName());
                }
                boolean createSuiteResultNode = false;
                if(result.size()>1){
                    createSuiteResultNode=true;
                }
                for (ISuiteResult r : result.values()) {
                    ExtentTest resultNode;
                    ITestContext context = r.getTestContext();
                    if(createSuiteResultNode){
                        //没有创建suite的情况下,将在SuiteResult的创建为一级节点,否则创建为suite的一个子节点。
                        if( null == suiteTest){
                            resultNode = extent.createTest(r.getTestContext().getName());
                        }else{
                            resultNode = suiteTest.createNode(r.getTestContext().getName());
                        }
                    }else{
                        resultNode = suiteTest;
                    }
                    if(resultNode != null){
                        resultNode.getModel().setName(suite.getName()+" : "+r.getTestContext().getName());
                        if(resultNode.getModel().hasCategory()){
                            resultNode.assignCategory(r.getTestContext().getName());
                        }else{
                            resultNode.assignCategory(suite.getName(),r.getTestContext().getName());
                        }
                        resultNode.getModel().setStartTime(r.getTestContext().getStartDate());
                        resultNode.getModel().setEndTime(r.getTestContext().getEndDate());
                        //统计SuiteResult下的数据
                        int passSize = r.getTestContext().getPassedTests().size();
                        int failSize = r.getTestContext().getFailedTests().size();
                        int skipSize = r.getTestContext().getSkippedTests().size();
                        suitePassSize += passSize;
                        suiteFailSize += failSize;
                        suiteSkipSize += skipSize;
                        if(failSize>0){
                            resultNode.getModel().setStatus(Status.FAIL);
                        }
                        resultNode.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",passSize,failSize,skipSize));
                    }
                    buildTestNodes(resultNode,context.getFailedTests(), Status.FAIL);
                    buildTestNodes(resultNode,context.getSkippedTests(), Status.SKIP);
                    buildTestNodes(resultNode,context.getPassedTests(), Status.PASS);
                }
                if(suiteTest!= null){
                    suiteTest.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",suitePassSize,suiteFailSize,suiteSkipSize));
                    if(suiteFailSize>0){
                        suiteTest.getModel().setStatus(Status.FAIL);
                    }
                }
    
            }
    //        for (String s : Reporter.getOutput()) {
    //            extent.setTestRunnerOutput(s);
    //        }
    
            extent.flush();
        }
    
        private void init() {
            //文件夹不存在的话进行创建
            File reportDir= new File(OUTPUT_FOLDER);
            if(!reportDir.exists()&& !reportDir .isDirectory()){
                reportDir.mkdir();
            }
            ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(OUTPUT_FOLDER + FILE_NAME);
            // 设置静态文件的DNS
            //怎么样解决cdn.rawgit.com访问不了的情况
            htmlReporter.config().setEncoding("gbk");
            htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS);
    
            htmlReporter.config().setDocumentTitle("自动化测试报告");
            htmlReporter.config().setReportName("自动化测试报告");
            htmlReporter.config().setChartVisibilityOnOpen(true);
            htmlReporter.config().setTestViewChartLocation(ChartLocation.TOP);
            htmlReporter.config().setTheme(Theme.STANDARD);
            htmlReporter.config().setCSS(".node.level-1  ul{ display:none;} .node.level-1.active ul{display:block;}");
            extent = new ExtentReports();
            extent.attachReporter(htmlReporter);
            extent.setReportUsesManualConfiguration(true);
        }
    
        private void buildTestNodes(ExtentTest extenttest, IResultMap tests, Status status) {
            //存在父节点时,获取父节点的标签
            String[] categories=new String[0];
            if(extenttest != null ){
                List<TestAttribute> categoryList = extenttest.getModel().getCategoryContext().getAll();
                categories = new String[categoryList.size()];
                for(int index=0;index<categoryList.size();index++){
                    categories[index] = categoryList.get(index).getName();
                }
            }
    
            ExtentTest test;
    
            if (tests.size() > 0) {
                //调整用例排序,按时间排序
                Set<ITestResult> treeSet = new TreeSet<ITestResult>(new Comparator<ITestResult>() {
                    @Override
                    public int compare(ITestResult o1, ITestResult o2) {
                        return o1.getStartMillis()<o2.getStartMillis()?-1:1;
                    }
                });
                treeSet.addAll(tests.getAllResults());
                for (ITestResult result : treeSet) {
                    Object[] parameters = result.getParameters();
                    String name="";
                    //如果有参数,则使用参数的toString组合代替报告中的name
                    for(Object param:parameters){
                        name+=param.toString();
                    }
                    if(name.length()>0){
                        if(name.length()>50){
                            name= name.substring(0,49)+"...";
                        }
                    }else{
                        name = result.getMethod().getMethodName();
                    }
                    if(extenttest==null){
                        test = extent.createTest(name);
                    }else{
                        //作为子节点进行创建时,设置同父节点的标签一致,便于报告检索。
                        test = extenttest.createNode(name).assignCategory(categories);
                    }
                    //test.getModel().setDescription(description.toString());
                    //test = extent.createTest(result.getMethod().getMethodName());
                    for (String group : result.getMethod().getGroups())
                        test.assignCategory(group);
    
                    List<String> outputList = Reporter.getOutput(result);
                    for(String output:outputList){
                        //将用例的log输出报告中
                        test.debug(output);
                    }
                    if (result.getThrowable() != null) {
                        test.log(status, result.getThrowable());
                    }
                    else {
                        test.log(status, "Test " + status.toString().toLowerCase() + "ed");
                    }
    
                    test.getModel().setStartTime(getTime(result.getStartMillis()));
                    test.getModel().setEndTime(getTime(result.getEndMillis()));
                }
            }
        }
    
        private Date getTime(long millis) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(millis);
            return calendar.getTime();
        }
    }
    View Code

    OverrideRetry.java

    package utils;
    import org.testng.IRetryAnalyzer;
    import org.testng.ITestResult;
    
    public class OverrideRetry implements IRetryAnalyzer {
        private int count = 1;
        private int max_count = 3;
    
        @Override
        public boolean retry(ITestResult result) {
            System.out.println("执行用例:"+result.getName()+",第"+count+"次失败");
            if (count < max_count) {
                count++;
                return true;
            }
            return false;
        }
    }
    View Code

    ParasUtils.java

    package utils;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    public class ParasUtils {
        private String db_url;
        private String db_username;
        private String db_password;
        private String db_tableName;
        private String url;
        private String username;
        private String password;
        private String userData;
        private String downloadDir;
        private String uploadDir;
        private String chromePath;
    
        public void readParas(){
            try {
                InputStream inStream = new FileInputStream(new File(System.getProperty("user.dir")+"\datas\Paras.properties"));
                Properties prop = new Properties();    
                prop.load(inStream);    
                setDb_url(prop.getProperty("db_url"));
                setDb_username(prop.getProperty("db_username"));
                setDb_password(prop.getProperty("db_password"));
                setDb_tableName(prop.getProperty("db_tableName"));
                setUrl(prop.getProperty("url"));
                setUsername(prop.getProperty("username")); 
                setPassword(prop.getProperty("password")); 
                setUserData(prop.getProperty("user-data-dir"));
                setUploadDir(prop.getProperty("uploadDir"));
                setDownloadDir(prop.getProperty("downloadDir"));
                setChromePath(prop.getProperty("chromePath"));
                
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
        }
    
        public String getUrl() {
            readParas();
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public String getUsername() {
            readParas();
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            readParas();
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getUserData() {
            readParas();
            return userData;
        }
    
        public void setUserData(String userData) {
            this.userData = userData;
        }
    
        public String getDownloadDir() {
            readParas();
            return downloadDir;
        }
    
        public void setDownloadDir(String downloadDir) {
            this.downloadDir = downloadDir;
        }
    
        public String getDb_username() {
            return db_username;
        }
    
        public void setDb_username(String db_username) {
            this.db_username = db_username;
        }
    
        public String getDb_url() {
            return db_url;
        }
    
        public void setDb_url(String db_url) {
            this.db_url = db_url;
        }
    
        public String getDb_password() {
            return db_password;
        }
    
        public void setDb_password(String db_password) {
            this.db_password = db_password;
        }
    
        public String getDb_tableName() {
            return db_tableName;
        }
    
        public void setDb_tableName(String db_tableName) {
            this.db_tableName = db_tableName;
        }
    
        public void setUp() {
            // TODO Auto-generated method stub
            
        }
    
        public String getUploadDir() {
            return uploadDir;
        }
    
        public void setUploadDir(String uploadDir) {
            this.uploadDir = uploadDir;
        }
    
        public String getChromePath() {
            return chromePath;
        }
    
        public void setChromePath(String chromePath) {
            this.chromePath = chromePath;
        }
        
    }
    View Code

    ReadCSV.java

    package utils;
    
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;
    
    public class ReadCSV {
         public static Object [][] readCSV(String fileName) 
                    throws IOException {
                //读取CSV文件的方法
                List<Object[]> records = new ArrayList<Object[]>();
                String record;
                BufferedReader file = new BufferedReader(new InputStreamReader(new FileInputStream(fileName),"UTF-8"));
                file.readLine();
                while ((record=file.readLine())!=null){
                    String fields[] =  record.split(",");
                    records.add(fields);
                }
                file.close();
    
                Object[][] results = new Object[records.size()][];
                for (int i=0; i<records.size();i++){
                    results[i] = records.get(i);
                }
                return results;
            }
         
    }
    View Code

    RetryListener.java

    package utils;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
    
    import org.testng.IAnnotationTransformer;
    import org.testng.IRetryAnalyzer;
    import org.testng.annotations.ITestAnnotation;
    
    public class RetryListener implements IAnnotationTransformer {
    
        public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
    
            IRetryAnalyzer retry = annotation.getRetryAnalyzer();
            if (retry == null) {
                annotation.setRetryAnalyzer(OverrideRetry.class); // 这个类名一定要和上方的对上
    
            }
        }
    }
    View Code

    TestngListener.java

    package utils;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    import org.apache.commons.io.FileUtils;
    import org.apache.log4j.Logger;
    import org.openqa.selenium.OutputType;
    import org.openqa.selenium.TakesScreenshot;
    import org.openqa.selenium.WebDriver;
    import org.testng.ITestContext;
    import org.testng.ITestNGMethod;
    import org.testng.ITestResult;
    import org.testng.TestListenerAdapter;
    
    import common.basic;
    
    public class TestngListener extends TestListenerAdapter {
        private static Logger logger = Logger.getLogger(TestngListener.class);
    
        @Override
        public void onTestFailure(ITestResult tr) {
            super.onTestFailure(tr);
            logger.info(tr.getName() + "Failure");
            basic basic=(basic)tr.getInstance();
            takeScreenshot(basic.driver);
        }
    
        @Override
        public void onTestSkipped(ITestResult tr) {
            super.onTestSkipped(tr);
            logger.info(tr.getName() + "Skipped");
            basic basic=(basic)tr.getInstance();
            takeScreenshot(basic.driver);
        }
    
        @Override
        public void onTestSuccess(ITestResult tr) {
            super.onTestSuccess(tr);
            logger.info(tr.getName() + "Success");
        }
    
        @Override
        public void onTestStart(ITestResult tr) {
            super.onTestStart(tr);
            logger.info(tr.getName() + "Start");
        }
    
        
        @Override
        public void onFinish(ITestContext testContext) {
            super.onFinish(testContext);
            ArrayList<ITestResult> testsToBeRemoved = new ArrayList<ITestResult>();
            Set<Integer> passedTestIds = new HashSet<Integer>();
            for (ITestResult passedTest : testContext.getPassedTests()
                    .getAllResults()) {
                logger.info("PassedTests = " + passedTest.getName());
                passedTestIds.add(getId(passedTest));
            }
    
            Set<Integer> failedTestIds = new HashSet<Integer>();
            for (ITestResult failedTest : testContext.getFailedTests()
                    .getAllResults()) {
                logger.info("failedTest = " + failedTest.getName());
                int failedTestId = getId(failedTest);
                if (failedTestIds.contains(failedTestId)
                        || passedTestIds.contains(failedTestId)) {
                    testsToBeRemoved.add(failedTest);
                } else {
                    failedTestIds.add(failedTestId);
                }
            }
    
            for (Iterator<ITestResult> iterator = testContext.getFailedTests()
                    .getAllResults().iterator(); iterator.hasNext();) {
                ITestResult testResult = iterator.next();
                if (testsToBeRemoved.contains(testResult)) {
                    logger.info("Remove repeat Fail Test: " + testResult.getName());
                    iterator.remove();
                }
            }
    
        }
    
        private int getId(ITestResult result) {
            int id = result.getTestClass().getName().hashCode();
            id = id + result.getMethod().getMethodName().hashCode();
            id = id
                    + (result.getParameters() != null ? Arrays.hashCode(result
                            .getParameters()) : 0);
            return id;
        }
    
        
        private void takeScreenshot(WebDriver driver,String screenPath) {
            try {
                File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
                FileUtils.copyFile(scrFile, new File(screenPath));
            } catch (IOException e) {
                System.out.println("Screen shot error: " + screenPath);
            }
        }
    
        public void takeScreenshot(WebDriver driver) {
            String screenName = String.valueOf(new Date().getTime()) + ".jpg";
            File dir = new File("test-output/snapshot");
            if (!dir.exists())
                dir.mkdirs();
            String screenPath = dir.getAbsolutePath() + "\" + screenName;
            this.takeScreenshot(driver,screenPath);
        }
        
    }
    View Code

    loginPage.java

    package page;
    
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.support.*;
    
    public class loginPage{
        //用户名
        @FindBy(id = "username")
        public WebElement username;
        
        //密码
        @FindBy(id = "pwd")
        public WebElement password;
        
        //登录按钮
        @FindBy(xpath = "//button[text()='登录' and @class='btn login-btn']")
        public WebElement loginButton;
    
        //个人中心
        @FindBy(xpath = "//li[@class='personal-center nav-info__item']")
        public WebElement personalCenter;
        
        //个人中心-名称
        @FindBy(xpath = "//div[@class='personal-info fl no-border']/div[2]/p[@class='name nowrap']")
        public WebElement nameInfo;
        
        //账号已休眠提示
        @FindBy(xpath = "//div[text()='该账号已休眠,请联系管理员激活' and @class='jquery-notific8-message']")
        public WebElement stopUserMessage;
        
        //用户名密码错误提示
        @FindBy(xpath = "//div[text()='用户名密码错误' and @class='jquery-notific8-message']")
        public WebElement wrongPwd;
        
        //登录错误次数过多提示
        @FindBy(xpath = "//div[text()='您的用户登录错误次数过多,已被锁定,请联系管理员' and @class='jquery-notific8-message']")
        public WebElement lockMessage;
        
        //解锁成功提示
        @FindBy(xpath = "//div[text()='解锁成功' and @class='jquery-notific8-message']")
        public WebElement unlockMessage;
        
        //重置密码成功提示
        @FindBy(xpath = "//div[text()='重置密码成功' and @class='jquery-notific8-message']")
        public WebElement resetMessage;
        
        //第一次登录修改密码提示
        @FindBy(xpath = "//div[text()='您是第一次登录,请修改密码' and @class='jquery-notific8-message']")
        public WebElement firstLoginMessage;
        
        //创建成功
        @FindBy(xpath = "//div[text()='创建成功' and @class='jquery-notific8-message']")
        public WebElement createSuccessMessage;
        
        //退出按鈕
        @FindBy(xpath = "//div[text()='退出' and @class='logout operate-item']")
        public WebElement logoutButton;
        
        //进入时间
        @FindBy(xpath = "//li[@fieldname='进入时间']")
        public WebElement time;
        
        //时间排序
        @FindBy(xpath = "//li[@fieldname='进入时间']/div/div[2]/div/div/div[2]")
        public WebElement sortArrow;
        
        //登出成功日志记录
        @FindBy(xpath = "//tbody/tr[3]/td[contains(text(),'登出成功')]")
        public WebElement logoutLogs;
        
        //ygtest用户
        @FindBy(xpath = "td[@text='ygtest')]")
        public WebElement ygtest;
        
        //ygtest01用户
        @FindBy(xpath = "//tbody/tr/td[contains(text(),'ygtest01')]")
        public WebElement ygtest01;
        
        //ygtest02用户
        @FindBy(xpath = "//tbody/tr/td[contains(text(),'ygtest02')]")
        public WebElement ygtest02;
        
        //输入关键字搜索
        @FindBy(xpath = "//input[@placeholder='输入关键字搜索']")
        public WebElement searchByKey;
    
        //用户菜单
        @FindBy(id="userManage")
        public WebElement userManage;
    
        //配置管理菜单
        @FindBy(id="configManage")
        public WebElement configManage;
        
        //锁定
        @FindBy(xpath = "//i[@class='ygmat-status-lock'and @title='锁定']")
        public WebElement lockIcon;
        
        //重置密码
        @FindBy(xpath = "//i[@class='ygmat-reset cursor-pointer resetPwd-btn mr8'and @title='重置密码']")
        public WebElement resetPwd;
        
        //新增用户
        @FindBy(xpath = "//li[@title='新增用户']")
        public WebElement addUser;
        
        //用户名
        @FindBy(xpath = "//input[@validatename='用户名']")
        public WebElement newusername;
        
        //显示名
        @FindBy(xpath = "//input[@validatename='显示名']")
        public WebElement newshowname;
        
        //原密码
        @FindBy(xpath = "//input[@validatename='原密码']")
        public WebElement oldPwd;
        
        //新密码
        @FindBy(xpath = "//input[@validatename='新密码']")
        public WebElement newPwd;
        
        //再次输入
        @FindBy(xpath = "//input[@validatename='再次输入']")
        public WebElement againPwd;
        
        //所属组织
        @FindBy(xpath = "//div[@class='belong-org clearfix mb10']/div/button")
        public WebElement belongOrg;
        
        //所属用户组
        @FindBy(xpath = "//div[@class='belong-group clearfix']/div/button")
        public WebElement belongGroup;
        
        //组织
        @FindBy(xpath = "//li[@class='folder-item']/p/input")
        public WebElement selectGroup;
        
        public loginPage(WebDriver driver){
            PageFactory.initElements(driver, this);
        }
    }
    View Code

    basic.java

    package common;
    
    import java.util.concurrent.TimeUnit;
    
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.chrome.ChromeOptions;
    import org.openqa.selenium.interactions.Actions;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.Select;
    import org.openqa.selenium.support.ui.WebDriverWait;
    import org.testng.Assert;
    
    import org.apache.log4j.Logger;
    
    import page.*;
    import utils.*;
    
    public class basic extends ParasUtils{
        private static Logger logger=Logger.getLogger(basic.class);
        
        public ChromeDriver driver;
        public WebDriverWait wait;
        public loginPage loginPage;
        public commonPage commonPage;
        
        //初始化浏览器
        public void initBrowser(){
            System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\datas\chromedriver2.37.exe");
            ChromeOptions options = new ChromeOptions();
            options.addArguments("UserDataDir="+this.getUserData());
            options.setBinary(this.getChromePath()+"chrome.exe");
            driver = new ChromeDriver(options);
            driver.manage().window().maximize();
            driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
            driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);
            logger.info("打开浏览器:"+this.getUrl());
            driver.get(this.getUrl());
        }
    
        //登录
        public void login(){
            initBrowser();
            loginPage=new loginPage(driver);
            loginPage.username.sendKeys(this.getUsername());
            loginPage.password.sendKeys(this.getPassword());
            threadwait(1000);
            click(loginPage.loginButton);
            logger.info("登录成功");
            commonPage=new commonPage(driver);
        }
        
        //管理员登录
        public void login_Manager(){
            initBrowser();
            loginPage=new loginPage(driver);
            loginPage.username.sendKeys("mat");
            loginPage.password.sendKeys("1234.abcd");
            threadwait(1000);
            click(loginPage.loginButton);
            logger.info("登录成功");
            commonPage=new commonPage(driver);
        }
        
        public void refreshBrower(){
             driver.navigate().refresh();
        }
        
        //退出
        public void logout(){
            driver.quit();
            logger.info("退出浏览器成功");
        }
        
        //等待元素可被点击
        public void waitFor(WebElement element){
            wait=new WebDriverWait(driver, 20);
            wait.until(ExpectedConditions.elementToBeClickable(element));
        }
        
        //等待元素点击
        public void click(WebElement element){
            try {
                waitFor(element);
                logger.info("点击"+element.getTagName()+element.getText());
                element.click();
            } catch (Exception e) {
                threadwait(2000);
                element.click();
            }
        }
        
        //等待元素点击
        public void mouseClick(WebElement element){
            Actions actions=new Actions(driver);
            logger.info("点击"+element.getText());
            try {
                actions.contextClick(element);
            } catch (Exception e) {
                threadwait(2000);
                actions.contextClick(element);
            }    
        }
        
        
        //强制等待
        public void threadwait(long time){
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        //模拟键盘双击
        public void doubleClick(WebElement element){
            waitFor(element);
            logger.info("点击"+element.getText());
            Actions actions=new Actions(driver);
            actions.doubleClick(element).perform();
        }
        
        //拖拽
        public void dragAndDrop(WebElement source,WebElement target){
            waitFor(source);
            logger.info(source.getText()+"拖拽到"+target.getText());
            Actions actions=new Actions(driver);
            actions.dragAndDrop(source, target).perform();
        }
        
        //悬浮
        public void hover(WebElement element){
            waitFor(element);
            logger.info("悬浮"+element.getText());
            Actions actions=new Actions(driver);
            actions.moveToElement(element).perform();
        }
        
        //判断元素是否存在
        public boolean isExist(WebElement element)
        { 
            try 
              { 
                  waitFor(element);
                  element.isDisplayed();
                  return true; 
              } 
            catch (Exception e) { 
                  return false; 
                } 
        }
        
        //等待元素消失不可见
        public boolean waitForDisappear(WebElement element){
            wait=new WebDriverWait(driver, 30, 1);
            try {
                wait.until(ExpectedConditions.invisibilityOf(element));
            } catch (Exception e) {
                return false;
            }
            return true;
        }
        
        public void selectby(WebElement element,int index){
            waitFor(element);
            Select select=new Select(element);
            select.selectByIndex(index);
        }
        
        public void assertTrue(WebElement element){
            wait=new WebDriverWait(driver, 30);
            try {
                wait.until(ExpectedConditions.elementToBeClickable(element));
            } catch (Exception e) {
            }
            Assert.assertTrue(element.isDisplayed());
        }
        
        //切换到某个元素所在的iframe下
        public void switchToIframe(WebElement ele){
            driver.switchTo().frame(ele);
        }
        
         //切换回默认frame
         public void switchToDefaultContent(){
             driver.switchTo().defaultContent(); 
         }
         
        //滚动到顶
        public void scrollToTop(){
             ((JavascriptExecutor)driver).executeScript("document.documentElement.scrollTop=0");
        }
            
        //滚动到底
        public void scrollToBottom(){
            ((JavascriptExecutor)driver).executeScript("document.documentElement.scrollTop=10000");
        }
        
        
    //    @Override
    //    @BeforeClass
    //    public void setUp(){
    //        System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\datas\chromedriver2.37.exe");
    //        driver=new ChromeDriver();
    //        driver.manage().window().maximize();
    //        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    //        driver.get(this.getUrl());
    //    }
        
    
    }
    View Code

    loginwithParas.java

    package testcase.login;
    
    import org.apache.log4j.Logger;
    import org.testng.Assert;
    import org.testng.annotations.DataProvider;
    import org.testng.annotations.Test;
    
    import common.basic;
    import page.loginPage;
    import utils.ReadCSV;
    
    /**
     * 用例名:用戶登录
     * 用例编号:AT-001
     */
    public class loginWithParas extends basic {
        private static Logger logger = Logger.getLogger(loginWithParas.class);
    
        @DataProvider(name = "loginData")
        public static Object[][] words() throws Exception {
            return ReadCSV.readCSV(System.getProperty("user.dir") + "\datas\loginData.csv");
        }
    
        @Test(dataProvider="loginData") 
        public void loginWithPara(String username, String password, String result) {
          logger.info(username+" "+password+" "+result);
          
          initBrowser();
          loginPage=new loginPage(driver);
          loginPage.username.sendKeys(username);
          loginPage.password.sendKeys(password);
          threadwait(1000);
          click(loginPage.loginButton);
          
          //验证已停用账号
          if (result.contains("停用")) {
              Assert.assertTrue(isExist(loginPage.stopUserMessage));
          //验证已停用账号
          } else if(result.contains("用户名密码错误")){
              Assert.assertTrue(isExist(loginPage.wrongPwd));
          } else {
          //验证其他不同类型帐号
              threadwait(1000);
              click(loginPage.personalCenter);
              threadwait(1000);
              logger.info("预期值:"+result);
              logger.info("实际值:"+loginPage.nameInfo.getText());
              Assert.assertTrue(loginPage.nameInfo.getText().contains(result));
          }
          
          
          logout();
      }
    }
    View Code

    extentsreport优化测试报告

    NoSuchElementException:检查页面元素的定位表达式是否正确,或尝试其他定位方式;查看页面是否加载延迟,设置等待时间;

    NoSuchFrameException :检查元素是否frame里,是否已切换到元素的frame下,或切换回default content

    ElementNotVisibleException:检查元素是否存在不可见属性的元素,可借助Javascript实现元素操作;检查是否操作速度过快,页面没加载出来

    Cannot focus element:检查是否sendkeys非input元素,可用Action后focus输入

    Actions actions = new Actions(driver);
    actions.moveToElement(element);
    actions.click();
    actions.sendKeys(text);
    actions.build().perform();

  • 相关阅读:
    matlab学习笔记10_7数值计算类型和常用计算公式
    matlab学习笔记10_5 通用字符串操作和比较函数
    matlab学习笔记10_6 字符串与数值间的转换以及进制之间的转换
    matlab-数组取值
    matlab学习笔记10_4MATLAB中的字符串表示
    matlab学习笔记10_3关系运算符和逻辑运算符
    matlab学习笔记10_2 一般操作符
    matlab学习笔记10 一般运算符
    matlab学习笔记9 高级绘图命令_2 图形的高级控制_视点控制和图形旋转_色图和颜色映像_光照和着色
    matlab学习笔记9 高级绘图命令_1 图形对象_根对象,轴对象,用户控制对象,用户菜单对象
  • 原文地址:https://www.cnblogs.com/gqhwk/p/10601556.html
Copyright © 2011-2022 走看看