TestNG的使用

****************************************************************************************************

TestNG教程:

****************************************************************************************************

一、Test Fixture

Test Fixture 是指一个测试运行所需的固定环境,准确的定义:

The test fixture is everything we need to have in place to exercise the SUT

在进行测试时,我们通常需要把环境设置成已知状态(如创建对象、获取资源等)来创建测试,每次测试开始时都处于一个固定的初始状态;测试结果后需要将测试状态还原,所以,测试执行所需要的固定环境称为 Test Fixture。

TestNG提供的Fixture方法

注解 说明
@BeforeSuite 注解的方法在测试套件(中的所有用例)开始前运行一次
@AfterSuite 注解的方法在测试套件(中的所有用例)结束后运行一次。
@BeforeClass 注解的方法在当前测试类(中所有用例)开始前运行一次。
@AfterClass 注解的方法在当前测试类(中所有用例)结束后运行一次。
@BeforeTest 对于套件测试,在运行属于标签内的类的所有测试方法之前运行。
@AfterTest 对于套件测试,在运行属于标签内的类的所有测试方法之后运行。
@BeforeGroups 在调用属于该组的所有测试方法之前运行。
@AfterGroups 在调用属于该组的所有测试方法之后运行。
@BeforeMethod 注解的方法将在每个测试方法之前运行。
@AfterMethod 注释的方法将在每个测试方法之后执行。


二、testing.xml文件解析

<!--必须要添加,表示遵循的规范文件-->
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<!--suite表示定义一个测试套件,name定义测试套件名称,verbose定义命令行信息打印等级,不会影响测试报告输出内容,范围:1-5-->
<suite name="Suite1" verbose="1" >    
  <!--test表示定义了一个测试,name定义测试的名称-->
  <test name="Nopackage" >    
    <!--classes表示定义一组测试类-->    
    <classes>    
       <!--class表示定义一个测试类,name指定要运行的测试类-->                    
       <class name="NoPackageTest" />    
    </classes>
  </test>

  <test name="Regression1">
    <classes>
      <class name="test.sample.ParameterSample"/>
      <class name="test.sample.ParameterTest"/>
    </classes>
  </test>
</suite>


三、测试级别设置

在我们创建测试用例时,大概分三个层级。

  • 测试包(目录)
  • 测试类(文件)
  • 测试用例(@Test 注解的方法)

接下来介绍,如何控制这三个级别用例的执行。当然,核心还是通过 testng.mxl 文件配置。

指定运行测试包


<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="测试套件" verbose="1" > <test name="简单测试"> <packages> <package name="test.sample" /> <package name="test.sample2" /> </packages> </test> </suite> 
  • <packages>...</packages> 定义一组测试包。
  • <package.../> 定义一个测试包。
    • name 指定测试包(目录)的名称。

指定运行测试类


<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="测试套件" verbose="1" > <test name="简单测试"> <classes> <class name="test.sample.FirstTest"/> <class name="test.sample.SecondTest"/> </classes> </test> </suite> 

指定测试类的运行,上一节已经介绍。

指定运行测试用例


<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="测试套件" verbose="1" > <test name="简单测试"> <classes> <class name="test.sample.FirstTest"> <methods> <include name="testCase" /> </methods> </class> </classes> </test> </suite> 
  • <methods>...</methods> 定义一组测试方法。
  • <include.../> 指定包含的测试用例(方法)。
    • name 指定测试用例(方法)的名称。

注意: 测试方法<methods>必须包含在<class>标签中。


四、TestNG用例分组

有时候我们的测试用例并不想以测试包、类和用例为单位去运行。测试用例可以有多个纬度去标识。

例如,可以根据用例的重要程度划分:

  • 重要程度:低——>中——>高

或者,根据用例的类型划分:

  • 类型:正常——>异常

TestNG 允许我们给测试用例贴标签。我们可以根据这些标签有选择地的跳过或执行这些用例。

实例


import org.testng.annotations.Test; import static org.testng.AssertJUnit.assertEquals; @Test(groups = {"功能测试"}) public class TagTest { @Test(groups={"高", "正常"}) public void testCase1(){
        assertEquals(2+2, 4);
    } @Test(groups = {"高", "正常"}) public void testCase2(){
        assertEquals(5-3, 2);
    } @Test(groups = {"中", "正常"}) public void testCase3(){
        assertEquals(2/1, 2);
    } @Test(groups = {"低", "异常"}) public void testCase4(){
        assertEquals(2/0, 1);
    }

}

接下来配置 testng.xml ,根据标签筛选要运行的测试用例。

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> 
<suite name="All Test Suite"> 
    <test name="简单测试"> 
        <groups> 
            <run> 
                <include name="高"/> 
            </run> 
        </groups> 
        <classes> 
            <class name="test.sample.TagTest"/> 
        </classes> 
    </test> 
</suite>


  • <groups>...</groups> 测试组标签。
  • <run>...</run> 运行测试。
  • <exclude> 根据groups的设置,排除不执行的用例。
  • <include> 根据groups的设置,指定执行的测试用例。

根据上面的配置,运行测试: testCase1 和 testCase2 两条用例将被执行。

不要忘了,我们给 TagTest 测类同样也划分了组(groups = {"功能测试"}),现在修改 testng.xml 配置。

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
    <test name="简单测试">
        <groups>
            <run>
                <exclude name="异常"/>
                <include name="功能测试"/>
            </run>
        </groups>
        <classes>
            <class name="net.weidian.phs.Demo02"/>
        </classes>
    </test>
</suite>


再次运行测试:testCase1、testCase2 和 testCase3 三条用例将被执行。


五、TestNG用例执行顺序

有时候,我们希望用例按照我们要求的顺序来执行。TestNG 同样可以满足这一点要求。

实例


import org.testng.annotations.Test; import static org.testng.AssertJUnit.assertEquals; public class CaseRunTest { @Test public void testCase1(){
        assertEquals(2+2, 4);
    } @Test public void testCase2(){
        assertEquals(2+2, 4);
    } @Test public void testCase3(){
        assertEquals(2+2, 4);
    }
}

通过 testng.xml 文件修改配置。

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="测试套件"> <test name="简单测试" preserve-order="false"> <classes> <class name="test.sample.CaseRunTest"> <methods> <include name="testCase3" /> <include name="testCase1" /> <include name="testCase2" /> </methods> </class> </classes> </test> </suite> 
  • preserve-order 参数用于控制测试用例的执行顺序。如果为:true,测试用例的顺序为:testCase > testCase1 > testCase2。如果为:false ,那么默认会按照用例的名称的有字母/数字的顺序执行:testCase1 > testCase2 > testCase3。

不设置的情况下默认为 true 。


六、TestNG用例依赖

当某一条用例运行失败时,其它用例必然也会失败,所以,我们就没有必要再运行其它用例了,这个时候我们就可以设置用例之间的依赖。

测试方法依赖


import org.testng.annotations.Test; import static org.testng.AssertJUnit.assertEquals; public class DependentMethodsTest { @Test public void testAdd1(){
        assertEquals(3+1, 5);
    } @Test(dependsOnMethods = {"testAdd1"}) public void testAdd2(){
        assertEquals(3+2, 5);
    }

}
  • dependsOnMethods 来设置用例的依赖,当 testAdd1() 运行失败时,则 testAdd2() 不再被执行。

测试组依赖


import org.testng.annotations.Test; import static org.testng.AssertJUnit.assertEquals; public class DependentGroupsTest { @Test(groups={"funtest"}) public void testAdd1(){
        assertEquals(3+1, 5);
    } @Test(groups={"funtest"}) public void testAdd2(){
        assertEquals(3+2, 5);
    } @Test(dependsOnGroups = {"funtest"}) public void testAdd3(){
        assertEquals(3+2, 5);
    }

}
  • dependsOnGroups 来设置组的依赖,testAdd1()和 testAdd2() 同属于于 funtest组,testAdd3() 依赖于funtest组,该组有中有一条用例运行失败,则testAdd3() 不再执行。


七、TestNG用例参数化

参数化也测试用例中常用的技巧之一,它可以增加用例的可配置性和减少相同用例的编写。

通过 @Parameters 实现参数化


import org.testng.annotations.Parameters; import org.testng.annotations.Test; import static org.testng.AssertJUnit.assertEquals; public class DataProviderTest { @Test @Parameters({"add1","add2","result"}) public void testAdd1(int add1, int add2, int result){
        assertEquals(add1+ add2, result);
    }

}
  • @Parameters 获取参数化数据,作为 testAdd1() 测试方法的参数。

具体的测试数据在 testng.mxl 文件中设置。

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="测试套件"> <test name="简单测试"> <parameter name="add1" value="3"/> <parameter name="add2" value="2"/> <parameter name="result" value="5"/> <classes> <class name="test.sample.DataProviderTest" /> </classes> </test> </suite> 
  • <parameter.../> 定义测试数据
    • name 定义数据的名字,在测试用例中通过该名字来获取对应的vlaue。
    • value 定义测试数据,通过对应的name来获取该值。

通过 @DataProvider 实现参数化


import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import static org.testng.AssertJUnit.assertEquals; public class DataProviderTest { // 定义对象数组 @DataProvider(name = "add") public Object[][] Users() { return new Object[][] {
                { 3, 2, 5 },
                { 2, 2, 4 },
                { 3, 3, 7 },
        };
    } @Test(dataProvider="add") public void testAdd2(int add1, int add2, int result){
        assertEquals(add1+add2, result);
    }

}
  • @DataProvider 定义对象数组,数组的名称为:add 。

在 testAdd2() 中通过 dataProvider="add" 调用定义的对象数组,并通过参数获取相应的测试数据。

执行结果如下:


八、TestNG多线程运行用例

TestNG 是我接触过的唯一自身支持多程技术的单元测试框架。虽然代码级别的单元测试运行得很快,多线程的意义并不大。但如果是UI自动化测试的话运行速度就会非常慢,这个时候多线程技术就会变得很重要。

多线程配置


这里只介绍 testng.xml 文件,其中的使用到的测试用例,请参考前面的章节创建。

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 
    <suite name="测试套件" parallel="classes" thread-count="2" > 
        <test name="简单测试">
             <classes> 
                <class name="test.sample.FirstTest" /> 
                <class name="test.sample.SecondTest" /> 
            </classes> 
        </test> 
    </suite>


parallel 设置多线程的级别划分:

  • parallel="methods": TestNG将在不同的线程中运行所有的测试方法。依赖方法也将在单独的线程中运行,但它们将尊重你指定的顺序。
  • parallel="tests": TestNG 将在同一个线程中运行相同的标记的所有方法,但是每个标记将在一个单独的线程中。这允许你将所有非线程安全的类分组在同一个中,并保证它们将在同一个线程中运行,同时利用尽可能多的线程来运行测试。

  • parallel="classes": TestNG将在同一个线程中运行同一个类中的所有方法,但是每个类都将在一个单独的线程中运行。

  • parallel="instances": TestNG将在同一个线程中运行相同实例中的所有方法,但是在两个不同实例上的两个方法将在不同的线程中运行。

    • thread-count 用于指定线程的个数。


九、TestNG其他使用技巧

除了前面介绍的功能外,TestNG 还有一些使用技巧,相对比较简单,这里通过一个例子来演示。

其它使用技巧


import org.testng.annotations.Test; import static org.testng.AssertJUnit.assertEquals; public class OtherTest { // 该条用例跳过执行 @Test(enabled = false) public void testCase1(){
        assertEquals(2+2, 4);
    } // 设定用例超时时间 @Test(timeOut = 3000) public void testCase2() throws InterruptedException {
        Thread.sleep(3001);
    } // 预设用例抛出的异常类型 @Test(expectedExceptions = RuntimeException.class) public void testCase3(){
        assertEquals(2/0,1);
    }

}
  • enabled 设置用例是否跳过执行,默认为:true ,表示不跳过。false 表示跳过执行。

  • timeOut 设置用例运行的超时间,3000 单位为毫秒,当用例运行时间超过 3000 毫秒则判定为失败。不管用例本身是否运行失败。

  • expectedExceptions 用来预设用例运行会出现的异常。例如 2/0 将会抛出 RuntimeException 类型的异常,如果出现异常则表示用例执行成功。


十、TestNG生成测试报告

TestNG 默认自带的有HTML格式的测试报告。这也充分说明拿它来做 UI 自动化测试的优势。

通过 Maven 生成报告


切换到 TestngTest 项目的根目录下,通过 mvn test 命令运行测试。

TestngTest> mvn test

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building TestngTest 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ TestngTest
 --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource ... ------------------------------------------------------- T E S T S ------------------------------------------------------- Running TestSuite Configuring TestNG with: org.apache.maven.surefire.testng.conf.TestNG652Configurator@104e3b2 Tests run: 19, Failures: 5, Errors: 0, Skipped: 2, Time elapsed: 3.862 sec <<< FAILURE! 

在该系列教程开始前,我已经说明了整个项目基于 Maven 创建。

现在打开 ..\TestngTest\target\surefire-reports\index.html 将会看到整个项目的运行结果。

通过 IntelliJ IDEA 生成测试报告


在 IntelliJ IDEA 中默认运行测试用例是不会生成HTML报告的,需要进行简单的配置。

菜单栏: “Run” -->“Edit Configuraction...” 。

如上图,选择运行测试用例的 testng.xml 文件-->“Configuration”-->“Listeners”--> 勾选“Use default reporters” 选项, 最后点击“OK” 按钮, 完成设置。

好了! 现在用 IntelliJ IDEA 运行 TestNG 测试用例一样可以生成报告了。




全部评论

相关推荐

点赞 2 评论
分享
牛客网
牛客企业服务