如果将测试方法的第一个参数申明为java.lang.reflect.Method,TestNG将使用这个第一个参数来
传递当前测试方法。当多个测试方法使用同一个@DataProvider而需要依当前申请数据的方法而
定来返回不同值时特别有用。
举例说明,下面的代码在@DataProvider中打印测试方法的名字:
@DataProvider(name = "dp")
public Object[][] createData(Method m) {
System.out.println(m.getName()); // print test method name
return new Object[][] { new Object[] { "Cedric" }};
}
@Test(dataProvider = "dp")
public void test1(String s) {
}
@Test(dataProvider = "dp")
public void test2(String s) {
}
将会显示:
test1
test2
5.6 - Dependent methods
有些时候,你需要你的测试方法按照一个特定的顺序被调用。这非常有用,比如:
* 在运行更多测试方法前确认特定数量的测试方法调用完成并且成功
* 初始化测试并希望这个初始化方法也作为测试方法(被标记为@Before/After的方法将不作为
最终报告的一部分)
为了做到这点,需要使用@Test注解的dependsOnMethods属性或者dependsOnGroups属性。
有两种依赖:
* 强依赖。在运行你的测试方法前所有依赖方法必须运行并且成功。哪怕有一个依赖方法失败,
测试方法都不会被调用,在报告中将被标记为SKIP。
* 软依赖。测试方法在依赖方法运行后总是会被运行,即使某些依赖方法失败。对于只想确认测
试方法是按照特定顺序运行,而测试方法并不真正依赖其他方法是否成功的情况,非常有用。软依
赖通过在@Test注解中增加"alwaysRun=true"来实现。
这里有一个强依赖的例子:
@Test
public void serverStartedOk() {}
@Test(dependsOnMethods = { "serverStartedOk" })
public void method1() {}
在这个例子中,method1()被申明依赖于方法serverStartedOk(),这保证serverStartedOk() 方法将
总是首先被调用。
也可以让方法依赖于完整的测试组:
@Test(groups = { "init" })
public void serverStartedOk() {}
@Test(groups = { "init" })
public void initEnvironment() {}
@Test(dependsOnGroups = { "init.* })
public void method1() {}
在这里例子中,method1()被申明依赖于任何匹配正则表达式"init.*"的组,这保证了方法serverSt
artedOk()和initEnvironment()总是在method1()前被调用。
注意:前面说明说,在测试运行期间,属于同一个组的方法的调用顺序并不保证相同。如果一个方
法的依赖失败了,而且是强依赖(默认alwaysRun=false),这个方法将不被标记为FAIL而是SKIP。被
跳过的方法在最终的报告中报告(在HTML中用红和绿之外的其他颜色),这很重要,因为被跳过
的方法并不一定是失败。
dependsOnGroups和dependsOnMethods都接受正则表达式作为参数。对于dependsOnMethods,
如果你依赖的方法巧合有多个重载的版本,所有装载的方法都将被调用。如果你只想调用重载的
方法中的一个,请使用dependsOnGroups。
有关方法依赖的更高级的例子,请参考本文档,将使用继承来提供一个优雅的解决方案来处理多
重依赖的问题。
5.7 - Factories
工厂类容许你动态创建测试案例。例如,想象你需要创建一个测试方法,访问一个web站点上的
页面很多次,而你希望用不同的值来调用它:
- public class TestWebServer {
- @Test(parameters = { "number-of-times" })
- public void accessPage(int numberOfTimes) {
- while (numberOfTimes-- > 0) {
- // access the web page
- }
- }
- }
-
- testng.xml:
- [xhtml] view plain copy
- <test name="T1">
- <parameter name="number-of-times" value="10"/>
- <class name= "TestWebServer" />
- </test>
- <test name="T2">
- <parameter name="number-of-times" value="20"/>
- <class name= "TestWebServer"/>
- </test>
- <test name="T3">
- <parameter name="number-of-times" value="30"/>
- <class name= "TestWebServer"/>
- </test>
-
- 这种方式很快就会变的难于管理,所以作为替换品,你可以使用factory:
- [java] view plain copy
- public class WebTestFactory {
- @Factory
- public Object[] createInstances() {
- Object[] result = new Object[10];
- for (int i = 0; i < 10; i++) {
- result[i] = new WebTest(i * 10);
- return result;
- }
- }
-
- 而新的测试类是这样:
- [java] view plain copy
- public class WebTest {
- private int m_numberOfTimes;
- public WebTest(int numberOfTimes) {
- m_numberOfTimes = numberOfTimes;
- }
- @Test
- public void testServer() {
- for (int i = 0; i < m_numberOfTimes; i++) {
- // access the web page
- }
- }
- }
复制代码testng.xml只需要引用简单引用这个包含factory方法的类,因为测试实例将在运行时被创建。 <class name="WebTestFactory" />
工厂类将像@Test和@Before/After一样接收参数,必须返回Object[]。返回的对象可以是任何类( 不一定要求是和factory类一样),并且他们甚至都不需要包含TestNG的注解(这种情况下他们将 被testNG忽略)。 5.8 - Class level annotations @Test注解可以放置在类上: - @Test
- public class Test1 {
- public void test1() {
- }
- public void test2() {
- }
- }
-
- 类级别注解的效果是将这个类的所有的public方法都变成测试方法,即使他们没有被注解。还可以在需要增加属性的方法上重复@Test注解。
- 例如:
- [java] view plain copy
- @Test
- public class Test1 {
- public void test1() {
- }
- @Test(groups = "g1")
- public void test2() {
- }
- }
复制代码
|