Как я могу запустить все модульные тесты JUnit, кроме тех, которые заканчиваются на "IntegrationTest" в моем проекте IntelliJ IDEA, используя интегрированный тестовый бегун?
В основном я хочу запускать все тесты JUnit unit в проекте IntelliJ IDEA (исключая тесты интеграции JUnit), используя метод static suite() для JUnit. Зачем использовать метод static suite()? Поскольку я могу использовать IntelliJ IDEA JUnit для запуска всех модульных тестов в моем приложении (и легко исключить все интеграционные тесты по соглашению об именах). Код выглядит так:
package com.acme;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class AllUnitTests extends TestCase {
public static Test suite() {
List classes = getUnitTestClasses();
return createTestSuite(classes);
}
private static List getUnitTestClasses() {
List classes = new ArrayList();
classes.add(CalculatorTest.class);
return classes;
}
private static TestSuite createTestSuite(List allClasses) {
TestSuite suite = new TestSuite("All Unit Tests");
for (Iterator i = allClasses.iterator(); i.hasNext();) {
suite.addTestSuite((Class<? extends TestCase>) i.next());
}
return suite;
}
}
Метод getUnitTestClasses() должен быть перезаписан, чтобы добавить все классы проекта, расширяющие TestCase, за исключением случаев, когда имя класса заканчивается в "IntegrationTest".
Я знаю, что могу сделать это легко в Maven, например, но мне нужно сделать это в IntelliJ IDEA, чтобы я мог использовать интегрированный тестовый бегун - мне нравится зеленый бар:)
Ответы
Ответ 1
Я написал некоторый код, чтобы выполнить большую часть работы. Он работает только в том случае, если ваши файлы находятся на локальном диске, а не в JAR. Все, что вам нужно, это один класс в пакете. С этой целью вы можете создать класс Locator.java, чтобы иметь возможность найти пакет.
public class ClassEnumerator {
public static void main(String[] args) throws ClassNotFoundException {
List<Class<?>> list = listClassesInSamePackage(Locator.class, true);
System.out.println(list);
}
private static List<Class<?>> listClassesInSamePackage(Class<?> locator, boolean includeLocator)
throws ClassNotFoundException {
File packageFile = getPackageFile(locator);
String ignore = includeLocator ? null : locator.getSimpleName() + ".class";
return toClassList(locator.getPackage().getName(), listClassNames(packageFile, ignore));
}
private static File getPackageFile(Class<?> locator) {
URL url = locator.getClassLoader().getResource(locator.getName().replace(".", "/") + ".class");
if (url == null) {
throw new RuntimeException("Cannot locate " + Locator.class.getName());
}
try {
return new File(url.toURI()).getParentFile();
}
catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
private static String[] listClassNames(File packageFile, final String ignore) {
return packageFile.list(new FilenameFilter(){
@Override
public boolean accept(File dir, String name) {
if (name.equals(ignore)) {
return false;
}
return name.endsWith(".class");
}
});
}
private static List<Class<?>> toClassList(String packageName, String[] classNames)
throws ClassNotFoundException {
List<Class<?>> result = new ArrayList<Class<?>>(classNames.length);
for (String className : classNames) {
// Strip the .class
String simpleName = className.substring(0, className.length() - 6);
result.add(Class.forName(packageName + "." + simpleName));
}
return result;
}
}
Ответ 2
Как разместить каждую основную группу тестов junit в своем собственном корневом пакете. Я использую эту структуру пакета в своем проекте:
test.
quick.
com.acme
slow.
com.acme
Без кодирования вы можете настроить IntelliJ для запуска всех тестов, просто быстрых или просто медленных.
Ответ 3
Как насчет использования JUnit4 и Suite-Runner?
Пример:
@RunWith(Suite.class)
@Suite.SuiteClasses({
UserUnitTest.class,
AnotherUnitTest.class
})
public class UnitTestSuite {}
Я сделал небольшую оболочку Script, чтобы найти все Unit-Tests и еще один, чтобы найти тесты Integration-Tests. Взгляните на мою запись в блоге:
http://blog.timomeinen.de/2010/02/find-all-junit-tests-in-a-project/
Если вы используете Spring TestContext, вы можете использовать @IfProfile Annotation для объявления различных тестов.
С уважением,
Тимо Мейнен
Ответ 4
Spring реализовала отличную функцию поиска класса в PathMatchingResourcePatternResolver. Если вы используете префикс classpath *: вы можете найти все ресурсы, включая классы в заданной иерархии, и даже фильтровать их, если хотите. Затем вы можете использовать дочерние объекты AbstractTypeHierarchyTraversingFilter, AnnotationTypeFilter и AssignableTypeFilter для фильтрации этих ресурсов либо на аннотациях уровня классов, либо на интерфейсах, которые они реализуют.
http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/core/io/support/PathMatchingResourcePatternResolver.html
http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/core/type/filter/AbstractTypeHierarchyTraversingFilter.html
Ответ 5
Решение: https://github.com/MichaelTamm/junit-toolbox
Используйте следующие функции.
@RunWith(WildcardPatternSuite.class)
@SuiteClasses({"**/*.class", "!**/*IntegrationTest.class"})
public class AllTestsExceptionIntegrationSuit {
}
предполагая, что вы следуете шаблону именования, в котором завершаются интеграционные тесты... IntegrationTest, и вы помещаете файл в самый верхний пакет (так что поиск классов **/*. будет иметь возможность забрать все ваши тесты )