zoukankan      html  css  js  c++  java
  • TestNG 单元测试框架(针对于testNG.xml配置)

    https://blog.csdn.net/df0128/article/details/83243822

    (一)TestNG介绍与安装
    1、介绍
    TestNG 官网地址:http://testng.org/doc/

    TestNG是一个测试框架的灵感来自JUnit和NUnit,但引入一些新的功能,使它更强大和更容易使用,如:

    注释。
    在任意大线程池中运行测试,并提供各种策略(所有方法都在自己的线程中,每个测试类有一个线程,等等)。
    测试你的代码多线程是安全的。
    灵活的测试配置。
    数据驱动的测试支持(@dataProvider)。
    参数支持。
    强大的执行模型(不再有TestSuite)。
    通过各种工具和插件支持(Eclipse, IDEA, Maven 等..)。
    通过进一步的灵活性Beanshell。
    运行时和日志的默认JDK功能(无依赖性)。
    应用服务器测试的相关方法。
    TestNG 表示下一代(Next Generation的首字母)。它的设计覆盖所有类别的测试:单元、功能、端到端、集成等。
    2、安装
    本教程基于 IntelliJ IDEA 和 Maven ,所以,这里只介绍 Maven 的安装方式。

    <!-- https://mvnrepository.com/artifact/org.testng/testng -->
    <dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.13</version>
    <scope>test</scope>
    </dependency>
    (二)第一个测试用例
    1、第一个测试用例
    通过 IntelliJ IDEA 创建 FirstTest 测试类。编写如下代码:

    import org.testng.annotations.Test;
    import static org.testng.AssertJUnit.assertEquals;


    public class FirstTest {

    @Test
    public void testCase(){
    assertEquals(2+2, 4);
    }
    }
    通过 @Test 注解一个方法为测试用例。
    通过 assertEquals() 方法来断言两个数是否相等。

    运行测试:

    ===============================================
    Default Suite
    Total tests run: 1, Failures: 0, Skips: 0
    ===============================================
    我们先感官上对TestNG使用有一个初步认识。

    (三)TestNG 之 FixTrue
    1、什么是Fixture
    Test Fixture 是指一个测试运行所需的固定环境,准确的定义:

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

    2、TestNG 提供的Fixture 方法
    表:

    注解 说明
    @BeforeSuite 注解的方法在测试套件(中的所有用例)开始前运行一次
    @AfterSuite 注解的方法在测试套件(中的所有用例)结束后运行一次。
    @BeforeClass 注解的方法在当前测试类(中所有用例)开始前运行一次。
    @AfterClass 注解的方法在当前测试类(中所有用例)结束后运行一次。
    @BeforeTest 对于套件测试,在运行属于标签内的类的所有测试方法之前运行。
    @AfterTest 对于套件测试,在运行属于标签内的类的所有测试方法之后运行。
    @BeforeGroups 在调用属于该组的所有测试方法之前运行。
    @AfterGroups 在调用属于该组的所有测试方法之后运行。
    @BeforeMethod 注解的方法将在每个测试方法之前运行。
    @AfterMethod 注释的方法将在每个测试方法之后执行。
    3、实例
    接下来通过例子演示上面部分注解的用法。

    import org.testng.annotations.*;


    public class FixtureTest {

    //在当前测试类开始时运行。
    @BeforeClass
    public static void beforeClass(){
    System.out.println("-------------------beforeClass");
    }

    //在当前测试类结束时运行。
    @AfterClass
    public static void afterClass(){
    System.out.println("-------------------afterClass");
    }

    //每个测试方法运行之前运行
    @BeforeMethod
    public void before(){
    System.out.println("=====beforeMethod");
    }

    //每个测试方法运行之后运行
    @AfterMethod
    public void after(){
    System.out.println("=====afterMethod");
    }

    @Test
    public void testCase1(){
    System.out.println("test case 1");
    }

    @Test
    public void testCase2(){
    System.out.println("test case 2");
    }


    }
    运行上面的测试,执行结果如下。

    -------------------beforeClass
    =====beforeMethod
    test case 1
    =====afterMethod
    =====beforeMethod
    test case 2
    =====afterMethod
    -------------------afterClass

    ===============================================
    Default Suite
    Total tests run: 2, Failures: 0, Skips: 0
    ===============================================
    (四)testng.xml文件解析
    TestNG 与 Junit 比较大的一个差异就是前者通过 testng.xml 文件来配置测试用例的执行。 testng.xml文件可以很好的控制要执行的测试用例的粒度,及各种运行策略。

    目前testng.xml DTD(Document Type Definition; DTD是一种XML的约束方式。) 配置说明可以在:这里

    1、testng.xml 文件解析
    <suite name="Suite1" verbose="1" >
    <test name="Nopackage" >
    <classes>
    <class name="NoPackageTest" />
    </classes>
    </test>

    <test name="Regression1">
    <classes>
    <class name="test.sample.ParameterSample"/>
    <class name="test.sample.ParameterTest"/>
    </classes>
    </test>
    </suite>
    <suite>...</suite> 表示定义了的一个测试套件。
    name 定义测试套件的名称。
    verbose 定义命令行信息打印等级,不会影响测试报告输出内容;可选值(1|2|3|4|5) 
    <test>...</test> 表示定义了一个测试。
    name 定义测试的名称。
    <classes>...</classes> 表示定义一组测试类。
    <class .../> 表示定义一个测试类。
    name 指定要运行的测试类
    2、实例
    测试项目目录结果如下:

     

    testng.xml 配置文件如下:

    <!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" > 必须要添加,表示遵循的规范文件。
    在 testng.xml 文件上右键点击运行测试。

    运行结果如下:

     

    (五)测试级别设置
    在我们创建测试用例时,大概分三个层级。

    测试包(目录)
    测试类(文件)
    测试用例(@Test 注解的方法)
    接下来介绍,如何控制这三个级别用例的执行。当然,核心还是通过 testng.xml 文件配置。

    1、指定运行测试包
    <!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 指定测试包(目录)的名称。
    2、指定运行测试类
    <!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>
    指定测试类的运行,上一节已经介绍。

    3、指定运行测试用例
    <!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 允许我们给测试用例贴标签。我们可以根据这些标签有选择地的跳过或执行这些用例。

    1、实例
    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="测试套件" verbose="1" >
    <test name="简单测试">
    <groups>
    <run>
    <exclude name="异常" /> <!-- 排除不执行的测试用例 -->
    <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 配置。

    ……
    <groups>
    <run>
    <exclude name="异常" /> <!-- 排除不执行的测试用例 -->
    <include name="功能测试" /> <!-- 指定执行的测试用例 -->
    </run>
    </groups>
    ……
    再次运行测试:testCase1、testCase2 和 testCase3 三条用例将被执行。

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

    1、实例
    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 用例依赖
    当某一条用例运行失败时,其它用例必然也会失败,所以,我们就没有必要再运行其它用例了,这个时候我们就可以设置用例之间的依赖。

    1、测试方法依赖
    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() 不再被执行。
    2、测试组依赖
    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 用例参数化
    参数化也测试用例中常用的技巧之一,它可以增加用例的可配置性和减少相同用例的编写。

    1、通过 @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.xml 文件中设置。

    <!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来获取该值。
    2、通过 @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自动化测试的话运行速度就会非常慢,这个时候多线程技术就会变得很重要。

    1、多线程配置
    这里只介绍 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 还有一些使用技巧,相对比较简单,这里通过一个例子来演示。

    1、其它使用技巧

    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 类型的异常,如果出现异常则表示用例执行成功。
    ————————————————
    版权声明:本文为CSDN博主「Penny 要努力呀」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_22003641/article/details/79378353

  • 相关阅读:
    MyBatis
    泛型集合(经典)
    Java高级特性--------->>>>>实用类
    Java高级特性----->>>>集合
    【java面试题】StringBuilder与StringBuffer和String 的区别
    Java面向对象------>try{}catch(){}异常
    Java面向对象----->接口和抽象类
    Java修饰符------>static、native和final以及super和this关键字
    面向对象------->多态
    面向对象--->封装和继承
  • 原文地址:https://www.cnblogs.com/ht22ht22/p/11742027.html
Copyright © 2011-2022 走看看