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)预订成功




原文地址:https://www.cnblogs.com/ychun/p/14282795.html