Como faço para programaticamente executar todos os testes JUnit no meu aplicativo Java?

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

  •  18-09-2019
  •  | 
  •  

Pergunta

De Eclipse eu posso facilmente executar todos os testes JUnit no meu aplicativo.

Eu gostaria de ser capaz de executar os testes em sistemas de destino do frasco aplicação, sem Eclipse (ou Ant ou Maven ou qualquer outra ferramenta de desenvolvimento).

Eu posso ver como executar um teste específico ou conjunto a partir da linha de comando.

Eu poderia criar manualmente um conjunto listando todos os testes na minha candidatura, mas que parece propenso a erros -. Tenho certeza de que em algum momento eu vou criar um teste e se esqueça de adicioná-lo para a suíte

O plugin Eclipse JUnit tem um assistente para criar um conjunto de testes, mas por alguma razão ele não "ver" as minhas classes de teste. Ele pode estar procurando JUnit 3 testes, não JUnit 4 testes anotados.

Eu poderia escrever uma ferramenta que iria criar automaticamente o pacote, verificando os arquivos de origem.

Ou eu poderia escrever código para a aplicação faria a varredura é próprio arquivo jar para testes (seja por convenção de nomenclatura ou olhando para a anotação @Test).

Parece que deve haver uma maneira mais fácil. O que eu estou ausente?

Foi útil?

Solução 2

Eu corri para um problema menor com a minha última solução. Se eu corri "todos os testes" de Eclipse eles correram duas vezes, porque eles correram os testes individuais ea suite. Eu poderia ter trabalhado em torno disso, mas então eu percebi que havia uma solução mais simples:

package suneido;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class RunAllTests {

    public static void run(String jarfile) {
        String[] tests = findTests(jarfile);
        org.junit.runner.JUnitCore.main(tests);
    }

    private static String[] findTests(String jarfile) {
        ArrayList<String> tests = new ArrayList<String>();
        try {
            JarFile jf = new JarFile(jarfile);
            for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements();) {
                String name = e.nextElement().getName();
                if (name.startsWith("suneido/") && name.endsWith("Test.class")
                        && !name.contains("$"))
                    tests.add(name.replaceAll("/", ".")
                            .substring(0, name.length() - 6));
            }
            jf.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return tests.toArray(new String[0]);
    }

    public static void main(String[] args) {
        run("jsuneido.jar");
    }

}

Outras dicas

De acordo com a uma recente fio na lista JUnit de discussão, ClasspathSuite pode coletar e executar todos os testes JUnit no classpath. Não é exatamente o que você quer, uma vez que é uma anotação em nível de classe, mas a fonte está disponível, assim você pode ser capaz de estender seu mecanismo de descoberta interno.

Com base http://burtbeckwith.com/blog/?p=52 Eu vim com o seguinte. Isso parece funcionar bem.

Eu posso executá-lo de dentro do meu código com:

org.junit.runner.JUnitCore.main("suneido.AllTestsSuite");

Um ponto fraco é que ele se baseia em uma convenção de nomenclatura (sufixo "Test") para identificar testes. Outro ponto fraco é que o nome do arquivo jar é codificado.

package suneido;

import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;

/**
 * Discovers all JUnit tests in a jar file and runs them in a suite.
 */
@RunWith(AllTestsSuite.AllTestsRunner.class)
public final class AllTestsSuite {
    private final static String JARFILE = "jsuneido.jar";

    private AllTestsSuite() {
    }

    public static class AllTestsRunner extends Suite {

        public AllTestsRunner(final Class<?> clazz) throws InitializationError {
            super(clazz, findClasses());
        }

        private static Class<?>[] findClasses() {
            List<String> classFiles = new ArrayList<String>();
            findClasses(classFiles);
            List<Class<?>> classes = convertToClasses(classFiles);
            return classes.toArray(new Class[classes.size()]);
        }

        private static void findClasses(final List<String> classFiles) {
            JarFile jf;
            try {
                jf = new JarFile(JARFILE);
                for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements();) {
                    String name = e.nextElement().getName();
                    if (name.startsWith("suneido/") && name.endsWith("Test.class")
                            && !name.contains("$"))
                        classFiles.add(name.replaceAll("/", ".")
                                .substring(0, name.length() - 6));
                }
                jf.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        private static List<Class<?>> convertToClasses(
                final List<String> classFiles) {
            List<Class<?>> classes = new ArrayList<Class<?>>();
            for (String name : classFiles) {
                Class<?> c;
                try {
                    c = Class.forName(name);
                }
                catch (ClassNotFoundException e) {
                    throw new AssertionError(e);
                }
                if (!Modifier.isAbstract(c.getModifiers())) {
                    classes.add(c);
                }
            }
            return classes;
        }
    }

}

Eu não tentei isso como ainda, mas me deparei com este blog recentemente: http: // burtbeckwith.com/blog/?p=52

O autor fornece uma classe que descobre todos os seus junits e os executa, então se você encaixar isso em seu projeto pode proporcionar a capacidade necessária?

Espero que isso ajude.

Obter o projeto Java e passar o projeto

JUnitLaunchShortcut jUnitLaunchShortcut = new JUnitLaunchShortcut();
jUnitLaunchShortcut.launch("Pass the Java Project containing JUnits Classes", "run");

Você também pode usar ANT , que foi construído com tarefa. Escrever um script ANT e executá-lo em máquina de destino. ANT poderia criar relatório como resultado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top