Java 在Eclipse'中对单元测试进行排序;s JUnit视图
Eclipse中的JUnit视图似乎对测试进行随机排序。我怎样才能按类名排序呢?马克写道: 它根据执行时间来命令他们, 也许你应该整理一下你的方法? 源/排序成员 马克是对的。但是您不能对单元测试进行排序。不允许猜测处决的顺序 单元测试必须独立构建,而且是随机的,UnitRunner如何调用它们Java 在Eclipse'中对单元测试进行排序;s JUnit视图,java,eclipse,junit,Java,Eclipse,Junit,Eclipse中的JUnit视图似乎对测试进行随机排序。我怎样才能按类名排序呢?马克写道: 它根据执行时间来命令他们, 也许你应该整理一下你的方法? 源/排序成员 马克是对的。但是您不能对单元测试进行排序。不允许猜测处决的顺序 单元测试必须独立构建,而且是随机的,UnitRunner如何调用它们 在大多数情况下,测试方法按字母顺序排序。课程是随机的。尝试使用TestSuite来排序测试。如果您确实需要JUnit测试之间的硬依赖,请尝试 JExample将生产者-消费者关系引入单元测试。 生产者是
在大多数情况下,测试方法按字母顺序排序。课程是随机的。尝试使用TestSuite来排序测试。如果您确实需要JUnit测试之间的硬依赖,请尝试 JExample将生产者-消费者关系引入单元测试。
生产者是一种测试方法,它将被测单位作为返回值产生。
消费者是一种测试方法,它取决于一个或多个生产者及其返回值 您可以,对于Junit4.4或4.5
import jexample.Depends;
@Test
@Depends("#testEmpty")
public Stack<Integer> testPush(Stack<Integer> $) {
$.push(42);
assertFalse($.isEmpty());
return $;
}
导入jexample.dependens;
@试验
@取决于(“#testEmpty”)
公共堆栈testPush(堆栈$){
美元推送(42);;
assertFalse($.isEmpty());
返回美元;
}
如本文所述: JUnit框架试图实现的一件事是测试隔离 缺点是,这使得很难指定测试用例执行的顺序,这对于任何类型的依赖测试都是必不可少的。
开发人员使用了不同的技术来解决这个问题,比如按字母顺序指定测试用例,或者严重依赖fixture(
@Before
@Before
)来正确设置
这些变通方法对于成功的测试来说很好,但是对于失败的测试来说,它们有一个不方便的结果:每个后续的依赖测试也会失败。在某些情况下,这可能导致大型测试套件报告不必要的故障
所以要小心:如果您保留了任何按照您想要的方式排序JUnit测试的解决方案。。。您需要考虑该解决方案是否支持“跳过”功能,以便允许其他测试继续进行,即使其中一个测试失败。正如Gary在评论中所说: 如果Unit Runner能够 被告知继续,并命令他们 类名。嗯,也许我应该看看 进入源代码 我确实看了一下,但是没有任何提示可以对这些名称进行排序。我会建议更改JUnit插件,但我不认为有很多人在使用它,所以:DIY
如果你修改插件代码,我想看看解决方案。我也在为此搜索解决方案,我在下面的URL中发现了一种漏洞。我不知道它是否适用于您,但它在SpringToolSuite 2.5.2中适用于我
可以做的一件事是使用JUnit3.x的模式。我们使用了一个名为AllTests的测试套件,您可以按特定顺序将测试添加到该套件中。每一个包裹我们都有另外一个AllTests。给这些测试套件一个与包相同的名称,可以轻松地构建junit插件应该重视的层次结构 我真的不喜欢它在Junit查看器中呈现测试方法的方式。它应该与TestCase类中指定的顺序完全相同。我根据重要性和特点对这些方法进行排序。因此,最失败的方法是首先纠正错误,然后在测试用例的后面部分纠正更特殊的错误 这真的很烦人,测试运行者正在扰乱这些。我会亲自看一看,如果我找到了解决方案,我会更新这个答案 更新: 我在TestCase中方法名的排序问题与此有关: (谢谢你!) 因此,最终oracle更改了class.getMethods或class.getDeclaredMethods调用中方法的顺序。现在,这些方法是随机的,可以在JVM的不同运行之间更改。这可能与比较的优化有关,甚至是试图压缩方法名——谁知道呢 那么剩下什么呢。第一个可以使用:@FixMethodOrder(from):
package org.junit.runners.model;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import com.flirtbox.ioc.OrderTest;
/**
* @author Martin Kersten
*/
public class TestClassUtil {
public static class MyClassVisitor extends ClassVisitor {
private final List<String> names;
public MyClassVisitor(List<String> names) {
super(Opcodes.ASM4);
this.names = names;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
names.add(name);
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
private static List<String> getMethodNamesInCorrectOrder(Class<?> clazz) throws IOException {
InputStream in = OrderTest.class.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class");
ClassReader classReader=new ClassReader(in);
List<String> methodNames = new ArrayList<>();
classReader.accept(new MyClassVisitor(methodNames), 0);
return methodNames;
}
public static void sort(Class<?> fClass, List<FrameworkMethod> list) {
try {
final List<String> names = getMethodNamesInCorrectOrder(fClass);
Collections.sort(list, new Comparator<FrameworkMethod>() {
@Override
public int compare(FrameworkMethod methodA, FrameworkMethod methodB) {
int indexA = names.indexOf(methodA.getName());
int indexB = names.indexOf(methodB.getName());
if(indexA == -1)
indexA = names.size();
if(indexB == -1)
indexB = names.size();
return indexA - indexB;
}
});
} catch (IOException e) {
throw new RuntimeException("Could not optain the method names of " + fClass.getName() + " in correct order", e);
}
}
}
package org.junit.runners.model;
导入java.io.IOException;
导入java.io.InputStream;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.Comparator;
导入java.util.List;
导入org.objectweb.asm.ClassReader;
导入org.objectweb.asm.ClassVisitor;
导入org.objectweb.asm.MethodVisitor;
导入org.objectweb.asm.opcode;
导入com.box.ioc.OrderTest;
/**
*@作者Martin Kersten
*/
公共类TestClassUtil{
公共静态类MyClassVisitor扩展了ClassVisitor{
私人最终名单名称;
公共MyClassVisitor(列出名称){
超级(操作码ASM4);
this.names=名称;
}
@凌驾
public方法访问者访问方法(int访问、字符串名称、字符串描述、,
字符串签名,字符串[]异常){
名称。添加(名称);
返回super.visitMethod(访问、名称、描述、签名、异常);
}
}
私有静态列表GetMethodNamesIncorrector(类clazz)引发IOException{
InputStream in=OrderTest.class.getResourceAsStream(“/”+clazz.getName().replace(“.”,“/”)+“.class”);
ClassReader ClassReader=新的ClassReader(在中);
List methodNames=new ArrayList();
classReader.accep
public TestClass(Class<?> klass) {
fClass= klass;
if (klass != null && klass.getConstructors().length > 1)
throw new IllegalArgumentException(
"Test class can only have one constructor");
for (Class<?> eachClass : getSuperClasses(fClass))
for (Method eachMethod : eachClass.getDeclaredMethods())
addToAnnotationLists(new FrameworkMethod(eachMethod));
//New Part
for(List<FrameworkMethod> list : fMethodsForAnnotations.values()) {
TestClassUtil.sort(fClass, list);
}
//Remove once you have verified the class is really picked up
System.out.println("New TestClass for " + klass.getName());
}