2012-01-27 18 views
6

Sto utilizzando JUnit 4.10 per l'esecuzione di test suite e ho implementato una regola "riprova tentativo fallito" seguendo le fantastiche note di Matthew Farwell nel post How to Re-run failed JUnit tests immediately?. Ho creato una classe "RetryTestRule" con il seguente codice:Come applicare una JUnit @Rule per tutti i casi di test in una suite

public class RetryTestRule implements TestRule { 

    private final int retryCount; 

    public RetryTestRule(int retryCount) { 
    this.retryCount = retryCount; 
    } 

    @Override 
    public Statement apply(Statement base, Description description) { 
    return statement(base, description); 
    } 

    private Statement statement(final Statement base, final Description description) { 
    return new Statement() { 
     @Override 
     public void evaluate() throws Throwable { 
     Throwable caughtThrowable = null; 

     // retry logic 
     for (int i = 0; i < retryCount; i++) { 
      try { 
      base.evaluate(); 
      return; 
      } catch (Throwable t) { 
      caughtThrowable = t; 
      System.err.println(description.getDisplayName() + ": run " + (i + 1) + "  failed"); 
      } 
     } 
     System.err.println(description.getDisplayName() + ": Giving up after " + retryCount 
      + " failures"); 
     throw caughtThrowable; 
     } 
    }; 
    } 
} 

Quando si utilizza questo come regola all'interno di un banco di prova funziona perfettamente, ma non sembra ottimale per utilizzare la notazione @Rule in ogni caso di test di un suite invece di una singola annotazione nella definizione Suite, così dopo aver controllato un po 'ho provato la nuova notazione @ClassRule nella mia classe Suite:

@RunWith(Suite.class) 
@SuiteClasses({ 
    UserRegistrationTest.class, 
    WebLoginTest.class 
}) 
public class UserSuite {  
    @ClassRule 
    public static RetryTestRule retry = new RetryTestRule(2); 
} 

il problema è che questo non funziona come previsto: superato i test non vengono riprovate . Qualcuno ha provato questo e conosce una soluzione? L'aiuto è molto apprezzato!

+0

Potrebbe essere un duplicato: http://stackoverflow.com/questions/7639353/how-to-define-junit-method-rule-in-a-suite – pholser

+0

Non lo trovi affatto preoccuparti che la tua unità i test falliscono casualmente? – Tobb

risposta

6

@ClassRule s vengono eseguiti una volta per classe, non una volta per metodo. Per avere qualcosa eseguito una volta per metodo, è necessario utilizzare @Rule come si sta facendo, o seguire la risposta per How to define JUnit method rule in a suite?.

Per riutilizzare la regola esistente, è possibile aggiungere la regola all'elenco delle regole per l'esecuzione, utilizzando la classe RunRules come segue:

public class MyRunner extends BlockJUnit4ClassRunner { 
    public MyRunner(Class<?> klass) throws InitializationError { 
     super(klass); 
    } 

    @Override 
    protected void runChild(final FrameworkMethod method, RunNotifier notifier) { 
     Description description= describeChild(method); 
     if (method.getAnnotation(Ignore.class) != null) { 
      notifier.fireTestIgnored(description); 
     } else { 
      RunRules runRules = new RunRules(methodBlock(method), Arrays.asList(new TestRule[]{new RetryTestRule(3)}), description); 
      runLeaf(runRules, description, notifier); 
     } 
    } 
} 

Questo sta usando l'esempio della risposta di cui sopra. Probabilmente potresti combinare le due risposte anche per un controllo più fine, creando una RetryTestRule se ad esempio ci fosse un'annotazione sul test.

+0

Grazie mille per la tua rapida risposta, Matthew. Ho combinato entrambe le risposte come suggerito e ho creato facilmente un corridore e una suite personalizzati. Poi ho aggiunto @RunWith (MySuite.class) alla mia classe suite e voilà! Ho ottenuto un test automatico in caso di fallimento per l'intera suite :) – jbaxenom

+0

Mi manca qualcosa o questo approccio (* combinazione di entrambe le risposte *) fa sì che i test vengano eseguiti prima dell'esecuzione di '@ClassRule ... ExternalResource .. .. prima del metodo' – Daniel

Problemi correlati