13

情况和问题

我有几个测试类,每个都有几个测试方法。所有测试在后台使用相同的测试数据库。每个测试类初始化它的数据库内容,然后在几个测试方法中测试东西。

当我单独运行每个测试时,它们都通过了。但是当我同时运行多个测试时(使用 maven 或我的 IDE,IntelliJ),不同测试类的方法会交错运行,例如。第二类的数据库初始化在第一类开始之后但在第一类的所有测试方法运行之前运行,因此这些方法将失败(因为数据库已经包含第二类的数据)。

我尝试过的一些事情,以及更多细节

最简单的解决方案是强制 TestNG 运行程序连续运行类(即,在运行另一个类的测试方法之前等待一个测试类的所有测试方法完成)。这可以做到吗?

我可以通过在我的套件中将每个类指定为单独的测试来做到这一点,但我不想这样做,因为这意味着每当我添加一个笨拙和错误的测试类时,我都必须向套件中添加一些东西-易于。

简单地要求 TestNG 不并行化任何东西(例如,将线程数设置为 1 或禁用并行运行)在这里没有帮助,因为方法仍然以错误的顺序运行(尽管不是同时)。

一种选择是为每个测试类使用不同的数据库,但我没有看到一种简单的方法来做到这一点(使用 JPA 和 Guice)。

我目前没有使用 DBUnit、Unitils 等;我不太了解这些工具,但我的印象是不能解决我的问题。

我正在使用 JPA 在每个测试类中初始化数据库(即创建实体对象并保存它们)。

4

7 回答 7

6

即使在顺序模式下,TestNG 也可以将同一套件中的测试方法交错。它确实保证了序列 @BeforeClass -> @Test -> @AfterClass 但它可以执行以下操作:

before class1
    test class1.method1
before class2
    test class2.method1
    test class1.method2
after class1
    test class2.method2
after class2

解决方案是强制每个类在不同的套件中(真正按顺序执行)。从 2.16 版开始,maven surefire 插件将每个类放在一个单独的套件中,因此问题得到了解决。

另一方面,IDEA(甚至是最新的 13 EAP)会生成一个 xml 文件,其中包含同一套件中的所有类。希望 IDEA 也能效仿并解决这个问题。在使用数据库等共享资源时,交错测试是一个很好的选择。

于 2013-09-07T05:00:46.363 回答
2

带着类似的问题来到这里。我认为 group-by-instances="true" 可能是一个解决方案。

于 2016-01-08T07:09:04.953 回答
1

TestNG 提供了几种并行策略。看起来methods对您的需求来说太激进了,但是您是否看过classes或可能看过instances

于 2013-06-24T16:20:16.990 回答
0

我不会在类级别使用dependsOnGroups,因为如果您所依赖的任何类中的任何测试方法失败,它根本不会运行您的类......这是使用“dependsOn”组的真正缺点(或方法)。我会先尝试在类级别设置 @Test(group = thisClassName),然后在 testng.xml 文件中使用测试标签标识类。然后控制你的类在 xml 中运行的顺序作为这些测试的列表。我相信您可能还需要在 xml 中的下一个更高级别的标记上设置 PreserveOrder = "True"。我会避免使用dependsOn,除非你真的需要它来进行依赖,而不是控制顺序。希望这可以帮助。-JR

于 2013-08-29T18:21:38.713 回答
0

我写了一篇文章讨论在 TestNG 中对测试进行排序的一些方法:

http://ancient-marinator.blogspot.com/2013/05/on-testing-scheduling-your-tests.html

当然,最好的信息来源是在家里:http ://testng.org/doc/index.html

于 2013-06-24T12:52:47.627 回答
0

使用方法拦截器(=编写并启用自定义拦截器)来控制排序。

此外,每个类都可能使用自己的数据库沙箱:将每个测试类包装到事务中可能会有所帮助。

为每个类设置单独的表/数据库后缀甚至可以让您的测试方法并行运行(我猜前两个选项不会)。

于 2013-06-25T04:31:44.587 回答
0

我们遇到了同样的问题,大多数人说这是由使用 dependsOn 引起的,但我们的解决方案只是在测试级别为我们的一些测试设置优先级。我设置了一个测试侦听器来重新确定我们的测试的优先级,以便它们以正确的顺序运行。这是基于 saberduck 在 https://github.com/cbeust/testng/issues/106中的解决方案

此解决方案将通过将测试优先级连接到类优先级来保留测试优先级。

package testng_Listeners;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import org.testng.IAnnotationTransformer;
import org.testng.Reporter;
import org.testng.annotations.ITestAnnotation;

//Listener to fix TestNG Interleaving issue. I had to re-write this as the original example I had did not allow for priority to be manually set on a test level.
public class RePrioritizingListener implements IAnnotationTransformer {

HashMap<Object, Integer> priorityMap = new HashMap<Object, Integer>();
Integer class_priorityCounter = 10000;
// The length of the final priority assigned to each method.
Integer max_testpriorityLength = 4;

@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {


// class of the test method.
Class<?> declaringClass = testMethod.getDeclaringClass();
// Current priority of the test assigned at the test method.
Integer test_priority = annotation.getPriority();
// Current class priority.
Integer current_ClassPriority = priorityMap.get(declaringClass);

if (current_ClassPriority == null) {
    current_ClassPriority = class_priorityCounter++;
    priorityMap.put(declaringClass, current_ClassPriority);
}

String concatenatedPriority = test_priority.toString();

// Adds 0's to start of this number.
while (concatenatedPriority.length() < max_testpriorityLength) {
    concatenatedPriority = "0" + concatenatedPriority;
}

// Concatenates our class counter to the test level priority (example
// for test with a priority of 1: 1000100001; same test class with a
// priority of 2: 1000100002; next class with a priority of 1. 1000200001)
concatenatedPriority = current_ClassPriority.toString() + concatenatedPriority;

//Sets the new priority to the test method.
annotation.setPriority(Integer.parseInt(concatenatedPriority));

String printText = testMethod.getName() + " Priority = " + concatenatedPriority;
Reporter.log(printText);
System.out.println(printText);

}
}

您还需要将侦听器添加到您的 testng.xml

<suite name="Suite" configfailurepolicy="continue" >
<listeners>
<listener class-name="testng_Listeners.RePrioritizingListener"></listener>
</listeners>
于 2017-06-27T19:43:44.893 回答