¿Cómo puedo ejecutar todas las pruebas unitarias de JUnit excepto las que terminan en & # 8220; IntegrationTest & # 8221; en mi proyecto IntelliJ IDEA usando el corredor de prueba integrado?

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

Pregunta

Básicamente, quiero ejecutar todas las pruebas JUnit unit en mi proyecto IntelliJ IDEA (excluyendo las pruebas de integración JUnit), usando el método static suite () de JUnit. ¿Por qué usar el método estático suite ()? Porque luego puedo usar el corredor de pruebas JUnit de IntelliJ IDEA para ejecutar todas las pruebas unitarias en mi aplicación (y excluir fácilmente todas las pruebas de integración por la convención de nomenclatura). El código hasta ahora se parece a esto:

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;
    }

}

El método getUnitTestClasses () se debe volver a escribir para agregar todas las clases de proyecto extendiendo TestCase, excepto si el nombre de la clase termina en " IntegrationTest " ;.

Sé que puedo hacer esto fácilmente en Maven, por ejemplo, pero necesito hacerlo en IntelliJ IDEA para poder usar el corredor de prueba integrado. Me gusta la barra verde :)

¿Fue útil?

Solución

He escrito un código para hacer la mayor parte del trabajo. Solo funciona si sus archivos están en el disco local en lugar de en un JAR. Todo lo que necesitas es una clase en el paquete. Para este fin, podría crear una clase Locator.java, solo para poder encontrar el paquete.

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;
    }
}

Otros consejos

¿Qué hay de poner cada grupo principal de pruebas junit en su propio paquete raíz? Utilizo esta estructura de paquete en mi proyecto:

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

Sin ningún tipo de codificación, puedes configurar IntelliJ para ejecutar todas las pruebas, solo las rápidas o las lentas.

¿Qué hay de usar JUnit4 y Suite-Runner?

Ejemplo:

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

Hice un pequeño Shell-Script para encontrar todas las Pruebas Unitarias y otro para encontrar mis Pruebas de Integración. Echa un vistazo a mi entrada de blog: http://blog.timomeinen.de/ 2010/02 / find-all-junit-tests-in-a-project /

Si usa Spring TestContext, puede usar la anotación @IfProfile para declarar diferentes pruebas.

Saludos cordiales, Timo Meinen

Spring ha implementado una excelente función de búsqueda classpath en PathMatchingResourcePatternResolver. Si usa el prefijo classpath *:, puede encontrar todos los recursos, incluidas las clases en una jerarquía determinada, e incluso filtrarlos si lo desea. Luego puede usar los hijos de AbstractTypeHierarchyTraversingFilter, AnnotationTypeFilter y AssignableTypeFilter para filtrar esos recursos en anotaciones de nivel de clase o en las interfaces que implementan.

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

Solución: https://github.com/MichaelTamm/junit-toolbox
Usa las siguientes características

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

Suponiendo que sigue un patrón de nomenclatura en el que las pruebas de integración terminan en ... Prueba de integración y coloca el archivo en el paquete más alto (de modo que la búsqueda de clases ** / *. tendrá la oportunidad de seleccionar todas sus pruebas )

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top