首页 > 其他分享 >TestNG的使用技巧

TestNG的使用技巧

时间:2023-01-16 15:12:12浏览次数:40  
标签:java 技巧 testng 使用 Test org TestNG public out

TestNG简介

Testng是一套开源测试框架,是从Junit继承而来,testng意为test next generation

创建maven项目,添加依赖

<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.14.3</version>
    <scope>test</scope>
</dependency>

常用注解

@BeforeSuite / @AfterSuite @BeforeTest / @AfterTest @BeforeClass / @AfterClass,在类运行之前/后运行 @BeforeMethod / @AfterMethod,在测试方法之前/后运行

分组测试

场景︰只想执行个别或者某一部分的测试用例
package com.qzcsbj;
 
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
 

public class TestGroups {
    @Test(groups = "login")
    public void testa(){
        System.out.println("TestIgnore.testa");
    }
 
    @Test(groups = "submitOrder")
    public void testb(){
        System.out.println("TestIgnore.testb");
    }
 
    @Test(groups = "submitOrder")
    public void testc(){
        System.out.println("TestIgnore.testc");
    }
 
    @BeforeGroups("submitOrder")
    public void testBeforeGroups(){
        System.out.println("TestGroups.testBeforeGroups");
    }
 
    @AfterGroups("submitOrder")
    public void testAfterGroup(){
        System.out.println("TestGroups.testAfterGroup");
    }
}
结果
TestIgnore.testa
TestGroups.testBeforeGroups
TestIgnore.testb
TestIgnore.testc
TestGroups.testAfterGroup   

xml方式
<?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="test">-->
    <test name="test">  <!--test必须有name属性-->
        <groups>
            <run>
                <include name="submitOrder"/>
            </run>
        </groups>
        <classes>
            <class name="com.qzcsbj.TestGroups"/>
        </classes>
    </test>
</suite>

输出结果:

TestGroups.testBeforeGroups
TestIgnore.testb
TestIgnore.testc
TestGroups.testAfterGroup

依赖测试

字符串数组,默认是空 dependsOnMethods和BeforeMethod的区别是: BeforeMethod是每个方法前都要执行,而dependsOnMethods只是依赖的方法前执行
package com.qzcsbj;
 
import org.testng.annotations.Test;
 

public class TestDepend {
    @Test(dependsOnMethods = {"test2"})
    public  void test(){
        System.out.println("TestAnnotation.test");
    }
 
    @Test
    public  void test2(){
        System.out.println("TestAnnotation.test2");
    }
}


运行结果:
TestAnnotation.test2
TestAnnotation.test
如果被依赖方法执行失败,有依赖关系的方法不会被执行; 应用场景,登录失败,就不能进行下单等操作
package com.qzcsbj;
 
import org.testng.annotations.Test;
 

public class TestDepend {
    @Test(dependsOnMethods = {"test2"})
    public  void test(){
        System.out.println("TestAnnotation.test");
    }
 
    @Test
    public  void test2(){
        System.out.println("TestAnnotation.test2");
        throw new RuntimeException();  // 抛出一个异常
    }
    }
运行结果:

TestAnnotation.test2
 
java.lang.RuntimeException
    at com.qzcsbj.TestDepend.test2(TestDepend.java:19)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)

超时

timeout属性的单位为毫秒。
package com.qzcsbj;
 
import org.testng.annotations.Test;

public class TestTimeOut {
    @Test(timeOut = 1000)  // 单位为毫秒值,期望在1秒内得到结果
    public void test() throws InterruptedException {
        System.out.println("TestTimeOut.test");
        Thread.sleep(500);
    }
 
    @Test(timeOut = 1000)
    public void test2() throws InterruptedException {
        System.out.println("TestTimeOut.test2");
        for (int i = 10; i > 0; i--) {
            Thread.sleep(101);
            System.out.println(i);
        }
        System.out.println("执行结束。");
    }
    }
    
    
    结果:
    TestTimeOut.test2

 
org.testng.internal.thread.ThreadTimeoutException: Method com.qzcsbj.TestTimeOut.test2() didn't finish within the time-out 1000
 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signalAll(AbstractQueuedSynchronizer.java:1953)
    at java.util.concurrent.ThreadPoolExecutor.tryTerminate(ThreadPoolExecutor.java:716)
    at java.util.concurrent.ThreadPoolExecutor.processWorkerExit(ThreadPoolExecutor.java:1014)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

断言

package com.qzcsbj;

public class Add {
    public int sum(int a, int b){
        return a+b;
    }
}




package com.qzcsbj;
 
import org.testng.Assert;
import org.testng.annotations.Test;
 
public class MyTest {
    @Test
    public void test(){
        Add add = new Add();
        int actual = add.sum(1, 2);
        int expect = 2;
        Assert.assertEquals(actual,expect);
    }
}

参数化(数据驱动测试)

两种方式向测试方法传递参数:   利用testng.xml定义parameter   利用DataProviders

xml文件参数化

package com.qzcsbj;
 
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
 

public class TestParameter {
    @Test
    @Parameters({"name","id"})
    public void test(String name, int id){
        System.out.println("name=" + name + ", id=" + id);
    }
}

xml

<?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="test">-->
    <test name="test">  <!--test必须有name属性-->
        <classes>
            <class name="com.qzcsbj.TestParameter">
                <parameter name="name" value="hyqtest"/>
                <parameter name="id" value="1"/>
            </class>
        </classes>
    </test>
</suite>

结果:
name=hyqtest, id=12

DataProvider参数化

代码和数据未分离
package com.qzcsbj;
 
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
 

public class TestDataProvider {
    @Test(dataProvider="data")  // 和下面的name对应起来
    public void testDataProvider(String name, int id){
        System.out.println("name=" + name + ", id=" + id);
    }
    @DataProvider(name = "data")  // 如果没有指定name,上面就写下面的方法名:providerData
    public Object[][] providerData(){
        Object[][] datas = new Object[][]{
                {"zhangsan",1001},
                {"lisi",1002},
                {"wangwu",1003}
        };
        return datas;
    }
}

name=zhangsan, id=1001
name=lisi, id=1002
name=wangwu, id=1003
代码和数据分离,数据存放在excel中
LoginCase.java 用课程中的数据类型封装
package com.qzcsbj;
 
import com.qzcsbj.HttpPostRequest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.HashMap;
 
 

public class LoginCase {
    @Test(dataProvider = "datasFromExcel")  // 多条数据,且数据和代码分离
    public void test(String username, String password){
        String url = "http://127.0.0.1:9999/login";
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("username", username);
        params.put("password", password);
        String res = HttpPostRequest.postRequest(url, params);
        System.out.println("入参:username=" + username + ", password=" + password);
        System.out.println("响应:" + res);
        System.out.println("============================\n");
    }
 
    @DataProvider(name = "datasFromExcel")
    public Object[][] datasFromExcel(){
        Object[][] datas = ExcelUtil.getdataFromExcel("E:\\case.xlsx");
        return datas;
    }
}
进一步优化
每行数据封装到对象或者map,返回:Iterator<Object[]> 每个一维里面是一个对象或者map  

标签:java,技巧,testng,使用,Test,org,TestNG,public,out
From: https://www.cnblogs.com/josonhuang/p/17055421.html

相关文章

  • 弱函数使用
    what?_weak函数是为了防止代码里面重复定义了同样函数名的函数,编译器在链接的时候会报错的一种手段。why?_weak一般被用在公共的接口上,比如中断入口函数,假如在isr.c定......
  • C# .NET6 Serilog的使用和配置
    入口文件:Program.csusingSerilog;usingSerilog.Events;//创建SerilogLog.Logger=newLoggerConfiguration().MinimumLevel.Override("Microsoft",LogEven......
  • postman简单使用
    postman是什么?postman是一款网页调试工具,支持几乎所有类型的HTTP请求下载地址:https://www.getpostman.com/简单使用网页使用F12打开调试模式,CopyasacURL(bash)......
  • [disruptor]03-disruptor的使用及缺陷
    03-disruptor的使用及缺陷disruptor的使用disruptor的使用代码可以见git仓库,这里仅仅对使用流程做一下简单介绍。消费者读数据消费者读数据的步骤如下:注册消费者,此时......
  • 三、四(调优系统性能、使用ACL控制对文件的访问)
    三、调优系统性能(不是重点)                     四、使用ACL控制对文件的访问           ......
  • Forexclub:为什么石油和天然气公司正在考虑使用绿色氢气
    随着全球对绿色氢的兴趣日益浓厚,能源公司正在利用各种可再生能源项目为氢生产提供动力。由于全球风电厂数十年的发展,这种生产的一个主要来源是风能。绿色氢被许多人誉为一种......
  • MeterSphere接口测试模块中循环控制器的使用
    MeterSphere开源持续测试平台的“接口测试”模块具有灵活的接口场景编排设计,模块覆盖了多种接口协议,可自由组合接口自动化测试场景,为接口测试带来方便快捷的体验。其中,逻辑......
  • 售前解决方案的一些工作小技巧
     在汇报工作的时候,该怎么讲清楚这个项目:1、有几个售前交流2、和谁配合3、什么情况4、关键节点5、关键人物6、需求7、结合点8、风险点9、下一步:之前有没有类似的......
  • SQL 函数使用
    replace用函数修改行数据1、使用replacesqlUPDATEtitles_testSETemp_no=REPLACE(emp_no,10001,10005)WHEREid=5;2、使用insert有......
  • LyX中使用Biblatex
    LyX2.2对于Biblatex的支持不是很充分,LyX2.3.7的支持基本完善,变换比较大,下面仅以LyX2.3.7为例说明LyX中的Biblatex的使用及配置。以样式“gb7714-2015”为例。......