TestNG指南5-测试方法、测试类与测试组

5.1 – 测试组(Test groups)

TestNG允许执行复杂的测试方法分组。不仅可以申明方法属于组,而且可以指定组包含其他组。然后TestNG可以被调用,并被要求包含某些组(或正则表达式)和排除其他的组。如果想要紧接着运行两个不同的测试配置,这将给如何划分测试的带来了最大的灵活性,且不需要重新编译。

例如,非常普遍的需要至少两种测试:

  • 检入(Check-in)测试:这些测试将在提交新代码之前运行,要求测试能够快速完成,仅确信没有破坏基础功能。
  • 功能测试:这些测试应该覆盖软件的所有功能,并且每日至少运行一次,尽管理想的是持续运行。

检入测试是功能测试的子集, TestNG 允许使用测试组以非常直接的方式说明这点。例如:你可以这样构造测试,通过申明整个测试类属于“functest”组,另外两个方法属于“checkintest”组:

public class Test1 {

    @Test(groups = { "functest", "checkintest" })

    public void testMethod1() {

    }

   

    @Test(groups = { "functest", "checkintest" })

    public void testMethod2() {

    }

   

    @Test(groups = { "functest" })

    public void testMethod3() {

    }

}

 

调用TestNG使用:

<test name="Test1">

    <groups>

       <run>

           <include name="functest" />

       </run>

    </groups>

    <classes>

       <class name="example1.Test1" />

    </classes>

</test>

将运行测试类中的所有方法,而使用checkintest调用将只运行testMethod1() 和testMethod2().

下面是另外一个例子,这次使用了正则表达式。假设某些测试方法不能在Linux下运行,测试可能这样写:

@Test

public class Test1 {

    @Test(groups = { "windows.checkintest" })

    public void testWindowsOnly() {

    }

   

    @Test(groups = { "linux.checkintest" })

    public void testLinuxOnly() {

    }

   

    @Test(groups = { "windows.functest" })

    public void testWindowsToo() {

    }

}

 

你可以使用下面的testng.xml只运行Windows方法:

<test name="Test1">

    <groups>

       <run>

           <include name="windows.*" />

       </run>

    </groups>

    <classes>

       <class name="example1.Test1" />

    </classes>

</test>

 

注意: TestNG 使用正则表达式,而不使用wildmats。要知道这个差别(例如:用“.*”匹配“所有”——圆点星号,而不是“*”)。

 

方法组(Method groups)

 

也可以排除或包括个别方法:

<test name="Test1">

    <classes>

       <class name="example1.Test1">

           <methods>

              <include name=".*enabledTestMethod.*" />

              <exclude name=".*brokenTestMethod.*" />

           </methods>

       </class>

    </classes>

</test>

 

这在屏蔽单个方法而不用重新编译任何代码时就能派得上用场。但并不推荐用得太多,因为在你开始重构Java代码(在标签中使用的正则表达式可能不再匹配测试方法)时,它往往会破坏你的测试框架。

5.2 – 组中组(Groups of groups)

组也可以包含其他组,这些组被称为“MetaGroups”。例如:你可能想要定义一个“all”组,包括“checkintest”和 “functest”。“functest”自身将包含“windows” 和 “linux”组,而“checkintest”将只包含“windows”。在你的属性文件中应该这样定义:

<test name="Regression1">

    <groups>

       <define name="functest">

           <include name="windows" />

           <include name="linux" />

       </define>

       <define name="all">

           <include name="functest" />

           <include name="checkintest" />

       </define>

       <run>

           <include name="all" />

       </run>

    </groups>

    <classes>

       <class name="test.sample.Test1" />

    </classes>

</test>

 

5.3 – 排除组(Exclusion groups)

TestNG 允许包含组也允许排除组.

例如:因为最近的修改还没来得及修复它们时,让测试临时中断就非常有用。然而,想要干净地运行功能测试,你得屏蔽掉这些测试,但是记住它们将来需要被重新激活。

解决这个问题的简单办法是建立一个“broken”组,并让这些测试方法属于它。例如:在上例中,我知道testMethod2() 现在被破坏了,所有我想屏蔽它:

    @Test(groups = { "checkintest", "broken" })

    public void method2() {

       //...

    }

现在我所需要做的只是在运行中排除这个组:

<test name="Simple example">

    <groups>

       <run>

           <include name="checkintest" />

           <exclude name="broken" />

       </run>

    </groups>

    <classes>

       <class name="example1.Test1" />

    </classes>

</test>

用这种方法,我将得到一个干净的测试运行,同时记录了那些被屏蔽并需要后续修复的测试。

注意:你也可以使用@Test和@Before/After注解的“enabled”属性,个别地屏蔽测试。

5.4 – 部分组(Partial groups)

你可以在类级别上定义组,然后在方法级别上添加组:

@Test(groups = { "checkin-test" })

public class All {

    @Test(groups = { "func-test" })

    public void method1() {

       //...

    }

   

    public void method2() {

       //...

    }

}

 

在这个类中,method2() 属于“checkin-test”组,在类的级别上定义。而method1() 同时属于“checkin-test”和“func-test”组.

5.5 – 参数

测试方法不一定没有参数,你可以在每个测试方法上使用任意数目的参数,并使用@Parameters注解让TestNG传递正确的参数。

设置参数有两种方式:使用testng.xml或者编码。

  5.5.1 – 用testng.xml传递参数

如果参数使用简单值,可以在testng.xml 中指定它:

    @Parameters( { "first-name" })

    @Test

    public void testSingleString(final String firstName) {

       System.out.println("Invoked testString " + firstName);

       assert "Cedric".equals(firstName);

    }

 

 

在这段代码中,我们指定Java方法的参数firstName应该接收被称为first-name的XML参数的值,XML参数在testng.xml中定义:

<suite name="My suite">

    <parameter name="first-name" value="Cedric" />

    <test name="Simple example">

    <!-- ... -->

 

 

上述技法同样可用于@Before/After和@Factory注解:

    @Parameters( { "datasource", "jdbcDriver" })

    @BeforeMethod

    public void beforeTest(final String ds, final String driver) {

       m_dataSource = ...; // look up the value of datasource

       m_jdbcDriver = driver;

    }

 

 

这次,两个Java参数dsdriver 将分别接收属性datasource和jdbc-driver的值。

使用@Optional注解,可将参数定义为可选:

    @Parameters("db")

    @Test

    public void testNonExistentParameter(@Optional("mysql") final String db) {...

    }

 

 

如果在testng.xml文件中没有找到名为“db” 的参数,测试方法将接收由@Optional注解指定的默认值“mysql”。

@Parameters注解可用于以下情形:

  • 已有@Test、@Before/After或 @Factory注解的任何一个方法.
  • 测试类有且仅有一个构造器。在该情形下,无论测试是否需要实例化,TestNG将调用带有参数的特殊构造器,初始化指定在testng.xml 的值。本特性可用来初始化类的属性值,然后在测试方法中使用。

注意:

·   XML参数被按照注解中的相同顺序映射成Java参数,如果数目不匹配TestNG将报错。

·   参数有范围限制。在testng.xml 中,既可以在<suite>标签也可以在<test>下定义参数。如果两个参数有相同的名称,则在<test>标签下的参数优先。这是很方便的,如果希望指定一个参数可适用于整个测试,且只在某个测试中覆盖它的值。

  5.5.2 - 用DataProviders传递参数

在testng.xml中指定参数,在以下情形下可能存在不足:

  • 没有使用testng.xml.
  • 需要传递复杂的参数,或者参数需要由Java创建(复杂对象、从属性文件或数据库读取对象,等等……).

在这些情形下,可以使用数据供应者为测试提供需要的值。数据供应者是Java类中返回二维数组对象的一个方法。本方法使用@DataProvider 注解:

   

    //This method will provide data to any test method that declares that its Data Provider

    //is named "test1"

    @DataProvider(name = "test1")

    public Object[][] createData1() {

       return new Object[][] { { "Cedric", new Integer(36) },

              { "Anne", new Integer(37) }, };

    }

   

    //This test method declares that its data should be supplied by the Data Provider

    //named "test1"

    @Test(dataProvider = "test1")

    public void verifyData1(final String n1, final Integer n2) {

       System.out.println(n1 + " " + n2);

    }

 

将打印:

Cedric 36

Anne 37

 

测试方法用@Test注解的dataProvider属性指定其数据供应者。名称必须与数据供应者类中用@DataProvider(name="...")注解的名称一致.

缺少情况下,数据供应者将查找当前测试类或其基类。如果想要将数据供应者放在不同的类,则必须是一个静态方法,并在dataProviderClass 属性中指定该类:

 

public class StaticProvider {

    @DataProvider(name = "create")

    public static Object[][] createData() {

       return new Object[][] { new Object[] { new Integer(42) } };

    }

}

 

 

public class MyTest {

    @Test(dataProvider = "create", dataProviderClass = StaticProvider.class)

    public void test(final Integer n) {

       // ...

    }

}

 

 

数据供应者方法可能返回下列两种类型之一:

  • 二维数组对象(Object[][]),其第一维大小是测试方法将要调用的次数,二维大小包含一个与测试方法的参数类型一致的对象排列(如上例所示)。
  • Iterator<Object[]>,与Object[][]的唯一不同是Iterator允许延迟创建测试数据。TestNG将调用迭代器,然后带参数的测试方法靠迭代器一个接一个地返回参数值。如果你有大量的参数集传递到方法并且不想像前面那样创建它们,则使用Iterator<Object[]>就特别有用。

下面是本特性在JDK 1.4和JDK5(注意:JDK1.4示例未使用范型)下的例子:

    /**

     * @testng.data-provider name="test1"

     */

    public Iterator createData() {

       return new MyIterator(DATA);

    }

 

 

   

    @DataProvider(name = "test1")

    public Iterator testXXX() {

       return null;

    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值