Comment puis-je exécuter tous les tests unitaires JUnit à l'exception de ceux se terminant par «IntegrationTest» dans mon projet IntelliJ IDEA à l'aide du programme d'exécution de test intégré?

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

Question

En gros, je souhaite exécuter tous les tests JUnit unit dans mon projet IntelliJ IDEA (à l'exception des tests d'intégration JUnit), à l'aide de la méthode static suite () de JUnit. Pourquoi utiliser la méthode statique suite ()? Parce que je peux ensuite utiliser le lanceur de tests JUnit d’IntelliJ IDEA pour exécuter tous les tests unitaires de mon application (et exclure facilement tous les tests d’intégration grâce à une convention de dénomination). Le code à ce jour ressemble à ceci:

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

}

La méthode getUnitTestClasses () doit être réécrite pour ajouter toutes les classes de projet étendant TestCase, sauf si le nom de la classe se termine par "IntegrationTest".

Je sais que je peux le faire facilement dans Maven par exemple, mais je dois le faire dans IntelliJ IDEA pour pouvoir utiliser le programme de test intégré - j'aime la barre verte:)

Était-ce utile?

La solution

J'ai écrit du code pour faire la plupart du travail. Cela ne fonctionne que si vos fichiers sont sur le disque local plutôt que dans un fichier JAR. Tout ce dont vous avez besoin est d’une classe dans le package. Vous pouvez, à cette fin, créer une classe Locator.java uniquement pour pouvoir trouver le package.

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

Autres conseils

Pourquoi ne pas inclure chaque groupe principal de tests Junit dans leur propre paquet racine. J'utilise cette structure de package dans mon projet:

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

Sans codage, vous pouvez configurer IntelliJ pour exécuter tous les tests, juste les plus rapides ou les plus lents.

Qu'en est-il de l'utilisation de JUnit4 et de Suite-Runner?

Exemple:

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

J'ai créé un petit script shell pour trouver tous les tests unitaires et un autre pour trouver mes tests d'intégration. Regardez mon entrée de blog: http://blog.timomeinen.de/ 2010/02 / test-dans-un-projet-find-all-junit /

Si vous utilisez Spring TestContext, vous pouvez utiliser l'annotation @IfProfile pour déclarer différents tests.

Cordialement, Timo Meinen

Spring a implémenté une excellente fonction de recherche de chemin d'accès aux classes dans PathMatchingResourcePatternResolver. Si vous utilisez le préfixe classpath *:, vous pouvez trouver toutes les ressources, y compris les classes d'une hiérarchie donnée, et même les filtrer si vous le souhaitez. Vous pouvez ensuite utiliser les enfants de AbstractTypeHierarchyTraversingFilter, AnnotationTypeFilter et AssignableTypeFilter pour filtrer ces ressources soit sur des annotations de niveau classe, soit sur des interfaces qu’elles implémentent.

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

Solution: https://github.com/MichaelTamm/junit-toolbox
Utilisez les fonctionnalités suivantes

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

en supposant que vous suiviez un modèle de dénomination dans lequel vos tests d'intégration se terminent par ... IntegrationTest et que vous placez le fichier dans le paquet le plus élevé (de sorte que la recherche ** / *. class aura la possibilité de récupérer tous vos tests). )

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top