Come posso eseguire tutti i test unitari di JUnit tranne quelli che terminano con & # 8220; IntegrationTest & # 8221; nel mio progetto IntelliJ IDEA utilizzando il test runner integrato?

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

Domanda

Fondamentalmente voglio eseguire tutti i test JUnit unit nel mio progetto IntelliJ IDEA (esclusi i test di integrazione JUnit), utilizzando il metodo suite statica () di JUnit. Perché usare il metodo suite statica ()? Perché posso quindi utilizzare il test runner JUnit di IntelliJ IDEA per eseguire tutti i test unitari nella mia applicazione (ed escludere facilmente tutti i test di integrazione in base alla convenzione di denominazione). Il codice finora appare così:

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

}

Il metodo getUnitTestClasses () deve essere riscritto per aggiungere tutte le classi di progetto che estendono TestCase, tranne se il nome della classe termina in " IntegrationTest " ;.

So che posso farlo facilmente in Maven, ad esempio, ma devo farlo in IntelliJ IDEA in modo da poter usare il test runner integrato - mi piace la barra verde :)

È stato utile?

Soluzione

Ho scritto del codice per svolgere gran parte del lavoro. Funziona solo se i tuoi file si trovano sul disco locale anziché in un JAR. Tutto ciò che serve è una classe nel pacchetto. A tal fine, è possibile creare una classe Locator.java, solo per trovare il pacchetto.

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

Altri suggerimenti

Che ne dici di mettere ogni gruppo principale di test junit nel loro pacchetto root. Uso questa struttura di pacchetti nel mio progetto:

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

Senza alcuna codifica, è possibile configurare IntelliJ per eseguire tutti i test, solo quelli veloci o solo quelli lenti.

Che ne dici di usare JUnit4 e Suite-Runner?

Esempio:

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

Ho creato un piccolo script shell per trovare tutti i test unitari e un altro per trovare i test integrativi. Dai un'occhiata al mio blog: http://blog.timomeinen.de/ 2010/02 / find-all-JUnit-test-in-a-progetto /

Se si utilizza Spring TestContext è possibile utilizzare l'annotazione @IfProfile per dichiarare diversi test.

Cordiali saluti, Timo Meinen

Spring ha implementato un'eccellente funzione di ricerca del percorso di classe in PathMatchingResourcePatternResolver. Se si utilizza il prefisso classpath *: è possibile trovare tutte le risorse, comprese le classi in una determinata gerarchia, e filtrarle anche se lo si desidera. Quindi puoi utilizzare i figli di AbstractTypeHierarchyTraversingFilter, AnnotationTypeFilter e AssignableTypeFilter per filtrare tali risorse sulle annotazioni a livello di classe o sulle interfacce che implementano.

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

Soluzione: https://github.com/MichaelTamm/junit-toolbox
Utilizza le seguenti funzionalità

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

supponendo che tu segua un modello di denominazione in cui i test di integrazione finiscono in ... IntegrationTest e inserisci il file nel pacchetto più in alto (quindi la ricerca di classe ** / * avrà l'opportunità di raccogliere tutti i tuoi test )

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top