2010-02-05 14 views
13

Diciamo che ho una classe test chiamato testFixtureA con diversi metodi testA, testB, testC, ecc, ognuno con @Test annotazione.jUnit ignorare i metodi @Test dalla classe base

Diciamo ora che sottoclassi testFixtureA nella classe testFixtureAB e non sovrascrivo nulla. testFixtureAB è vuoto per ora.

Quando lancio test da testFixtureAB, metodi testA, testB e testC vengono eseguite mediante test corridore perché prova corridore non distingue tra i metodi di prova dalla classe e baseclass.

Come posso forzare il corridore di prova a tralasciare i test dalla baseclass?

risposta

20

ristrutturare i vostri classi di test.

  • Se non si desidera utilizzare i test dalla baseclass, allora non estenderlo
  • Se avete bisogno di altre funzionalità dalla classe base, dividere la classe in due - i test, e la altre funzionalità
+0

Questo non è utile per il motivo che @martosoler indica nella risposta qui sotto - ci sono casi ovvi (nella mia situazione, test di selenio contro diversi browser) dove questo è un consiglio molto cattivo. Tu vuoi * lo stesso comportamento a volte; solo la configurazione delle variabili "SUT" si differenzia tra le sottoclassi. –

+1

@ MikeBurton - In realtà, questo è un buon consiglio, anche se potrebbe non essere ovvio ciò che suggerisce Bozho. Quello che devi fare è * refactor * la tua classe base, estraendo il codice che dovrebbe essere riutilizzato in una nuova, (astratta) classe proto-base. La tua nuova classe di test estenderebbe quindi la classe proto-base piuttosto che quella che chiamavamo la classe base. Questo sarebbe un buon esempio di seguire l'LSP e la regola generale che non dovresti mai ignorare le implementazioni concrete. Se non ti dispiace rompere queste regole, puoi seguire la mia raccomandazione qui sotto. –

+0

In realtà non so perché mi sono opposto a questo a luglio. Questa è esattamente la soluzione alla quale sono arrivato alla fine. Anche se a questo punto sembra che ci sia una soluzione AOP che risolverà meglio il mio problema specifico. Non sono abbastanza ambizioso da risolverlo al momento, comunque. –

9

ignorando tutta la classe di base:

@Ignore 
class BaseClass { 
    // ... 
} 

check out this example

+3

Questo ignorerà la classe base ovunque, rendendo praticamente inutile. – whiskeysierra

+5

i metodi di test ereditati verranno eseguiti come test nelle classi derivate ... – dfa

+1

Rendi astratta la classe base? – user7610

1

Nell'ultima JUnit è possibile utilizzare l'annotazione @Rule sulla sottoclasse per ispezionare il nome del test e intercettare l'esecuzione di test per ignorare il test in modo dinamico. Ma suggerirei che l'idea di @ Bozho sia la migliore: il fatto che sia necessario farlo indica un problema più grande che probabilmente mostra che l'ereditarietà non è la soluzione giusta qui.

22

e non sovrascrivo nulla. testFixtureAB è vuoto per ora

C'è una tua risposta. Se si desidera non eseguire TestB dalla classe principale, overrride esso:

public class testFixtureAB extends testFixtureA { 
    @Override 
    public void testB() {} 
} 
+1

Soluzione semplice ed evidente +1 – whiskeysierra

+1

per chiarire per gli altri poiché non ho capito questa risposta quando l'ho vista per la prima volta, diciamo che hai metodo 'testB' in classe base annotato con @Test, e non vuoi' testB 'test per eseguire nella sottoclasse, quindi passare alla sottoclasse, sovrascrivere questo metodo' testB', quindi questo test non verrà più eseguito nella sottoclasse –

1

Lo so, non è la risposta ...

consideri la ragione per la quale si estende classi di test concreti. In questo modo si duplicano i metodi di test.

Se si condivide il codice tra i test, prendere in considerazione la scrittura di classi di test di base con helper and fixture setup methods o test helper class.

Se per eseguire i test, provare a organizzare i test con suite e categories.

1

E se si desidera eseguire lo stesso test per diverse configurazioni della stessa suite di test?

Ad esempio, supponiamo di avere una Classe A con i metodi test1, test2 e test3 che colpiscono un database incorporato, quindi si desidera creare "setUp" e "tearDown" separati per ogni fornitore incorporato (H2, HyperSQL, ecc.) Ma esegue lo stesso test per ciascuno di essi.

Vorrei estendere una classe che contenga quei metodi di prova e configurarla in una sottoclasse. Il mio problema è che la super classe NON DEVE essere considerata idonea per il corridore di prova. Il problema sorge quando il test runner esegue la classe di super e dato che non ha trovato i metodi di impostazione e teardown corrispondenti, si scontri :(

6

E 'abbastanza facile da raggiungere attuare alcune poche classi:

  • Crea il proprio TestRunner
  • creare un'annotazione come @IgnoreInheritedTests
  • Creare una classe che estende org.junit.runner.manipulation.Filter

sulla classe del filtro:

public class InheritedTestsFilter extends Filter { 

    @Override 
    public boolean shouldRun(Description description) { 
     Class<?> clazz = description.getTestClass(); 
     String methodName = description.getMethodName(); 
     if (clazz.isAnnotationPresent(IgnoreInheritedTests.class)) { 
      try { 
       return clazz.getDeclaredMethod(methodName) != null; 
      } catch (Exception e) { 
       return false; 
      } 
     } 
     return true; 
    } 

    @Override 
    public String describe() { 
     // TODO Auto-generated method stub 
     return null; 
    } 

} 

sul corridore personalizzato:

/** 
* @param klass 
* @throws InitializationError 
* @since 
*/ 
public CustomBaseRunner(Class<?> klass) throws InitializationError { 
    super(klass); 
    try { 
     this.filter(new InheritedTestsFilter()); 
    } catch (NoTestsRemainException e) { 
     throw new IllegalStateException("class should contain at least one runnable test", e); 
    } 
} 
0

nella classe di test di base metodi @Test:

assumeTrue(getClass().equals(BaseClassTest.class)); 

ignorerà quelli nelle prove sottoclasse ma non lasciarli completamente fuori.

Problemi correlati