Perché i framework xUnit non consentono l'esecuzione in parallelo dei test?


15

Conoscete qualche framework xUnit che consenta di eseguire test in parallelo, per utilizzare più core nella macchina di oggi?

Se nessuno (o così pochi) lo fa, forse c'è una ragione ... È che i test di solito sono così rapidi che le persone semplicemente non sentono il bisogno di paralizzarli?

C'è qualcosa di più profondo che impedisce di distribuire (almeno alcuni) i test su più thread?


I test unitari sono decisamente lenti. Anche se ogni test da solo è veloce, si accumulerebbero poiché le persone hanno letteralmente milioni di casi di test.
Pacerier,

Risposte:


6

NUnit 2.5 in bundle pNUnit che consente l'esecuzione di test in parallelo.

Questa versione include pNUnit, un runner NUnit esteso per test paralleli distribuiti. Il programma pNUnit è stato sviluppato da Codice Software per l'uso nel test di Plastic SCM ed è stato contribuito a NUnit. Per ulteriori informazioni sull'uso di pNUnit, consultare il sito pNUnit.

Il lato JUnit ha junit parallele e amino .


Quindi l'unica ragione per gli altri framework sarebbe "non ancora implementata"?
Xavier Nodet

1
@Xavier Sì; questa è una dichiarazione equa.
Aaron McIver l'

10

Per rispondere alla seconda parte della tua domanda: c'è qualcosa di più profondo che impedisce di distribuire (almeno alcuni dei) test su più thread?

Una grande quantità di codice funziona solo quando viene eseguito il thread singolo. È banale produrre accidentalmente contese di risorse e deadlock quando si scrivono programmi partendo dal presupposto che verranno eseguiti a thread singolo. E questo funziona bene perché la maggior parte dei programmi esegue effettivamente single thread. Il parallelismo si ottiene eseguendo più copie o programmi diversi contemporaneamente (gli script Web sono un esempio comune: molti utenti che accedono a una singola pagina significano molte copie degli script per quella pagina in esecuzione contemporaneamente).

Immagina una semplice classe "accedi al file". Quando si crea un'istanza, apre il file per la scrittura, quando si libera l'istanza, si chiude il file. Quindi, il primo test crea un'istanza e inizia a eseguire un test. Il secondo test fa la stessa cosa in un secondo thread. E non riesce, perché la seconda istanza non può ottenere l'accesso in scrittura al file. Ma se eseguito uno alla volta, tutti i test passerebbero.

Tutto questo può essere codificato e il semplice esempio può essere modificato per funzionare. Ma farlo probabilmente non è necessario per il programma originale . Dover scrivere un codice thread-safe solo per poter eseguire unit test è irragionevole per molte persone. Quindi i test unitari multi-thread dovrebbero rimanere un extra opzionale.


+1 Questa dovrebbe essere la risposta esclusa perché in realtà risponde al perché.
Oliver Weiler,

4

Se i test devono configurare e interrogare un database, i test eseguiti in parallelo interferirebbero tra loro a meno che, a meno che non esista un database separato per ciascun test in esecuzione in parallelo.


Questo non è importante per la piattaforma di test (xUnit); questo è un dettaglio di implementazione.
Aaron McIver l'

E non tutti i test scritti in un framework di unit test sono unit test, proprio come quello che accede al database non è in realtà un unit test, più come un test di integrazione.
c_maker

Solo perché un test tocca un database non significa che sia un test di integrazione. Un metodo che viene eseguito parzialmente in C # e parzialmente in uno sproc del database, ad esempio, è ancora concettualmente un test unitario, purché non sia prevista alcuna preconfigurazione (ovvero lo schema dei dati è presente, ma non sono presenti dati). Tali test possono creare dati per una singola esecuzione, ma al termine devono reimpostarsi su uno stato vuoto). Questa è probabilmente un'opinione controversa, ma tali test non possono essere considerati test di integrazione, perché sono esplicitamente test a configurazione zero, a distribuzione zero che testano piccole unità di codice.
Triynko,

2

Anche se JUnit di per sé potrebbe non consentirlo (non ho familiarità con le sue ultime versioni), Maven con il suo plugin Surefire ha un'opzione per eseguire test in parallelo. Non l'ho ancora provato però.

Non sono fortemente sollecitato a studiare questa opzione, poiché abbiamo solo poco più di un migliaio di test e vengono eseguiti abbastanza velocemente. Tuttavia, so che alcune delle apparecchiature di test hanno dipendenze implicite tra (abbiamo riscontrato alcune di tali dipendenze quando alcuni test si sono interrotti inaspettatamente in passato), quindi c'è il rischio che parallelizzare i test farà fallire in modo imprevedibile alcuni di essi. Puoi dire che va bene in quanto rende esplicito il problema. Tuttavia, abbiamo a che fare con un sistema legacy e abbiamo molte altre questioni importanti da affrontare: il tempo è una risorsa scarsa (come al solito).


0

La codifica multi-thread non è banale. Anche quando fatto da persone che sanno cosa stanno facendo, possono verificarsi bug dipendenti dal tempo. Sono difficili da risolvere. Avendo affrontato le migliaia di bug di un tipo di caso che può produrre il multi-treading, preferirei non averli nel mio framework di test. La prima correzione che ho ricevuto sembrava funzionare, ma su ulteriori test è stato scoperto che era appena diventato un bug di decine di migliaia.

Le tecniche per eseguire il multi-threading su più processori stanno migliorando con l'avvento dei PC multiprocessore. Tuttavia, ci vorrà del tempo prima che siano ampiamente utilizzati.

Alcune suite di test hanno dipendenze tra i test che non devono essere esplicitamente dichiarate quando i test vengono eseguiti in un singolo flusso. Tuttavia, su un motore a vapore multiplo, dovrebbero essere esplicitamente dichiarati. (Dove dovrebbero esistere tali dipendenze è una domanda diversa.)

Da un altro punto di vista, alcune cose non devono essere eseguite in parallelo. Se il processo si svolge in modo sufficientemente veloce, è meglio focalizzare gli sforzi su cose diverse dall'implementazione del multi-threading.


0

MBUnit è in grado di eseguire test in parallelo semplicemente specificando alcuni attributi a livello di assembly.

[assembly: DegreeOfParallelism(6)]
[assembly: Parallelizable(TestScope.All)]

Ho usato quel progetto per eseguire i test di selenio in parallelo abbastanza bene per qualche tempo. Purtroppo il progetto non è più molto vivo.

xUnit 2.0 dovrebbe anche supportare i test delle unità parallele ma non l'ho ancora provato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.