单元测试框架testNG学习笔记

来源:互联网 发布:大逃杀网络延迟检测 编辑:程序博客网 时间:2024/05/22 10:40

testNG离线安装网站

http://dl.bintray.com/testng-team/testng-eclipse-release/

点击最下方的zipped,然后选择下载的版本进行下载

然后将site_assembly.zip解压缩到eclipse目录的dropins文件夹中,然后重启eclipse

 

 

JUnit是Java代码的单元测试

JUnit缺点:

    最初的设计,适用于单元测试,现在只用于各种测试。

    不能依赖测试

    配置控制欠佳(安装/拆卸)

    侵入性(强制扩展类,并以某种方式命名方法)

    静态编程模型(不必要的重新编译)

不适合管理复杂项目应用,JUnit复杂项目中测试非常棘手。

TestNG(Test Next Generation测试下一代)是一个测试框架 其灵感来自于Junit和NUnit但引入了一些新的功能,使其功能更强大,使用更方便

 

TestNG特点

    注解

    TestNG使用Java和面向对象的功能

      支持综合类测试(例如,默认情况下,不用创建一个新的测试每个测试方法的类的实例)

    独立的编译时测试代码和运行时配置/数据信息

    灵活的运行时配置

    主要介绍“测试组”。当编译测试,只要要求TestNG运行所有的“前端”的测试,或“快”,“慢”,“数据库”等

    支持依赖测试方法,并行测试,负载测试,局部故障

    灵活的插件API

    支持多线程测试

 

 

Testing的基本注解

在JUnit3 中用于指示测试方法的传统方式是将其名称加上前缀,该方法不能很好的扩展(例如如果想传递额外的参数到测试框架)

注解是从JDK5开始正式添加到Java语言中,testNG选择使用注解来注释测试类

 

 

Testing的注释列表

注解   描述

@BeforeSuite       在该套件的所有测试都运行在注释的方法之前,仅运行一次。

@AfterSuite   在该套件的所有测试都运行在注释方法之后,仅运行一次。

@BeforeClass        在调用当前类的第一个测试方法之前运行,注释方法仅运行一次。

@AfterClass    在调用当前类的第一个测试方法之后运行,注释方法仅运行一次

@BeforeTest 注释的方法将在属于<test>标签内的类的所有测试方法运行之前运行。

@AfterTest   注释的方法将在属于<test>标签内的类的所有测试方法运行之后运行。

@BeforeGroups   配置方法将在之前运行组列表。 此方法保证在调用属于这些组中的任何一个的第一个测试方法之前不久运行。

@AfterGroups      此配置方法将在之后运行组列表。该方法保证在调用属于任何这些组的最后一个测试方法之后不久运行。

@BeforeMethod 注释方法将在每个测试方法之前运行。

@AfterMethod     注释方法将在每个测试方法之后运行。

@DataProvider    标记一种方法来提供测试方法的数据。 注释方法必须返回一个Object [] [],其中每个Object []可以被分配给测试方法的参数列表。 要从该DataProvider接收数据的@Test方法需要使用与此注释名称相等的dataProvider名称。

@Factory 将一个方法标记为工厂,返回TestNG将被用作测试类的对象。 该方法必须返回Object []。

@Listeners      定义测试类上的侦听器。

@Parameters        描述如何将参数传递给@Test方法。

@Test 将类或方法标记为测试的一部分。

 

 

 

使用注释的好处

Testing通过查找注释来识别它感兴趣的方法,方法名称不限制任何模式或格式

可以将其他参数传递给注释

注释是强类型的,所以编译器会马上标记任何错误

测试类不在需要扩展任何东西(如testCase ,对于JUnit3)

 

 

 

testNG预期异常测试

在这里演示使用TestNG expectedExceptions来测试代码中的预期异常抛出

1.    运行时异常

例:

public class TestRuntime {

 

   @Test(expectedExceptions = ArithmeticException.class)

   public void divisionWithException() {

       int i = 1 / 0;

       System.out.println("After division the value of i is :"+ i);

    }

 

}

 

运行该程序,,如果异常类型是ArithmeticException则程序运行通过,但是控制台没有打印After division。。。因为预测到异常类型后直接通过脚本

 

 

检查异常

检查异常的用法与运行时异常相似,可以自定义异常类型,继承自exception,然后在函数定义中某一位置抛出自定义异常,

在函数调用中Test中注释(expectedExceptions=异常的的类型)即可

 

 

 

 

 

 

 

testNG忽略测试

当我们编写的代码并没有准备就绪,并且测试用例要测试该方法/代码是否失败(或成功),这时,在该测试的Test注解后注明不运行,可以控制该测试用例不执行(@Test(enabled = false))

注:当Test注释没有注明时,默认为true

例:

@Test // defaultenable=true

    public void test1() {

        Assert.assertEquals(true, true);

    }

 

    @Test(enabled = true)

    public void test2() {

        Assert.assertEquals(true, true);

    }

 

    @Test(enabled = false)

    public void test3() {

        Assert.assertEquals(true, true);

    }

 

 

TestNG超时测试

在测试用例中,我们可以设置某一用例的超时时间,当单条用例花费的时间超过设置的超时时间,那么TestNG将会中止它并将其标记为失败

超时也可用于性能测试,以确保方法在合理的时间内返回

例:

@Test(timeOut =5000) // time in mulliseconds

    public void testThisShouldPass() throwsInterruptedException {

        Thread.sleep(6000);

    }

 

 

testNG分组测试

分组测试是TestNG的一个新的创新功能,它允许我们将方法调度到适合的部分,并执行复杂的测试方法分组,使用<groups>标记在testng.xml文件中指定分组

1.    在方法上的分组(最后的代码(dependOngroups)在分组执行完毕后执行)

例:

 

@AfterGroups("database")

public void cleanDB() {

       System.out.println("cleanDB()");

    }

 

   @Test(groups = "selenium-test")

   public void runSelenium() {

       System.out.println("runSelenium()");

}

@Test(dependsOnGroups = {"database", "selenium-test" })

   public void runFinal() {

       System.out.println("runFinal");

    }

2.    在类上的分组

分组可以在类上应用,则该类中的所有公共方法都是该分组

例:略

如果执行多个类中的程序,则需要配置testng.xml文档,并且在运行前配置上该文件

例:

 

 

<?xml version="1.0"encoding="UTF-8"?>

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">

<suite name="TestAll">

   <test name="final">

       <classes>

           <class name="com.yiibai.TestSelenium" />

           <class name="com.yiibai.TestGroup" />

       </classes>

   </test>

   <!-- Run test method on group "selenium" only -->

   <test name="selenium">

       <groups>

           <run>

                <includename="selenium-test" />

           </run>

       </groups>

       <classes>

           <class name="com.yiibai.TestSelenium" />

           <class name="com.yiibai.TestGroup" />

       </classes>

   </test>

</suite>

该文档的大致意思为:第一行第二行的头必不可少,suite指定运行所有的套件,该套件下有两组测试

第一组测试中有两个测试类,因为先执行TestSelenium类,类中是selenium-test分组,所以在testGroup类中先执行的是中Selenium-test分组(虽然该类中database分组在最前面,没有按照顺序结构来执行)

第二组测试也是有两个测试类,但是文档中已经声明只执行两个类中selenium-test分组的测试用例,所以另一分组database并未执行

testNG套件测试

测试套件是用于测试软件程序的行为或一组行为的测试用例的集合,在testNG中,我们无法在测试源代码中定义一个套件,但他可以由一个XML文件表示,因为套件是执行的功能,它还允许灵活配置要运行的测试。套件可以包含一个或多个测试,并由《suite》标记定义

《suite》是testng.xml的跟标记,它描述了一个测试套件,它又由几个《test》部分组成,以下是《suite》接受的所有定义的合法属性

属性 描述

name        套件的名称,这是一个强制属性。

verbose   运行的级别或详细程度。

parallel     TestNG是否运行不同的线程来运行这个套件。

thread-count       如果启用并行模式(忽略其他方式),则要使用的线程数。

annotations   在测试中使用的注释类型。

time-out    在本测试中的所有测试方法上使用的默认超时。

 

 

在testng.xml中可以在suite标签只定义运行的classes类,也可以指定运行的packages包,在类中可以运行指定的分组或方法,或不运行指定的分组或方法

例1:

<groups>

       <run>

           <exclude name="brokenTests" />

           <include name="db" />

       </run>

   </groups>

 

   <classes>

       <class name="com.yiibai.TestDatabase" />

</classes>

 

 

 

例2:<classes>

       <class name="com.yiibai.TestConfig" />

       <class name="com.yiibai.TestOrder">

           <methods>

                <includename="testMakeOrder" />

                <includename="testUpdateOrder" />

                <!--

                    <excludename="testMakeOrder" />

                 -->

           </methods>

       </class>

    </classes>

 

例3:

<suite name="TestAll">

 

   <test name="order">

       <packages>

           <package name="com.yiibai.*" />

       </packages>

   </test>

 

</suite>

 

 

TestNG依赖测试

有时,我们可能需要以特定顺序调用测试用例中的方法,或者可能希望在方法之间共享一些数据和状态。TestNG支持这种依赖关系,因为它支持在测试方法之间显式依赖的声明

TestNG允许指定依赖关系:

在@Test注释中使用属性 dependsOnMethods,或者在@Test注释中使用属性dependsOnGroups,如果依赖方法失败,则将跳过所有后续测试方法

注意依赖的类或方法必须用双引号引起,如果依赖的类多于1个则用大括号引起,类或方法间用逗号隔开

 

 

TestNG参数化测试

在大多数情况下,会遇到业务逻辑需要大量测试的场景,参数化测试允许开发人员使用不同的值运行相同的测试

TestNG可以通过两种不同的方式将参数直接传递给测试方法:

使用testng.xml

使用数据提供者

1.         使用testng.xml传递参数

在文件中通过标签《parameter》来指定参数名和参数值

例:<parameter name="dbconfig" value="db.properties"/>

在类中函数调用的时候通过@Parameters(“参数名”)调用,并在函数参数列表中与标签中的参数名参数类型保持一致,在函数中直接用就行

注:

在testng.xml文件中可以在suite和test标签内定义参数符合规律:

1.    在suite范围内定义某个参数的值,对所有test有效

2.    在test范围内定义某个参数的值,只对该test有效

3.    如果同时在suite和test中定义某个参数,test范围的值会屏蔽suite的值

 

 

2.使用DataProvider传递参数

如果需要传递复杂的参数或者从Java中创建参数(复杂对象,对象从属性文件或者数据库中读取的等),这样,可以使用dataProvider来给需要的测试提供参数

所谓数据提供者,就是一个能返回对象数组的方法,并且这个方法被@DataProvider注解标注

被@Test标注的方法通过dataProvider属性指明其数据提供商。这个名字必须与@DataProvider(name="...") 中的名字相一致。

 

 

2. DataProvider返回的是一个Object的二维数组,二维数组中的每个一维数组都会传递给调用函数,作为参数使用。运行的时候,会发现, @Test标识的test method被执行的次数和object[][]包含的一维数组的个数是一致的,而@Test标识的函数的参数个数,也和object内一维数组内的元素数是一致的(DataProvider支持传递一个对象参数,例:return new Object[][] { { map } };)

例:

@Test(dataProvider= "provideNumbers")

    public void test(int number, int expected){

        Assert.assertEquals(number + 10,expected);

}

 

    @DataProvider(name ="provideNumbers")

    public Object[][] provideData() {

 

        return new Object[][] { { 10, 20 }, {100, 110 }, { 200, 210 } };

    }

 

 

注:DataProvider注解函数可以支持根据测试方法名称传递不同的参数,步骤为:

1.    在被DataProvider注解的函数参数列表中添加Method Method参数(Method参数的引入包为java.lang.reflect.Method)

2.    用if语句通过method.getName().equals(“test函数名”)判断函数名,返回不同类型的Object对象

注:DataProvider也可以根据ITestContext传递不同的参数,步骤:

1.      在被DataProvider注解的函数参数列表中添加ITestContext context(ITestContext引入包为org.testng.ITestContext)

2.      通过context.get…方法获取XML配置文件中类或分组名称

3.      通过if语句判断分组或类的类型返回不同类型的Object对象

 

例:for (String group :context.getIncludedGroups()) {

                   if("groupA".equals(group)) {

                       result = new Object[][] { { 1 }};

                       break;

                   }

 

 

 

通过注解@Test的属性invocationCount,threadPoolSize我们可以设置脚本进行的次数,开启的线程池中线程的数量,可用来进行负载测试!