I rami nelle prove unitarie sono cattivi?

3

Dire che voglio affermare che un determinato menu di opzioni è visualizzato nel front-end di un progetto. Il menu è sullo schermo X e devo prima selezionare i dati in Y per arrivare a X. Ora, non importa affatto quali dati seleziono in Y, porterò sempre a X.

Ma a volte, a seconda dei dati, otterrò una schermata Z che posso semplicemente saltare. Ovviamente, se scrivo il test in modo deterministico, il test potrebbe fallire se i dati che ho selezionato portano alla schermata Z.

I dati di cui sto parlando sono dati di test, impostati prima di ogni test allo stesso stato. Quindi, in teoria, potrei semplicemente selezionare una voce di dati che so non andrà alla schermata Z.

Ma potrei anche semplicemente includere un controllo per vedere se sono sullo schermo Z dopo aver selezionato i dati e saltare Z. Ora anche le modifiche ai dati di test (sebbene rari, succede) non infrangono il mio test.

In qualche modo non mi piace questo approccio, ma non posso davvero spiegare il perché. Aggiungere un metodo per verificare la presenza di Z aggiungerebbe un (probabilmente) metodo "inutile" al mio framework di test.

Quindi la mia domanda è: le filiali gestiscono un comportamento condizionale che non viene testato in quel test specifico? Ci sono problemi con questo approccio? È bello fare questo?

    
posta Timo Türschmann 02.10.2013 - 10:43
fonte

3 risposte

7

Non è irragionevole cambiare i dati del test per cambiare il risultato di un test.

Non inserirò il ramo condizionale, mi assicurerei di avere un test separato con un set di dati di test che va sempre sullo schermo Z in modo che il comportamento possa essere testato.

Se il test iniziale che stai tentando di fare è che quando vengono immessi i dati da Y, viene visualizzata la schermata X, che è esattamente ciò che dovresti testare - non complicare eccessivamente i test.

Y - > Z - > X non è la stessa di Y - > X e io presumiamo che alcune logiche di business (che dovrebbero essere testate) controllino l'aspetto di Z?

    
risposta data 02.10.2013 - 10:49
fonte
6

Eviterei le ramificazioni nel codice di test - vorrei trovare le condizioni esatte che mi hanno portato lungo il percorso X- > Y e testare i percorsi più comuni e di confine per questo. Quindi identificherei le condizioni che hanno portato l'utente lungo la X - > Z - > Y percorso e scrivere un test separato per le condizioni al contorno di quello.

Se non stai usando dati / mock completamente deterministici in modo che i tuoi test non si comportino in modo del tutto prevedibile, non stai scrivendo test unitari.

Se i due test hanno molto in comune, potresti voler inserire il codice condiviso in metodi helper o setup / takedown in modo da non ripeterti troppo nei test.

A seconda della piattaforma su cui stai lavorando, può essere molto utile disporre di test parametrizzati in modo da poter eseguire dati diversi attraverso lo stesso test per coprire diverse condizioni al contorno.

    
risposta data 02.10.2013 - 15:54
fonte
2

In generale, quando esegui il test, vuoi evitare qualsiasi incertezza e vuoi mantenere il test al punto. L'incertezza / casualità nei dati o nella logica di test renderà le cose più complicate / meno comprensibili a te o ad altri sviluppatori che portano a un incubo di manutenzione. Questo è vero per tutti i test su tutta la linea.

Questo significa che imposta solo i dati (se possibile) necessari per testare una cosa . Ciò renderà i test più facili da capire e da mantenere perché ci sono meno distrazioni da ciò che conta. Inoltre, rende i test più disaccoppiati l'uno dall'altro perché i dati che stai utilizzando per quella funzionalità non interferiscono con altri test. Per le applicazioni più piccole con una piccola suite di test, è possibile fare i conti con "singoli dati di test di grandi dimensioni". Tuttavia, il mantenimento di un set di dati così ampio diventa un incubo quando si lavora con un'applicazione più grande.

Per quanto riguarda la logica di test, non vuoi ingombrare con condizionali come se per caso ho questa cosa intermedia, ignora e continua . In un test dovresti sempre sapere quale azione conduce a quale stato, quindi dovresti specificarlo in modo specifico. Tali dichiarazioni condizionali distolgono solo da ciò che è importante per il test e può portare a più codice che si occupa semplicemente di queste "possibilità" rispetto al codice di test stesso . Un altro problema con questo approccio è che l'applicazione e il codice di test possono andare fuori sincrono. Quando l'applicazione si evolve, rimuovi lo stato Z ma non viene ripulito dal codice di test stesso perché era lì solo condizionatamente (i test non si interrompono, quindi non segnala che c'è un problema). Questo può essere estremamente stressante specialmente per qualcuno che è nuovo alla base di codice perché ora devono scavare per vedere di cosa tratta questo codice.

    
risposta data 02.10.2013 - 17:48
fonte

Leggi altre domande sui tag