在 Eclipse 中,JUnit 视图似乎会随机排序测试用例。如何按类名排序呢?
正如Gary在评论中所说:
如果Unit Runner可以按类名排序,那就太好了。嗯,也许我应该查看源代码...
我确实查看了,但没有发现任何有关对这些名称进行排序的功能。我建议向JUnit插件提出更改请求,但我认为使用这个插件的人不多,因此:自己动手吧。
如果您修改插件代码,我想看到解决方案。
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);
}
}
}
将这个文件放在src/test/java文件夹中的org.junit.runners.model包中。现在将junit 4.5库的org.junit.runners.model.TestClass复制到同一个包中,并通过添加排序程序来修改其构造函数。
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());
}
现在,您已经按照Java文件中声明的顺序精心排序了方法。如果您想知道类路径通常是这样设置的,即src(目标或bin)文件夹中的所有内容首先由类加载器考虑。因此,在定义完全相同的包和相同的类时,您可以“覆盖”您使用的任何库中的每个类/接口。这就是诀窍!
更新3 我能够获得每个包和每个类的树形视图,以正确的顺序。
就是这样。我随处添加的套件类是:
@RunWith(MySuiteRunner.class)
public class AllTests {
}
就是这样。这应该可以给你足够的内容来开始并扩展它。测试套件运行器仅使用反射,但我按子目录中的测试类和套件按字母顺序排序,并将子目录(代表它们所在的包)的套件排序到最上面。
Mark写道:
它根据执行时间对它们进行排序, 或许你应该对你的方法进行排序? 源/排序成员
Mark是正确的。但是你不能对单元测试进行排序。不允许猜测执行顺序。
单元测试必须独立构建,调用顺序是随机的。
在大多数情况下,测试方法按字母顺序排序。类是随机的。尝试使用TestSuite来对你的测试进行排序。
按执行顺序排序的结果为:按执行时间对测试结果进行排序
JUnit视图现在提供了按执行时间对结果进行排序的功能。
默认情况下,结果将按执行顺序排序。
从JUnit视图菜单中选择Sort By > Execution Time
将在所有测试完成后重新排序结果。当测试仍在运行时,它们将按执行顺序显示。
import jexample.Depends;
@Test
@Depends("#testEmpty")
public Stack<Integer> testPush(Stack<Integer> $) {
$.push(42);
assertFalse($.isEmpty());
return $;
}
@Before
@After
)来正确设置事物。我也在寻找解决方案,我从下面的 URL 中找到了一种方法。不知道这是否适用于您,但在 Spring Tool Suite 2.5.2 中对我有效。