Как я могу запустить все модульные тесты JUnit, кроме тех, которые заканчиваются на “IntegrationTest” в моем проекте IntelliJ IDEA, используя интегрированный тестовый модуль?

StackOverflow https://stackoverflow.com/questions/176913

Вопрос

Я в принципе хочу запустить все JUnit единица измерения тесты в моем проекте IntelliJ IDEA (исключая интеграционные тесты JUnit), использующие метод static suite() JUnit.Зачем использовать метод static suite()?Потому что затем я могу использовать тестовый модуль JUnit от IntelliJ IDEA для запуска всех модульных тестов в моем приложении (и легко исключить все интеграционные тесты с помощью соглашения об именовании).Код пока выглядит примерно так:

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, чтобы я мог использовать встроенный тестовый раннер - мне нравится зеленая полоса :)

Это было полезно?

Решение

Я написал некоторый код для выполнения большей части работы. Это работает, только если ваши файлы находятся на локальном диске, а не в 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;
    }
}

Другие советы

Как насчет размещения каждой основной группы тестов junit в их собственный корневой пакет? Я использую эту структуру пакета в моем проекте:

test.
  quick.
    com.acme
  slow.
    com.acme

Без какого-либо кодирования вы можете настроить IntelliJ для запуска всех тестов, только быстрых или только медленных.

Как насчет использования JUnit4 и Suite-Runner?

Пример:

@RunWith(Suite.class)
@Suite.SuiteClasses({
UserUnitTest.class,
AnotherUnitTest.class
})
public class UnitTestSuite {}

Я создал небольшой Shell-скрипт для поиска всех модульных тестов и еще один для поиска моих интеграционных тестов.Взгляните на запись в моем блоге:http://blog.timomeinen.de/2010/02/find-all-junit-tests-in-a-project/

Если вы используете Spring TestContext, вы можете использовать аннотацию @IfProfile для объявления различных тестов.

Kind regards, Timo Meinen

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

Решение: https://github.com/MichaelTamm/junit-toolbox
Используйте следующие функции

@RunWith(WildcardPatternSuite.class)
@SuiteClasses({"**/*.class", "!**/*IntegrationTest.class"})
public class AllTestsExceptionIntegrationSuit {
}

при условии, что вы следуете шаблону именования, где интеграционные тесты заканчиваются ... IntegrationTest и вы помещаете файл в самый верхний пакет (так что поиск по классу ** / *. будет иметь возможность забрать все ваши тесты )

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top