TestNG文档翻译

  • 介绍
本文是 http://testng.org/doc/documentation-main.html的翻译,如有错误或者不妥之处欢迎指出!
5.7 - 依赖
有时候,你需要指定测试方法执行的顺序。这里有几个例子:
  • 在运行更多的测试方法之前确保有确定数量的测试方法已经完成并成功。
  • 为了在测试方法之前初始化完成(使用@Before/After注解的方法将不会再最终的报告中)。
TestNG允许你通过注解或者XML来指定依赖。
5.7.1 - 通过注解添加依赖
在@Test注解中你可以使用属性dependsOnMethods或者dependsOnGroups。 以后两种类型的依赖:
  • 硬依赖。所有依赖的方法必须运行并成功。如果所有的依赖中有任意一个失败的话,将不会被执行并在报告中标识为SKIP。
  • 软依赖。这个总会在依赖的方法之后运行,即使有失败也如此。当你只是需要确保运行的顺序而不要求是否成功的情况下,这是很有用的。软依赖可以通过在@Test注解中添加属性"alwaysRun=true"。
这里有一个硬依赖的例子: [codesyntax lang="java"]
@Test
public void serverStartedOk() {}
 
@Test(dependsOnMethods = { "serverStartedOk" })
public void method1() {}
[/codesyntax] 在这个例子中,method1()被申明依赖了方法serverStartedOk(), 这样会保证serverStartedOk()总是先执行。 你也可以在一个方法上添加一个组依赖: [codesyntax lang="java"]
@Test(groups = { "init" })
public void serverStartedOk() {}
 
@Test(groups = { "init" })
public void initEnvironment() {}
 
@Test(dependsOnGroups = { "init.*" })
public void method1() {}
[/codesyntax] 在这个例子中,方法method1()被申明依赖了任何匹配表达式"init.*"的组,这保证了方法serverStartedOk()和initEnvironment()总是在方法method1()之前运行。
Note:  as stated before, the order of invocation for methods that belong in the same group is not guaranteed to be the same across test runs.
If a method depended upon fails and you have a hard dependency on it (alwaysRun=false, which is the default), the methods that depend on it are not marked as FAIL but as SKIP.  Skipped methods will be reported as such in the final report (in a color that is neither red nor green in HTML), which is important since skipped methods are not necessarily failures. Both dependsOnGroups and dependsOnMethods accept regular expressions as parameters.  For dependsOnMethods, if you are depending on a method which happens to have several overloaded versions, all the overloaded methods will be invoked.  If you only want to invoke one of the overloaded methods, you should use dependsOnGroups. For a more advanced example of dependent methods, please refer to this article, which uses inheritance to provide an elegant solution to the problem of multiple dependencies. By default, dependent methods are grouped by class. For example, if method b() depends on method a() and you have several instances of the class that contains these methods (because of a factory of a data provider), then the invocation order will be as follows: [codesyntax lang="php"]
a(1)
a(2)
b(2)
b(2)
[/codesyntax] TestNG will not run b() until all the instances have invoked their a() method. This behavior might not be desirable in certain scenarios, such as for example testing a sign in and sign out of a web browser for various countries. In such a case, you would like the following ordering: [codesyntax lang="php"]
signIn("us")
signOut("us")
signIn("uk")
signOut("uk")
[/codesyntax] For this ordering, you can use the XML attribute group-by-instances. This attribute is valid either on <suite> or <test>: [codesyntax lang="xml"]
<suite name="Factory" group-by-instances="true">
or
  <test name="Factory" group-by-instances="true">
[/codesyntax]
5.7.2 - 在XML中添加依赖
另外,你还可以在testng.xml文件中执行你的组依赖。你可以使用<dependencies>标签: [codesyntax lang="xml"]
<test name="My suite">
  <groups>
    <dependencies>
      <group name="c" depends-on="a  b" />
      <group name="z" depends-on="c" />
    </dependencies>
  </groups>
</test>
[/codesyntax] <depends-on>属性包含了空格分隔的几个组依赖。
5.8 - 工厂
Factories允许你动态地创建测试用例。例如,你想要创建一个会在一个站点中多次访问页面的测试方法,但是传递不同的值: [codesyntax lang="java"]
public class TestWebServer {
  @Test(parameters = { "number-of-times" })
  public void accessPage(int numberOfTimes) {
    while (numberOfTimes-- > 0) {
     // access the web page
    }
  }
}
[/codesyntax] [codesyntax lang="xml"]
<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>
[/codesyntax] 这样的话会变得很难管理,这时候你可以使用一个工厂(factory)来替代: [codesyntax lang="java"]
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;
  }
}
[/codesyntax] 然后,新的测试类就是现在这样的: [codesyntax lang="java"]
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
    }
  }
}
[/codesyntax] 你的testng.xml只需要引用包含工厂(factory)方法的类即可,测试类的实例会在运行期被创建: [codesyntax lang="xml"]
<class name="WebTestFactory" />
[/codesyntax] 工厂(factory)方法可以接受参数,正如@Test和@Before/After一样, 它的返回值类型必须是Object[]。返回的对象可以是任意类型(没必要和工厂类时同一个类型),它们甚至都不需要包含TestNG的注解(它们可能会被TestNG忽略)。 工厂也可以使用数据源, 你可考虑把@Factory注解放到一个普通的方法或者是一个构造函数上。这里有一个构造函数上使用工厂的例子: [codesyntax lang="java"]
@Factory(dataProvider = "dp")
public FactoryDataProviderSampleTest(int n) {
  super(n);
}
 
@DataProvider
static public Object[][] dp() {
  return new Object[][] {
    new Object[] { 41 },
    new Object[] { 42 },
  };
}
[/codesyntax] 这个例子会让TestNG创建两个测试类,在构造函数上的参数n会有41和42两个值。
5.9 - 类级别注解
5.17 - TestNG监听器
有几个接口允许你修改TestNG的行为。这些接口叫做“TestNG监听器”。这里有几个监听器: 当你实现了其中的一个接口后,你可以通过下面几种方式来让TestNG知道这一点:
5.17.1 - 在testng.xml或者Java中指定监听器
这里展示了如何在你的testng.xml文件中定义监听器: [codesyntax lang="xml"]
<suite>
 
  <listeners>
    <listener class-name="com.example.MyListener" />
    <listener class-name="com.example.MyMethodInterceptor" />
  </listeners>
 
...
[/codesyntax]   或者你喜欢在Java中定义监听器的话就是这样的; [codesyntax lang="java"]
@Listeners({ com.example.MyListener.class, com.example.MyMethodInterceptor.class })
public class MyTest {
  // ...
}
[/codesyntax]   @Listeners这个注解可以包含除了IAnnotationTransformer和IAnnotationTransformer2以外的实现了接口org.testng.ITestNGListener的类。原因是这些监听器需要在过程中让TestNG非常清楚地知道,以便TestNG使用它们来重新你的注解,因此你需要在你的testng.xml文件中指定这些监听器。 记住注解@Listeners将会应用在你的套件文件中,所以你需要在testng.xml文件中指定。 如果你想要限制这个范围(例如,只在当前类中运行),你的监听器中的代码能够首先检查测试方法并决定什么时候来运行。这里有一个已经完成的例子。 1.首先定义一个注解用来指定限制: [codesyntax lang="java"]
@Retention(RetentionPolicy.RUNTIME)
@Target ({ElementType.TYPE})
public @interface DisableListener {}
[/codesyntax] 2.在你的监听器中添加一个编辑检查: [codesyntax lang="java"]
public void beforeInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
    ConstructorOrMethod consOrMethod =iInvokedMethod.getTestMethod().getConstructorOrMethod();
    DisableListener disable = consOrMethod.getMethod().getDeclaringClass().getAnnotation(DisableListener.class);
    if (disable != null) {
        return;
    }
    //else resume your normal operations
}
[/codesyntax] 3.在有监听器的类上添加注解后将不会执行:   [codesyntax lang="java"]
@DisableListener
@Listeners({ com.example.MyListener.class, com.example.MyMethodInterceptor.class })
public class MyTest {
  // ...
}
[/codesyntax]
5.17.2 - 通过ServiceLoader指定监听器
Finally, the JDK offers a very elegant mechanism to specify implementations of interfaces on the class path via the ServiceLoader class. With ServiceLoader, all you need to do is create a jar file that contains your listener(s) and a few configuration files, put that jar file on the classpath when you run TestNG and TestNG will automatically find them. Here is a concrete example of how it works. Let's start by creating a listener (any TestNG listener should work): 未完待续。。。

转载于:https://my.oschina.net/surenpi/blog/816972

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值