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

Я в основном хочу запустить все JUnit блок тесты в моем проекте IntelliJ IDEA (исключая тесты интеграции JUnit), используя метод static suite () JUnit. Зачем использовать метод static suite ()? Потому что я могу использовать JUnit test runner 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, чтобы я мог использовать интегрированный тестовый бегун - мне нравится зеленая полоса:)

5 ответов


Я написал код, чтобы выполнить большую часть работы. Это работает только если ваши файлы находятся на локальном диске, а не в банке. Все, что вам нужно, это один класс в пакете. Для этой цели можно создать локатор.класс 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 {}

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

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

С уважением, Тимо Мейнен!--2-->


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 и вы помещаете файл в самый верхний пакет (так что**/*.класс search будет иметь возможность забрать все ваши тесты)