(四)TestNG学习之路—注解详述之@Test

目录

(一)TestNG学习之路—HelloWorld入门
(二)TestNG学习之路—注解及属性概览
(三)TestNG学习之路—TestNG.xml/YAML
(四)TestNG学习之路—注解详述之@Test
(五)TestNG学习之路—注解详述之参数化
(六)TestNG学习之路—注解详述之@Factory
(七)TestNG学习之路—注解详述之忽略测试
(八)TestNG学习之路—注解详述之并发
(九)TestNG学习之路—失败测试重跑
(十)TestNG学习之路—编码执行TestNG
(十一)TestNG学习之路—BeanShell高级用法
(十二)TestNG学习之路—注解转换器
(十三)TestNG学习之路—方法拦截器
(十四)TestNG学习之路—TestNG监听器
(十五)TestNG学习之路—依赖注入
(十六)TestNG学习之路—测试报告
(十七)基于TestNG+Rest Assured+Allure的接口自动化测试框架

前言

TestNG提供的诸多注解中,用得最频繁的估计是@Test了,该篇文章将对@Test注解进行详述。

@Test详述

import org.testng.annotations.*;

public class TestNGHelloWorld1 {
    @BeforeTest
    public void bfTest(){
        System.out.println("TestNGHelloWorld1 beforTest!");
    }

    @Test()
    public String helloWorldTest1(){
        System.out.println("TestNGHelloWorld1 Test1!");
        return "@Test return!";
    }

    @AfterTest
    public void AfTest(){
        System.out.println("TestNGHelloWorld1 AfterTest!");
    }
}

如下所示,testng.xml配置allow-return-values为false(默认为false),执行测试会忽略@Test注解的helloWorldTest1方法。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite" allow-return-values="false">
    <test verbose="2" preserve-order="true" name="D:/IntelliJ_IDEA_workspace/TestNG/src/test/resources">
        <classes>
            <class name="TestNGHelloWorld1"/>
        </classes>
    </test>
</suite>

输出结果为:

TestNGHelloWorld1 beforTest!
TestNGHelloWorld1 AfterTest!

===============================================
Default Suite
Total tests run: 0, Failures: 0, Skips: 0
===============================================
  • description属性
    描述@Test,在测试报告体现。
@Test(description = "test")
    public void helloWorldTest1() {
        System.out.println("TestNGHelloWorld1 Test1!");
    }
  • enabled属性
    设置为false,执行测试会忽略@Test注解的helloWorldTest1方法。
    @Test(enabled = false)
    public void helloWorldTest1() {
        System.out.println("TestNGHelloWorld1 Test1!");
    }
  • groups属性
    对测试方法进行分组,可在类级别或方法级别添加组,类级别分组,表示类里面的所有方法都属于该分组,如下所示。
import org.testng.annotations.*;

@Test(groups = "test")
public class TestNGHelloWorld1 {
    @BeforeTest
    public void bfTest() {
        System.out.println("TestNGHelloWorld1 beforTest!");
    }

    @Test(groups = {"test1","test2"})
    public void helloWorldTest1() {
        System.out.println("TestNGHelloWorld1 Test1!");
    }

    @Test(groups = {"test3"})
    public void helloWorldTest2() {
        System.out.println("TestNGHelloWorld1 Test2!");
    }

    @AfterTest
    public void AfTest() {
        System.out.println("TestNGHelloWorld1 AfterTest!");
    }
}

运行分组test分组,但不运行test1分组。

<?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:/IntelliJ_IDEA_workspace/TestNG/src/test/resources">
        <groups>
            <run>
                <include name="test"/>
                <exclude name="test1"/>
            </run>
        </groups>

        <classes>
            <class name="TestNGHelloWorld1"/>
        </classes>
    </test>
</suite>

输出结果:

TestNGHelloWorld1 beforTest!
TestNGHelloWorld1 Test2!
TestNGHelloWorld1 AfterTest!

===============================================
All Test Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

xml配置组名称等也支持正则表达式,开发/测试人员可更灵活的配置测试,例如:

<groups>
            <run>
                <!--匹配以test开始的所有组-->
                <include name="test.*"/>
                <exclude name="test1"/>
            </run>
</groups>
<classes>
        <class name="TestNGHelloWorld1">
            <methods>
                <!--匹配包含Test2串的方法-->
                <include name=".*Test2.*"/>
            </methods>
        </class>
</classes>
  • dependsOnGroups属性
    定义组之间的依赖关系,可使用正则表达式作为参数。
import org.testng.Assert;
import org.testng.annotations.*;

public class TestNGHelloWorld1 {
    @BeforeTest
    public void bfTest() {
        System.out.println("TestNGHelloWorld1 beforTest!");
    }

    @Test(groups = {"test1"})
    public void helloWorldTest1() {
        System.out.println("TestNGHelloWorld1 Test1!");
        Assert.assertEquals("1","2");
    }

    //test3依赖于test1组,如果test1组执行失败,则test3跳过测试
    @Test(groups = {"test3"},dependsOnGroups = "test1")
    public void helloWorldTest2() {
        System.out.println("TestNGHelloWorld1 Test2!");
    }

    @AfterTest
    public void AfTest() {
        System.out.println("TestNGHelloWorld1 AfterTest!");
    }
}

执行结果:

TestNGHelloWorld1 beforTest!
TestNGHelloWorld1 Test1!

java.lang.AssertionError: expected [2] but found [1]
Expected :2
Actual   :1
 <Click to see difference>


    at org.testng.Assert.fail(Assert.java:93)
    at org.testng.Assert.failNotEquals(Assert.java:512)
    at org.testng.Assert.assertEqualsImpl(Assert.java:134)
    at org.testng.Assert.assertEquals(Assert.java:115)
    at org.testng.Assert.assertEquals(Assert.java:189)
    at org.testng.Assert.assertEquals(Assert.java:199)
    at TestNGHelloWorld1.helloWorldTest1(TestNGHelloWorld1.java:14)
    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:108)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:661)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:869)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1193)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:744)
    at org.testng.TestRunner.run(TestRunner.java:602)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:380)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:375)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
    at org.testng.SuiteRunner.run(SuiteRunner.java:289)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1301)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1226)
    at org.testng.TestNG.runSuites(TestNG.java:1144)
    at org.testng.TestNG.run(TestNG.java:1115)
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)


Test ignored.
TestNGHelloWorld1 AfterTest!

===============================================
All Test Suite
Total tests run: 2, Failures: 1, Skips: 1
===============================================
  • dependsOnMethods属性
    定义方法之间的依赖关系,与dependsOnGroups用法类似。可使用正则表达式作为参数。另外,如果依赖于一个碰巧有多个重载版本的方法,那么会调用所有重载的方法。
  • timeout属性
    设定超时时间(单位为ms),如果执行测试超过该设定时间,则当做失败处理。
@Test(timeOut = 2000)
public void helloWorldTest2() throws InterruptedException {
      Thread.sleep(3000);
      System.out.println("TestNGHelloWorld1 Test2!");
}
  • invocationTimeOut属性
    该属性和invocationCount结合使用才会工作,耗时值不能超过设置的最大毫秒数。
@Test(invocationCount = 5, invocationTimeOut = 4000)
public void helloWorldTest3() throws InterruptedException{
     Thread.sleep(1000);
      System.out.println("lsss");
 }
  • invocationCount属性
    表示执行的次数。
@Test(threadPoolSize = 3,invocationCount = 2,timeOut = 2000)
public void helloWorldTest2() throws InterruptedException {
      Thread.sleep(3000);
      System.out.println("TestNGHelloWorld1 Test2!");
}
  • threadPoolSize属性
    表示线程池的内线程的个数。
@Test(threadPoolSize = 3,invocationCount = 2,timeOut = 2000)
public void helloWorldTest2() throws InterruptedException {
      Thread.sleep(3000);
      System.out.println("TestNGHelloWorld1 Test2!");
}
  • successPercentage属性
    当前方法执行所期望的success的百分比。如下所示,执行10次,如果成功9次,则认为测试通过。
@Test(invocationCount = 10,successPercentage = 9)
public void helloWorldTest1() {
      System.out.println("TestNGHelloWorld1 Test1!");
      Assert.assertEquals("1","1");
}
  • dataProvider属性
    结合@DataProvider使用,后续文章详述。
  • dataProviderClass属性
    结合@DataProvider使用,后续文章详述。
  • alwaysRun属性
    如果为true,则该测试方法依然会被运行即使其所依赖的方法执行失败。为false的话,则该测试方法会被skip如果其所依赖的方法执行失败。
import org.testng.Assert;
import org.testng.annotations.*;

public class TestNGHelloWorld1 {
    @BeforeTest
    public void bfTest() {
        System.out.println("TestNGHelloWorld1 beforTest!");
    }

    @Test()
    public void helloWorldTest1() {
        System.out.println("TestNGHelloWorld1 Test1!");
        Assert.assertEquals("2", "1");
    }

    @Test(dependsOnMethods = "helloWorldTest1",alwaysRun = true)
    public void helloWorldTest2() throws InterruptedException {
        System.out.println("TestNGHelloWorld1 Test2!");
    }

    @AfterTest
    public void AfTest() {
        System.out.println("TestNGHelloWorld1 AfterTest!");
    }
}

执行结果:

TestNGHelloWorld1 beforTest!
TestNGHelloWorld1 Test1!

java.lang.AssertionError: expected [1] but found [2]
Expected :1
Actual   :2
 <Click to see difference>


    at org.testng.Assert.fail(Assert.java:93)
    at org.testng.Assert.failNotEquals(Assert.java:512)
    at org.testng.Assert.assertEqualsImpl(Assert.java:134)
    at org.testng.Assert.assertEquals(Assert.java:115)
    at org.testng.Assert.assertEquals(Assert.java:189)
    at org.testng.Assert.assertEquals(Assert.java:199)
    at TestNGHelloWorld1.helloWorldTest1(TestNGHelloWorld1.java:15)
    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:108)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:661)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:869)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1193)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:744)
    at org.testng.TestRunner.run(TestRunner.java:602)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:380)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:375)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
    at org.testng.SuiteRunner.run(SuiteRunner.java:289)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1301)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1226)
    at org.testng.TestNG.runSuites(TestNG.java:1144)
    at org.testng.TestNG.run(TestNG.java:1115)
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)

TestNGHelloWorld1 Test2!
TestNGHelloWorld1 AfterTest!

===============================================
Default Suite
Total tests run: 2, Failures: 1, Skips: 0
===============================================
  • expectedExceptions属性
    属性expectedExceptions是一组类,包含了这个测试方法中预期会抛出的异常列表。如果没有抛出异常,或抛出的异常不再该属性的类表中,那么TestNG就会认为这个测试方法失败了。以下测试执行通过。
@Test(expectedExceptions = ArithmeticException.class)
public void helloWorldTest1() {
      System.out.println("TestNGHelloWorld1 Test1!");
      int c = 1/0;
      Assert.assertEquals("1", "1");
}
  • expectedExceptionsMessageRegExp属性
    异常信息正则表达式。以下测试执行通过。
@Test(expectedExceptions = ArithmeticException.class,expectedExceptionsMessageRegExp = ".*zero")
public void helloWorldTest1() {
      System.out.println("TestNGHelloWorld1 Test1!");
      int c = 1/0;
      Assert.assertEquals("1", "1");
}
  • suiteName属性
    测试套件名称。
  • testName属性
    测试名称,跟description属性作用类似。
  • singleThreaded属性
    如果设置为true,那么这个测试类中的所有方法都保证在同一个线程中运行,即使测试当前使用parallel="methods"运行。这个属性只能在类级别使用,如果在方法级别使用,它将被忽略。
  • retryAnalyzer属性
    TestNG重试机制,后续文章详解。
  • skipFailedInvocations属性
    是否跳过失败的调用,如果不跳过,可能会导致测试用例的死锁。
  • ignoreMissingDependencies属性
    如果为true,找不到依赖也继续执行。
import org.testng.Assert;
import org.testng.annotations.*;

public class TestNGHelloWorld1 {
    @BeforeTest
    public void bfTest() {
        System.out.println("TestNGHelloWorld1 beforTest!");
    }

    @Test(expectedExceptions = ArithmeticException.class, expectedExceptionsMessageRegExp = ".*zero")
    public void helloWorldTest1() {
        System.out.println("TestNGHelloWorld1 Test1!");
        int c = 1 / 0;
        Assert.assertEquals("1", "1");
    }

    @Test(dependsOnGroups = "test",ignoreMissingDependencies = true)
    public void helloWorldTest2() {
        Assert.assertEquals("1", "1");
        System.out.println("TestNGHelloWorld1 Test2!");

    }

    @AfterTest
    public void AfTest() {
        System.out.println("TestNGHelloWorld1 AfterTest!");
    }
}
  • priority属性
    标注测试方法的优先级。较低的优先级将优先执行。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 感谢原作者的奉献,原作者博客地址:http://blog.csdn.net/zhu_ai_xin_520/arti...
    狼孩阅读 13,999评论 1 35
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • 首先,根据百度的步骤获取记录值 然后,我们进行域名验证。 我们创建一个demo来验证域名吧。 首先, 通过expr...
    QiuZhiFeng阅读 1,151评论 0 0
  • 对,你才对了 这就是一个日记本
    建奇A阅读 162评论 0 1
  • 第十一章“学会重新看世界”的中心意思,就是“再次体验纯真的眼神”。为此,作者提供了两个操作建议: 第一个:“为了达...
    黄虎阅读 169评论 1 2