zoukankan      html  css  js  c++  java
  • TestNG 安装、常用注解、断言、参数化、生成测试报告、测试套件、执行Excel测试用例

    1、安装 testng

    1)离线安装 

    (先断网)帮助→安装新软件→添加,位置选择 achive,选择 zip 文件即可。

    插件:

    链接:https://pan.baidu.com/s/1-HUUvDV02w2gAYKFS_7_TQ
    提取码:nd35

    2)、网络安装 

       帮 助 → 安 装 新 软 件 → 联 网 安 装 testing , Work with 下 输 入 : http://beust.com/eclipse→添加→勾选 TestNG

     2、常用注解

    @BeforeSuite/@AfterSuite:在某个测试套件开始之前运行 / 在某个测试套件开始之后运行

    @BeforeTest/@AfterTest:在某个测试(test)开始之前运行 / 在某个测试(test)开始之后运行

    @BeforeClass/@AfterClass : 在某个测试类的开始之前运行 / 在某个测试类的开始之后运行。

    @BeforeMethod / @AfterMethod : 在某个测试方法的开始之前运行 / 在某个测试方法的开始之后运行。

    package com02;
    
    import org.testng.Assert;
    import org.testng.annotations.*;
    
    public class TestTestNG01 {
    
    
        @BeforeSuite
        public void test01(){
            System.out.println("--BeforeSuite");
        }
    
        @AfterSuite
        public void test03(){
            System.out.println("--AfterSuite");
        }
    
    
        @BeforeTest
        public void test04(){
            System.out.println("--BeforeTest");
        }
    
        @AfterTest
        public void test05(){
            System.out.println("--AfterTest");
        }
    
        @BeforeClass
        public void test06(){
            System.out.println("--BeforeClass");
        }
    
        @AfterClass
        public void test07(){
            System.out.println("--AfterClass");
        }
    
    
        @BeforeMethod
        public void test08(){
            System.out.println("--BeforeMethod");
        }
    
        @AfterMethod
        public void test09(){
            System.out.println("--AfterMethod");
        }
    
        @Test
        public void test02(){
            Assert.assertEquals(1,1);
    
            System.out.println("'------------------------------'");
        }
    
    
    }
    View Code
    D:2toolsjavainjava.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:2toolsIntelliJ IDEA 2020.2.2libidea_rt.jar=62163:D:2toolsIntelliJ IDEA 2020.2.2in" -Dfile.encoding=UTF-8 -classpath "D:2toolsIntelliJ IDEA 2020.2.2libidea_rt.jar;D:2toolsIntelliJ IDEA 2020.2.2plugins	estnglib	estng-rt.jar;D:2toolsjavajrelibcharsets.jar;D:2toolsjavajrelibdeploy.jar;D:2toolsjavajrelibextaccess-bridge-64.jar;D:2toolsjavajrelibextcldrdata.jar;D:2toolsjavajrelibextdnsns.jar;D:2toolsjavajrelibextjaccess.jar;D:2toolsjavajrelibextjfxrt.jar;D:2toolsjavajrelibextlocaledata.jar;D:2toolsjavajrelibext
    ashorn.jar;D:2toolsjavajrelibextsunec.jar;D:2toolsjavajrelibextsunjce_provider.jar;D:2toolsjavajrelibextsunmscapi.jar;D:2toolsjavajrelibextsunpkcs11.jar;D:2toolsjavajrelibextzipfs.jar;D:2toolsjavajrelibjavaws.jar;D:2toolsjavajrelibjce.jar;D:2toolsjavajrelibjfr.jar;D:2toolsjavajrelibjfxswt.jar;D:2toolsjavajrelibjsse.jar;D:2toolsjavajrelibmanagement-agent.jar;D:2toolsjavajrelibplugin.jar;D:2toolsjavajrelib
    esources.jar;D:2toolsjavajrelib
    t.jar;D:java	est	estProject2	argetclasses;D:
    epositorymavenReporgdom4jdom4j2.1.1dom4j-2.1.1.jar;D:
    epositorymavenRepjaxenjaxen1.2.0jaxen-1.2.0.jar;D:
    epositorymavenReporg	estng	estng7.4.0	estng-7.4.0.jar;D:
    epositorymavenRepcomeustjcommander1.78jcommander-1.78.jar;D:
    epositorymavenReporgwebjarsjquery3.5.1jquery-3.5.1.jar;D:2toolsIntelliJ IDEA 2020.2.2plugins	estnglibjcommander-1.27.jar" com.intellij.rt.testng.RemoteTestNGStarter -usedefaultlisteners false -socket62162 @w@C:UsersliyujiaoAppDataLocalTempidea_working_dirs_testng.tmp -temp C:UsersliyujiaoAppDataLocalTempidea_testng.tmp
    
    
    
    --BeforeSuite
    
    
    --BeforeTest
    
    
    --BeforeClass
    
    
    --BeforeMethod
    
    
    '------------------------------'
    
    
    --AfterMethod
    
    
    --AfterClass
    
    
    --AfterTest
    
    
    --AfterSuite
    
    
    ===============================================
    Default Suite
    Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
    ===============================================
    
    
    Process finished with exit code 0
    View Code

    5) @Test(属性 1=值 1,属性 2=值 2,...)

    @Test(description="订票",priority=2,dataProvider="getParam",dataProviderClass=getParam所在类的类名.class )
    public void book(String cong , String dao){
    
    

     6) @DataProvider(name="参数集名")

    用来修饰获得参数的方法,此方法用于生成测试数据

    3、断言

    1) Assert.assertTrue(boolean 型结果)

     2) Assert.assertEquals(实际结果,预期结果)

     

      4、参数化

    @Parameters 
    运行入口testng.xml文件
    package com02;
    
    import org.testng.annotations.Parameters;
    import org.testng.annotations.Test;
    
    public class Test02 {
        //读取配置文件中参数
        @Test
        @Parameters(value = {"type","num"})
        public void test01(String type,String num){
            System.out.println("type="+type+",num="+num);
        }
    
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="All Test Suite">
        <test verbose="2" preserve-order="true" name="D:/java/test/testProject2">
            <classes>
                <class name="com02.Test02">
                    <methods>
                        <include name="test01"/>
                    </methods>
                    <parameter name="type" value="fox"/>
                    <parameter name="num" value="2"/>
                </class>
            </classes>
        </test>
    
    </suite>

    @DataProvider(name="测试数据集名")

    name 项可省略,括号无所谓

    例如

    1) 创建获取参数的方法
    @DataProvider
    public Object[][] getParam() throws Exception{
    Object data[][]={ {"London","Paris"},{"Denver","London"},{"Paris","Denver"} };
    return data;
    }
    
    2)使用 dataProvider 访问参数
    @Test(description="订票",priority=2,dataProvider="getParam")
    public void book(String cong , String dao){
    new Select(drv.findElement(By.name("depart"))).selectByVisibleText(cong);
    new Select(drv.findElement(By.name("arrive"))).selectByVisibleText(dao);
    Boolean rs=drv.findElement(By.tagName("body")).getText().contains("leaves "+cong+" for "+dao);
    assertTrue(rs);
    drv.findElement(By.name("Book Another")).click();
    }

    方式二:分离获得参数的类,使用列表获取文件中的参数

    1)定义获得参数的类

    @DataProvider
    public Object[][] getParam() throws Exception{
      List<String[]> rows=new ArrayList<String[]>();
      File file=new File("C:/.../flights.txt");
      FileReader reader=new FileReader(file);
      BufferedReader buffer=new BufferedReader(reader);
      String row=null;
      while((row=buffer.readLine())!=null){
        String columns[]=row.split(" ");
        rows.add(columns);
    }
      reader.close();
      Object[][] data=new Object[rows.size()][];
      for(int i=0;i<rows.size();i++)
          data[i]=rows.get(i);
       return data;
    }

    2)引用参数类中的参数
    @Test(description="订票",priority=2,dataProvider="getParam",dataProviderClass=getParam所在类的类名.class )
    public void book(String cong , String dao){
    new Select(drv.findElement(By.name("depart"))).selectByVisibleText(cong); 
    new Select(drv.findElement(By.name("arrive"))).selectByVisibleText(dao);
    drv.findElement(By.name("Book Another")).click();
    }

    依赖测试

    不加依赖执行测试,顺序为:ASCII

    加入依赖


     


     忽略测试

    enabled = false

     


    超时测试  

    timeOut = 500

     


    分组执行

    1、测试方法指定groups

    2、在testng.xml的test指定相应的测试类

    3、在testng.xml的groups里面指定run的分组,或者exclude的分组

    include

     

     exculde

     


    5 生成测试报告

    测试报告默认存储位置 : Java 项目名 est-output

    可以自己编写并优化 TestReport.java

    例如:

     

    TestRepost.class

    package utils;    
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.nio.file.StandardOpenOption;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import org.testng.ITestContext;
    import org.testng.ITestResult;
    import org.testng.TestListenerAdapter;
     
    public class TestReport extends TestListenerAdapter{
        private String reportPath;
     
        @Override
        public void onStart(ITestContext context) {
            File htmlReportDir = new File("test-output");
            if (!htmlReportDir.exists()) {
                htmlReportDir.mkdirs();
            }
            String reportName = formateDate()+"_result.html";
            reportPath = htmlReportDir+"/"+reportName;
            File report = new File(htmlReportDir,reportName);
            if(report.exists()){
                try {
                    report.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            StringBuilder sb = new StringBuilder("<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />"
                    + "<title>自动化测试报告</title></head><body style="background-color:#99FFCC;">"
                    + "<div id="top" align="center"><p style="font-weight:bold;">测试用例运行结果列表</p>"            
                    + "<table width="90%" height="80" border="1" align="center" cellspacing="0" rules="all" style="table-layout:relative;">"
                    + "<thead>"
                    + "<tr>"
                    + "<th>测试用例名</th>"
                    + "<th>测试用例结果</th>"
                    + "</tr>"
                    + "</thead>"
                    + "<tbody style="word-wrap:break-word;font-weight:bold;" align="center">");
            String res = sb.toString();
            try {  
                Files.write((Paths.get(reportPath)),res.getBytes("utf-8"));  
            } catch (IOException e) {  
                e.printStackTrace();  
            } 
        }
        
        @Override
        public void onTestSuccess(ITestResult result) {
            StringBuilder sb = new StringBuilder("<tr><td>");
            sb.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName());
            sb.append("</td><td><font color="green">Passed</font></td></tr>");
            String res = sb.toString();
            try {
                Files.write((Paths.get(reportPath)),res.getBytes("utf-8"),StandardOpenOption.APPEND);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        @Override
        public void onTestSkipped(ITestResult result) {
            StringBuilder sb = new StringBuilder("<tr><td>");
            sb.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName());
            sb.append("</td><td><font color="yellow">Skipped</font>");
            sb.append("<p align="left">测试用例<font color="red">跳过</font>,原因:<br>");
            sb.append("<br><a style="background-color:#CCCCCC;">");
            Throwable throwable = result.getThrowable(); 
                    sb.append(throwable.getMessage()); 
                    sb.append("</a></p></td></tr>");
            String res = sb.toString();
            try {
                Files.write((Paths.get(reportPath)),res.getBytes("utf-8"),StandardOpenOption.APPEND);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        @Override
        public void onTestFailure(ITestResult result) {
            StringBuilder sb = new StringBuilder("<tr><td>");
            sb.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName());
            sb.append("</td><td><font color="red">Failed</font><br>");
            sb.append("<p align="left">测试用例执行<font color="red">失败</font>,原因:<br>");
            sb.append("<br><a style="background-color:#CCCCCC;">");
            Throwable throwable = result.getThrowable();
            sb.append(throwable.getMessage());
            sb.append("</a></p></td></tr>");
            String res = sb.toString();
            try {
                Files.write((Paths.get(reportPath)),res.getBytes("utf-8"),StandardOpenOption.APPEND);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        @Override
        public void onFinish(ITestContext testContext) {
            StringBuilder sb = new StringBuilder("</tbody></table><a href="#top">返回顶部</a></div></body>");
            sb.append("</html>");
            String msg = sb.toString();
            try {
                Files.write((Paths.get(reportPath)),msg.getBytes("utf-8"),StandardOpenOption.APPEND);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        public static String formateDate(){
            SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd HHmmss");
            Calendar cal = Calendar.getInstance();
            Date date = cal.getTime();
            return sf.format(date);
        }
    }

    6、测试套件suite

    一个 suite 可以包含多个独立的 test。

    1)定义测试套件

    2)修正testng.xml

     3)运行测试套件

    打开 testng.xml→点击工具栏运行按钮→选择“TestNG Suite”。

    7、为测试套件中的测试方法传递参数

    1)定义参数

     2)引用参数

    @Test @Parameters({ "参数名 1", "参数名 2" })

    public void 测试方法(String 参数名 1){

    }

    testng.xml
    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite thread-count="2" name="ExplorerSuite" parallel="tests"> <test name="IETest"> <classes> <class name="com03.IETest"/> </classes> </test> <!-- IETest --> <test name="ChromeTest"> <pav rameter name="url" value="http://localhost:1080/webtours" /> <classes> <class name="com03.ChromeTest"/> </classes> </test> <!-- ChromeTest --> </suite> <!-- ExplorerSuite -->


    引用参数

    @Test(description="登录",priority=1,dataProvider="getParamByExcel",dataProviderClass=Param.class)
    public void login(String username,String password,String expect) throws InterruptedException {
      // 进入frame navbar
      driver.switchTo().defaultContent();
      driver.switchTo().frame("body");
      driver.switchTo().frame("navbar");
      // 识别元素
      // 用户名
      driver.findElement(By.name("username")).clear();
      driver.findElement(By.name("username")).sendKeys(username);
      // 密码
      driver.findElement(By.name("password")).clear();
      driver.findElement(By.name("password")).sendKeys(password);
      // 点击登录
      driver.findElement(By.name("login")).click();
       Thread.sleep(4000);
      testSuccess(driver,"body","info","登录结果验证:",expect);
    }

    
    

    8、执行 Excel 测试用例

    1 )准备 Excel 测试用例

       至少包括输入数据和预期结果

    2 )读 Excel

    首先导入 jxl.jar 包

    
    

    package com02;

    
    

    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    
    

    import java.util.Set;

    
    

    import org.testng.annotations.DataProvider;

    
    

    import jxl.Cell;
    import jxl.Sheet;
    import jxl.Workbook;
    import jxl.read.biff.BiffException;

    
    

    public class Param {

      @DataProvider
        public Object[][] getParamByExcel() throws IOException, BiffException{
             InputStream file = new FileInputStream("C:\Users\blue\Desktop\fight.xls");
             Workbook excel = Workbook.getWorkbook(file);
             Sheet sheet =  excel.getSheet(0);
             List<String[]>  list  = new ArrayList<String[]>();
             Cell cell = null;
           //0 表示第 1 行
             for (int i=0; i<sheet.getRows();i++) { 
                //创建数组存储一行的多列值
                 String[] rowi_col=new String[sheet.getColumns()];       
                 for (int j= 0;j<sheet.getColumns();j++) {
                    //获取第 i 行第 j 列的值
                     cell=sheet.getCell(j,i); 
                     rowi_col[j]=cell.getContents();
                     }
                // 把刚获取的列存入 list
                     list.add(rowi_col);
             }
             file.close();
    //返回 Object 对象作为参数 Object[][] data
    = new Object[list.size()][3]; for(int i=0;i<list.size();i++) { data[i] = list.get(i); } return data; }

    3)断言失败时输出实际结果

    断言失败时,断言语句后面的语句将停止运行

    String result=driver.findElement(By.tagName("body")).getText();
    Boolean loginResult=result.contains(expect);
    try{
    Assert.assertTrue(loginResult);
    }catch(AssertionError e){
    Assert.fail(result);
    }
    完整代码展示

    package
    com02; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.Listeners; import org.testng.annotations.Test; import utils.TestReport; //参数化,测试登录 @Listeners({TestReport.class}) public class TestWebtours05 { static WebDriver driver ; //打开网站 @BeforeClass public void before() throws Exception { // 打开浏览器 System.setProperty("webdriver.chrome.driver", "C:\Users\blue\Desktop\driver\chromedriver.exe"); driver = new ChromeDriver(); // 打开网址 driver.get("http://localhost:1080/webtours"); } //每运行一个方法,自动休眠3S @AfterMethod public void sleep() throws InterruptedException { Thread.sleep(3000); } //登录 @Test(description="登录",priority=1,dataProvider="getParamByExcel",dataProviderClass=Param.class) public void login(String username,String password,String expect) throws InterruptedException { // 进入frame navbar driver.switchTo().defaultContent(); driver.switchTo().frame("body"); driver.switchTo().frame("navbar"); // 识别元素 // 用户名 driver.findElement(By.name("username")).clear(); driver.findElement(By.name("username")).sendKeys(username); // 密码 driver.findElement(By.name("password")).clear(); driver.findElement(By.name("password")).sendKeys(password); // 点击登录 driver.findElement(By.name("login")).click(); Thread.sleep(4000); testSuccess(driver,"body","info","登录结果验证:",expect); } //关闭窗口 @AfterClass public void close() { //关闭窗口 driver.quit(); } //断言 public static void testSuccess(WebDriver driver,String location_1,String location_2,String message,String info) { driver.switchTo().defaultContent(); driver.switchTo().frame(location_1); driver.switchTo().frame(location_2); //判断是否加载网页成功 Boolean res = driver.findElement(By.tagName("body")).getText().contains(info); System.out.println("---------断言--------"+message+res+" "); try { Assert.assertTrue(res); }catch(AssertionError e) { //输出实际结果 Assert.fail(driver.findElement(By.tagName("body")).getText()); } } }

     页面效果

     

    1)登录

    
    

    
    

    2)登陆成功

    
    
    
    

     

    
    
    
    

    3)预订航班

    
    

     

    
    
    
    

    4)选择班次

    
    

     

    
    
    
    

    5)用户信息确认

    
    

     

    
    

      6)预订成功

    
    

    
    
    
  • 相关阅读:
    构造与析构的次序
    为什么析构函数常声明为虚函数
    偏移数组的二分查找
    字符串循环右移N位
    const 补充
    对类 sizeof
    指针与引用
    python小练习
    初学数据挖掘——相似性度量(一)
    每天进步一点点(二)
  • 原文地址:https://www.cnblogs.com/ychun/p/14282795.html
Copyright © 2011-2022 走看看