Come fare un test dipende dai risultati di un altro test?

11

Diciamo che esiste una classe di utilità che fornisce alcuni metodi statici comuni usati ovunque nel tuo codice da molte altre classi.

Come progetteresti i tuoi test unitari per i consumatori dell'utilità in modo che i loro test falliscano se uno qualsiasi dei test di utilità non passa? Puoi farlo o devi controllare tu stesso se i test di classe di utilità sono tutti verdi?

Ad esempio, ho un programma di utilità di separazione dei messaggi che viene utilizzato (o meglio il suo output) da un parser di messaggi. Mi piacerebbe essere sicuro che lo smistatore di messaggi funzioni correttamente prima che il parser del messaggio venga testato.

Ho scritto test per entrambi, ma c'è un modo per collegarli e fare un test dipende dal risultato di qualche altro test?

Non sono riuscito a trovare un tag adatto per questo, ma sto utilizzando il motore di test dell'unità di Visual Studio.

    
posta t3chb0t 27.02.2015 - 10:53
fonte

5 risposte

9

Non ha senso fare in modo che ogni difetto nel tuo sistema effettui un esattamente un test.

Una suite di test ha un lavoro: verificare che non ci siano difetti noti. Se c'è un difetto, non importa se un test fallisce o 10. Se ti abitui al fallimento della tua suite di test, se cerchi di valutare quanto "cattivo" il tuo programma è contando in mancanza di test, non stai usando il test di regressione nel modo giusto. La suite di test dovrebbe superare tutti i test tutti prima di pubblicare il codice.

L'unico motivo valido per saltare i test è che se testano la funzionalità incompleta e prendi una quantità eccessiva di tempo che potresti impiegare meglio durante l'implementazione della cosa che dovrebbero testare. (Questo è solo un problema se non si pratica uno sviluppo rigoroso basato sui test, ma questa è una scelta valida, dopotutto.)

Altrimenti, non preoccuparti di provare a trasformare la tua suite di test in un indicatore che ti dice esattamente cosa c'è che non va. Non sarà mai esatto, e non dovrebbe essere. Dovresti proteggerti dal fare lo stesso errore due volte, tutto qui.

    
risposta data 03.03.2015 - 11:23
fonte
8

Dipende dai tuoi strumenti, ma probabilmente non puoi (e non dovresti)

Alcuni framework di test delle unità (prendi PHPUnit , ad esempio) consente di eseguire test" concatenati "in modo che un test non riuscito a un livello non esegua altri test. Tuttavia, dubito che questo risolverà il tuo problema per questa situazione.

Non permettendo che le prove di esecuzione degli ordini di test garantiti siano isolate l'una dall'altra ed è generalmente considerata una buona cosa. Immagina cosa succederebbe se i test non solo si comportassero da soli, ma fornissero anche dati per altri test su cui lavorare ...

È possibile inserire questi metodi di utilità in una soluzione separata o in una categoria di test. Assicurati che siano visivamente "in risalto" nel tuo runner di test, o che questa categoria venga eseguita per prima e non esegua altri test se i test in questa categoria falliscono *. Quando uno di questi test fallisce, l'errore probabilmente si sovrapporrà a tutti i test e si dovrebbe fare in modo di assicurarsi che chiunque esegua i test sappia iniziare a correggere questi test di errore prima di tutto. Lo stesso vale per i test unitari e l'integrazione. Se un Unittest fallisce, cadrà a cascata e causerà ogni sorta di caos nei test di Integrazione. Tutti sanno che quando i test di Unit AND Integration falliscono, si inizia controllando gli Unittests ...

* Con uno script di build o di test automatico è possibile eseguire prima questa categoria, controllare il risultato e eseguire solo gli altri test se questa prima serie di test passa.

    
risposta data 03.03.2015 - 13:10
fonte
5

Prova a mantenere il tuo test unitario atomico. Ricorda che il codice di test automatizzato fa anche parte della tua base di codice, ma non è esso stesso sotto test, quindi tienilo il più semplice e ovvio possibile.

Per rispondere alla tua domanda più direttamente, non vi è alcuna garanzia dell'ordine di esecuzione dei test, quindi non c'è modo di garantire che il test di utilità abbia esito positivo prima dell'esecuzione degli altri test. Quindi non esiste un modo garantito per ottenere quello che vuoi pur avendo una singola suite di test per tutti i tuoi test.

È possibile spostare le utilità sulla propria soluzione e aggiungere un riferimento alla relativa DLL risultante nel progetto corrente.

    
risposta data 27.02.2015 - 11:14
fonte
4

In un riepilogo non vuoi usare strumenti / tecniche per fare cose diverse da quelle per cui sono destinate.

Quello che stai cercando di fare sembra una preoccupazione che potrebbe essere risolta facilmente con una pratica di CI (integrazione continua).

In questo modo puoi mantenere i tuoi test atomici come già suggerito e lasciare che la CI si occupi di verificare i tuoi test.

Se qualche test fallisce, puoi impostarlo in modo che non permetta al tuo codice di essere pubblicato.

    
risposta data 05.03.2015 - 02:01
fonte
2

Ho l'abitudine di cercare sempre di differenziare il codice a livello di applicazione dal codice a livello di framework, quindi ho riscontrato il problema che stai descrivendo abbastanza spesso: di solito vuoi che tutto il codice a livello di framework sia testato prima che inizi il codice a livello di applicazione essere testato. Inoltre, anche all'interno del codice a livello di framework, tendono ad esserci alcuni moduli di framework fondamentali che vengono utilizzati da tutti gli altri moduli framework e, se qualcosa non funziona nei fondamentali, non c'è davvero alcun motivo per testare qualcos'altro.

Sfortunatamente, i fornitori di framework di test tendono ad avere idee un po 'rigide su come le loro creazioni sono destinate ad essere utilizzate, e sono piuttosto protettive rispetto a quelle idee, mentre le persone che usano i loro framework tendono ad accettare l'uso previsto senza fare domande. Questo è problematico, perché soffoca la sperimentazione e l'innovazione. Non so di tutti gli altri, ma preferirei avere la libertà di provare a fare qualcosa in un modo strano, e vedere da solo se i risultati sono migliori o peggiori rispetto al modo stabilito, piuttosto che non avere la libertà di fai le cose a modo mio in primo luogo.

Quindi, a mio parere, le dipendenze dei test sarebbero una cosa fantastica e, al posto di ciò, la possibilità di specificare l'ordine in cui verranno eseguiti i test sarebbe la cosa migliore.

L'unico modo in cui ho trovato di affrontare il problema di ordinare i test è un'attenta denominazione, in modo da sfruttare la tendenza dei framework di test per eseguire test in ordine alfabetico.

Non so come funzioni in Visual Studio, perché devo ancora fare qualsiasi cosa che implichi test approfonditi con C #, ma nella parte Java del mondo funziona come segue: Sotto la cartella sorgente di un progetto di solito abbiamo due sottocartelle, una chiamata "main", contenente il codice di produzione e una chiamata "test", contenente il codice di test. Sotto "main" abbiamo una gerarchia di cartelle che corrisponde esattamente alla gerarchia dei pacchetti del nostro codice sorgente. I pacchetti Java corrispondono approssimativamente agli spazi dei nomi C #. C # non richiede di associare la gerarchia di cartelle alla gerarchia di namespace, ma è consigliabile farlo.

Ora, ciò che le persone di solito fanno nel mondo Java è che nella cartella "test" loro rispecchiano la gerarchia delle cartelle trovata nella cartella "principale", in modo che ogni test risieda in lo stesso pacchetto esatto della classe che prova. La logica alla base di questo è che molto spesso la classe di test ha bisogno di accedere ai membri del pacchetto privato della classe sotto test, quindi la classe di test deve essere nello stesso pacchetto della classe sotto test. Nel lato C # del mondo non esiste la visibilità locale dei namespace, quindi non c'è ragione di specchiare le gerarchie delle cartelle, ma penso che i programmatori C # seguano più o meno la stessa disciplina nella strutturazione delle loro cartelle.

In ogni caso, trovo tutta questa idea di permettere alle classi di test di avere accesso ai membri del pacchetto locale delle classi sotto test errate, perché tendo a testare le interfacce, non le implementazioni. Quindi, la gerarchia delle cartelle dei miei test non deve rispecchiare la gerarchia delle cartelle del mio codice di produzione.

Quindi, quello che faccio è che nomino le cartelle (cioè i pacchetti) dei miei test come segue:

t001_SomeSubsystem
t002_SomeOtherSubsystem
t003_AndYetAnotherSubsystem
...

Questo garantisce che tutti i test per "SomeSubsystem" saranno eseguiti prima di tutti i test per "SomeOtherSubsystem", che a loro volta saranno tutti eseguiti prima di tutti i test per "AndYetAnotherSubsystem", e così via, e così via.

All'interno di una cartella, i singoli file di test sono denominati come segue:

T001_ThisTest.java
T002_ThatTest.java
T003_TheOtherTest.java

Ovviamente, è di grande aiuto che i moderni IDE abbiano potenti capacità di refactoring che ti permettono di rinominare interi pacchetti (e tutti i sotto-pacchetti e tutto il codice che li fa riferimento) con solo un paio di clic e sequenze di tasti.

    
risposta data 24.12.2015 - 15:08
fonte

Leggi altre domande sui tag