2008-10-07 1 views
12

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

+0

С тегами, что и Java, так что больше людей увидят его (не знаю, действительно ли он специфичен для Java, но он использует Java). – 2008-10-07 03:25:23

+0

В качестве побочного примечания: рассмотрите возможность использования для каждого. Ваш for-loop будет выглядеть так: for (Класс testClass: allClasses) {suite.addTestSuite (testClass); } – crunchdog 2009-08-30 12:06:34

ответ

7

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

С некоторыми изменениями, в основном, чтобы сделать это рекурсивным, это сработало хорошо для меня. Благодаря! – thvo 2008-10-09 22:58:34

8

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

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

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

5

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

Пример:

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

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

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

С наилучшими пожеланиями, Timo Meinen

0

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

0

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

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

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

Смежные вопросы