Одна вещь, которую можно сделать, это использовать схему JUnit 3.x. Мы использовали набор тестов, который назывался AllTests, в который вы добавляете тесты в определенном порядке. И для каждого пакета мы получили еще один AllTests. Присвоение этим комплектам тестов имени, совпадающего с пакетом, позволяет легко построить иерархию, которая должна оцениваться плагином junit.
Мне действительно не нравится, как это даже представляет методы тестирования в средстве просмотра Junit. Он должен быть в том же порядке, в котором они указаны в классе TestCase. Я заказываю эти методы в порядке важности и возможностей. Таким образом, самый неудачный метод - сначала исправить, а затем более особенный в более поздней части тестового примера.
Это действительно раздражает, что бегун тестирует их. Я сам посмотрю на него и, если найду решение, обновлю этот ответ.
Обновление:
Моя проблема с упорядочением имен методов в TestCase связана с этой:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7023180 (Спасибо, Оракул!).
Таким образом, в конце оракул изменил порядок методов внутри вызова class.getMethods или class.getDeclaredMethods. Теперь методы являются случайными и могут меняться между различными запусками JVM. Кажется, это связано с оптимизацией сравнения или даже является попыткой сжать имя метода - кто знает ...
Так что же осталось. Сначала можно использовать: @FixMethodOrder (из javacodegeeks.com ):
- @ FixMethodOrder (MethodSorters.DEFAULT) - детерминированный порядок на основе внутреннего компаратора
- @ FixMethodOrder (MethodSorters.NAME_ASCENDING) - в порядке возрастания имен методов
- @ FixMethodOrder (MethodSorters.JVM) - до 4.11 способ зависимости от порядка на основе отражения
Это глупо, но объясняет, почему люди начинают использовать схему test1TestName.
Update2
Я использую ASM, поскольку Javassist также производит случайные отсортированные методы в getMethods (). Они используют Карты внутри. С ASM я просто использую Visitor.
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. Теперь скопируйте org.junit.runners.model.TestClass из библиотеки junit 4.5 в тот же пакет и измените его конструктор, добавив процедуру сортировки.
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 (target или bin). Поэтому, определяя один и тот же пакет и один и тот же класс, вы можете «переопределить» каждый класс / интерфейс в любой используемой вами библиотеке. Вот и весь трюк!
Update3
Я смог получить представление дерева каждого пакета и каждого класса в правильном порядке.
- Идея состоит в том, чтобы создать подкласс ParentRunner, а затем добавить в него все классы, которые вы определили как общедоступные и с методами, аннотированными с помощью test.
- Добавьте метод getName (), возвращающий только имя пакета класса, представляемого вашим исполнителем пакета (поэтому вы видите дерево как дерево пакетов без имени класса пакета).
- Проверьте подкаталоги, если вы найдете определенный класс комплекта (я использую AllTests для всех классов комплекта).
- Если вы не нашли класс комплекта в подкаталоге, проверьте все его подкаталоги, таким образом, вы не пропустите пакет, содержащий тесты, если родительский каталог не содержит комплект.
Вот и все. Класс набора, который я добавляю везде:
@RunWith(MySuiteRunner.class)
public class AllTests {
}
Вот и все. Это должно дать вам достаточно, чтобы начать и расширить этот. Бегунок комплекта использует только отражение, но я сортирую тестовые классы и наборы подкаталогов в алфавитном порядке, а наборы подкаталогов (которые представляют собой пакеты, в которых они находятся) отсортированы наиболее эффективно.