2010-03-09 12 views
11

Da Eclipse I può facilmente eseguire tutti i test JUnit nella mia applicazione.Come si eseguono a livello di programmazione tutti i test JUnit nella mia applicazione Java?

Vorrei essere in grado di eseguire i test sui sistemi di destinazione dal barattolo applicazione, senza Eclipse (o formica o Maven o qualsiasi altro strumento di sviluppo).

posso vedere come eseguire un test specifico o suite dalla riga di comando.

Potrei creare manualmente una suite che elenca tutti i test nella mia applicazione, ma sembra essere soggetta a errori - sono sicuro che a un certo punto creerò un test e dimenticherò di aggiungerlo alla suite.

L'Eclipse JUnit plugin ha una procedura guidata per creare una suite di test, ma per qualche motivo non "vede" i miei classi di test. Potrebbe essere alla ricerca di test JUnit 3, non di test annotati con JUnit 4.

Potrei scrivere uno strumento che creerebbe automaticamente la suite attraverso la scansione dei file di origine.

Oppure potrei scrivere codice in modo che l'applicazione esegua la scansione del proprio file jar per i test (sia mediante denominazione convenzione o cercando l'annotazione @Test).

sembra che ci dovrebbe essere un modo più semplice. Cosa mi manca?

risposta

4

Ho avuto un piccolo problema con la mia ultima soluzione. Se ho eseguito "tutti i test" da Eclipse, sono stati eseguiti due volte perché hanno eseguito i singoli test E la suite. Avrei potuto lavorato in tutto questo, ma poi ho capito che c'era una soluzione più semplice:

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

} 
+4

Perché non modificare il tuo vecchio post quindi, la risposta multipla è solo confusa? – for3st

1

con Classe JUnitCore

JUnitCore è una facciata per l'esecuzione di test. Supporta l'esecuzione di test JUnit 4, test JUnit 3.8.xe miscele. Per eseguire test dalla riga di comando, eseguire java org.junit.runner.JUnitCore TestClass1 TestClass2 .... Per le prove con test singolo, utilizzare il metodo statico runClasses (Classe []). Se si desidera aggiungere listener speciali, creare prima un'istanza di JUnitCore e utilizzarla per eseguire i test.

+0

che non risolve il mio problema. Come ho detto, so come eseguire specifiche classi di test dalla riga di comando. Ma quello che voglio è eseguire TUTTI i test nella mia applicazione, senza elencarne esplicitamente ciascuno. –

1

non ho ancora provato questo come di, ma sono imbattuto in questo blog di recente: http://burtbeckwith.com/blog/?p=52

l'autore fornisce una classe che scopre tutte le junits e li esegue, quindi se si SLOT questo al vostro progetto, può fornire la capacità richiesta?

Spero che questo aiuti.

+0

Avevo scoperto quel post prima. Il problema è che analizza i file sorgente. Sui miei sistemi di destinazione non ho la fonte. Tuttavia, potrei essere in grado di adattare la sua soluzione per eseguire la scansione del file jar. –

4

Basato su http://burtbeckwith.com/blog/?p=52 Mi è venuto in mente quanto segue. Sembra che funzioni bene.

posso eseguo da dentro il mio codice con:

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

Un punto debole è che si basa su una convenzione di denominazione (suffisso "Test") per identificare le prove. Un altro punto debole è che il nome del file jar è hardcoded.

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

} 
+0

Potreste forse spiegare perché usate la verifica per isAbstract, e non altre opzioni come isInterface? I genitori astratti vengono caricati automaticamente quando i bambini vengono usati per la prima volta? – Hamy

6

Secondo a recent thread sulla mailing list JUnit, ClasspathSuite può raccogliere ed eseguire tutti i test JUnit sul classpath.Non è esattamente quello che vuoi, dal momento che si tratta di un'annotazione a livello di classe, ma l'origine è disponibile, quindi potresti essere in grado di estendere il suo meccanismo di scoperta interna.

+0

Grazie, sembra che farebbe quello che voglio, ma probabilmente rimarrò con la mia soluzione perché è più semplice. –

0

È inoltre possibile utilizzare ANT che ha un'attività incorporata. Scrivi lo script ANT ed eseguilo sul computer di destinazione. ANT potrebbe creare report come risultato.

+0

Sì, ma non voglio installare questo tipo di strumento sul sistema di destinazione. (Come ho detto nella mia domanda iniziale). –

1

ottenere il progetto Java e passare il progetto

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