Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何确保TestNG连续而不是交错地在测试类上运行方法? 形势与问题_Testng - Fatal编程技术网

如何确保TestNG连续而不是交错地在测试类上运行方法? 形势与问题

如何确保TestNG连续而不是交错地在测试类上运行方法? 形势与问题,testng,Testng,我有几个测试类,每个类都有几个测试方法。所有测试都在后台使用相同的测试数据库。每个测试类初始化其数据库内容,然后在几个测试方法中测试内容 当我单独运行每个测试时,它们都通过了。但当我同时运行多个测试时(使用maven或IDE IntelliJ),不同测试类的方法是交叉运行的,例如,第二个类的数据库初始化在第一个类启动之后但在第一个类的所有测试方法运行之前运行,因此这些方法将失败(因为数据库已经包含第二类的数据) 我试过一些东西,还有一些细节 最简单的解决方案是强制TestNG运行程序连续运行类(

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

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

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

我可能可以通过在套件中将每个类指定为单独的测试来实现这一点,但我不想这样做,因为这意味着每当我添加一个笨拙且容易出错的测试类时,我都必须向套件中添加一些内容

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

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

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


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

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


当然,最好的信息来源是在家里:

TestNG提供了几种并行策略。看起来
方法对您的需求来说太过激进,但是您是否看过
或者
实例

使用(=编写并启用自定义方法)来控制顺序

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


为每个类设置单独的tables/db后缀甚至可以让您的测试方法并行运行(我想前两个选项不会).

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

即使在顺序模式下,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也会这样做并解决这个问题。在使用共享资源(如数据库)时,交叉测试是一个很好的选择。

出现了类似的问题。我认为group by instances=“true”可能是一个解决方案。

我们遇到了同样的问题,大多数人说这是由于使用dependsOn造成的,但我们的解决方案只是在测试级别为我们的一些测试设置优先级。我设置了一个测试侦听器来重新排列测试的优先级,以便它们以正确的顺序运行。这是基于saberduck在年提出的解决方案

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

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\u侦听器;
导入java.lang.reflect.Constructor;
导入java.lang.reflect.Method;
导入java.util.HashMap;
导入org.testng.IAnnotationTransformer;
导入org.testng.Reporter;
导入org.testng.annotations.ITestAnnotation;
//监听器修复TestNG交错问题。我不得不重新编写这个示例,因为我的原始示例不允许在测试级别上手动设置优先级。
公共类重新设置优先级侦听器实现了IANotationTransformer{
HashMap priorityMap=新HashMap();
整数类_优先级计数器=10000;
//分配给每个方法的最终优先级的长度。
整数max_testpriorityLength=4;
@凌驾
公共void转换(ITestAnnotation注释、类testClass、构造函数testConstructor、方法testMethod){
//测试方法的类别。
类declaringClass=testMethod.getDeclaringClass();
//在测试方法中指定的测试的当前优先级。
整数test_priority=annotation.getPriority();
//当前类优先级。
整数current_ClassPriority=priorityMap.get(declaringClass);
if(当前_类优先级==null){
当前_ClassPriority=class_priorityCounter++;
priorityMap.put(declaringClass,当前_类优先级);
}
字符串concatenatedPriority=test_priority.toString();
//将0添加到此数字的开头。
while(concatenatedPriority.length()<suite name="Suite" configfailurepolicy="continue" >
<listeners>
<listener class-name="testng_Listeners.RePrioritizingListener"></listener>
</listeners>