Come devo testare il mio codice TEST?


22

Una delle poche cose su cui la maggior parte degli sviluppatori di software concorda è che non dovresti fare affidamento sul codice per funzionare correttamente a meno che non lo provi. Se non lo collaudi, potrebbero esserci bug nascosti che ti causeranno solo più lavoro lungo la strada.

Capisco come testare il mio codice normale, ma come devo testare il mio codice di test per essere sicuro che possa trovare e segnalare in modo efficace gli errori quando sono presenti? Personalmente sono stato abbastanza stupido da scrivere casi di test errati che sarebbero passati quando non avrebbero dovuto, sconfiggendo così in primo luogo lo scopo dei miei test di scrittura. Fortunatamente, ho trovato e corretto gli errori nel tempo, ma secondo i mantra dei test sembra che nessuna suite di test sarebbe completa senza avere il proprio set di test per assicurarsi che funzionasse.

Mi sembra che il modo migliore per farlo sia quello di assicurarsi che il test fallisca per il codice difettoso. * Se passo 2 minuti alternativamente ad aggiungere bug al codice e assicurandomi che fallisca, dovrei avere un grado accettabile di fiducia che il "lavoro" dei test. Questo mi porta alla mia seconda domanda: quali sono i modi migliori per introdurre i bug per assicurarsi che vengano catturati dai casi di test? Devo solo commentare casualmente le dichiarazioni, assicurarmi che il ramo sbagliato di un if-elsevenga eseguito negandone le condizioni e cambiare l'ordine di esecuzione del codice con effetti collaterali, ecc., Finché non sono soddisfatto che i miei test cattureranno la maggior partebug comuni? In che modo gli sviluppatori professionisti confermano che i loro test fanno effettivamente quello che dovrebbero fare? Assumono semplicemente che i test funzionino o si prendono anche il tempo di testarli? In tal caso, come testano i test?

Non sto suggerendo alle persone di dedicare così tanto tempo a testare i loro test e quindi a testare i test per i loro test in modo che non scrivano mai il vero codice, ma ho fatto cose abbastanza stupide che sento di poter trarre beneficio da un po ' di "meta-test", ed era curioso del modo migliore di procedere. : D

* Ho potuto verificare se il test ha esito positivo durante il test del codice "privo di bug", ma l'utilizzo del codice come una specifica per il test sembra piuttosto arretrato ...


Sembra che tu non abbia fiducia nei tuoi test unitari - molto probabilmente perché ti manca molta esperienza nella scrittura dei test? In tal caso sarebbe irragionevole scrivere più test e aspettarsi un risultato diverso. Continua a fare quello che stai facendo, sii il più accurato possibile (prova per fallimento e successo) e presto i tuoi test unitari inizieranno a pagare per se stessi - e la tua fiducia in essi crescerà.
MattDavey,

Possibile duplicato di Come testare i test?
moscerino del

Prima di utilizzare più strumenti, utilizzare meglio gli strumenti reali . Scrivi meno test, ma test scritti più efficienti e migliori. Non puoi fidarti di qualcosa che non capisci.
Steve Chamaillard,

Risposte:


16

Il flusso standard per TDD è:

  1. Scrivi un test fallito. (Rosso)
  2. Apporta la modifica del codice più piccola che lo fa passare (verde)
  3. Refactor (mantenendolo verde)

Il test per i test in questo caso è il passaggio 1: assicurarsi che il test abbia esito negativo prima di apportare eventuali modifiche al codice.

Un altro test che mi piace è se è possibile eliminare un po 'di codice e implementarlo nuovamente in un modo diverso, e i test falliscono dopo la cancellazione ma funzionano con un algoritmo diverso in atto.

Come per tutte le cose, non esiste un proiettile magico. Dimenticare di scrivere un test richiesto è altrettanto facile per uno sviluppatore quanto dimenticare di scrivere il codice. Almeno se stai facendo entrambe le cose, hai il doppio delle opportunità per scoprire la tua omissione.


4
Doppia contabilità: i test unitari verificano il codice di produzione e viceversa. Esistono due modi diversi per indicare lo stesso problema. Come nella doppia contabilità, dove registri le tue transazioni in due modi diversi ed entrambi devono ottenere gli stessi totali.
EricSchaefer,

La domanda riguarda il problema quando il passaggio 2 rende il test verde anche se il codice è ancora errato. Esempio semplice: si dispone di una funzione che deve restituire un puntatore a un oggetto elenco non vuoto. Il test verifica se il puntatore è nulle non riesce al passaggio 1. Apportare la modifica del codice più piccola che lo fa passare restituendo un elenco vuoto. Il test ora è "verde" perché hai due bug.
Christian Hackl,

@ChristianHackl in quella fase di sviluppo è un'implementazione perfetta! Devi aggiungere uno (o più) test che inizialmente non riescono a specificare ulteriormente il comportamento previsto. Successivamente lo implementate, rendendo questi test verdi.
Andy,

@Andy: cura di elaborare come questa sia un'implementazione perfetta quando ho un bug sia nel codice che nel test, e uno mi impedisce di notare l'altro? (Il bug nel codice è che viene restituito un elenco vuoto e il bug nel test è che controllo per nulle non per vuoto.)
Christian Hackl

@ChristianHackl hai ragione secondo il segno di spunta vuoto. Questo, in effetti, dovrebbe essere fatto anche in un test. Quando traduci i tuoi requisiti in test, passo dopo passo, c'è poco spazio per i bug. Tranne quelli quando non ti attieni alle specifiche (come trascurare un controllo non vuoto).
Andy,

9

Un approccio è il test di mutazione , utilizzando uno strumento come Jester :

Jester apporta alcune modifiche al codice, esegue i test e, se i test superano, Jester visualizza un messaggio che dice cosa è cambiato


4

Test per prove? Non seguire quella strada. Quindi probabilmente avrai bisogno di test per test per test, e quindi test per test per test per test ... dove ti fermi?

Il normale flusso di test procede in questo modo e, come sviluppatore, trascorrerai la maggior parte del tempo sui punti 1-3:

  1. Codice
  2. Test unitari
  3. Test di integrazione
  4. Sistema / altro automatizzato
  5. QA / tester umani

Se passo 2 minuti alternativamente aggiungendo bug al codice (...)

Il tuo codice alla fine "farà crescere" i propri bug, non perdere tempo a introdurli a mano. Per non parlare, una cosa che sapevi in ​​anticipo è davvero un bug? Gli insetti arriveranno, non me ne preoccuperei.

Devo solo commentare casualmente le dichiarazioni, assicurarmi che il ramo sbagliato di un if-else venga eseguito negandone la condizione (...)

Questo è in realtà un approccio praticabile per verificare se effettivamente testare ciò che pensi di fare. Non penso che sia sempre così buono in quanto soffre dello stesso problema di "test per test per test ..." cosa: quando smetti di alterare il codice sapendo che il codice che stai testando funziona al 100%?

È anche bello ricordare tutti i consigli pragmatici del programmatore di tutti i tempi - non ne avrai bisogno . Sii agile, scrivi test e codice per veri e propri bug, invece per quelli ipotetici che potrebbero o meno apparire.


3
Non sono preoccupato che il mio codice cresca i propri bug, sono preoccupato che i miei test li catturino quando accadono. Se i miei test sono errati, non faranno il loro lavoro e penserò che mi sono sbarazzato di una certa classe di bug quando in realtà esistono ancora, rendendo il mio lavoro più difficile perché sto guardando risultati di test imprecisi (passa quando dovrebbero fallire).
Gordon Gustafson,

@CrazyJugglerDrummer: i tuoi test non cattureranno sicuramente tutti i bug. Non servono a questo scopo - è qui che entra in gioco il QA. Se lo facessero, significherebbe che il software è privo di bug, a meno che il codice sorgente non cambi, che non ho mai visto.
km

3

Per costruzione, il codice funzionale e il codice di test vengono testati uno contro l'altro. Rimane un problema: il caso di bug in modalità comune, quando un bug nel codice funzionale è nascosto da un bug nel codice di test. TDD non è immune da questo effetto. Questo è il motivo per cui i test vengono generalmente eseguiti su più livelli da persone diverse al fine di ridurre questa probabilità.


0

Si verifica il test unitario una volta quando lo si scrive, nel debugger. Quindi lo lasci in pace e te ne dimentichi. Non ci sono problemi qui.

Considera questo. Qual è lo scopo di un test unitario? Ti avvisa quando una qualsiasi delle numerose modifiche che farai nel tuo programma principale cambia accidentalmente la logica in quel programma. Vuoi averlo perché sai che qualsiasi cambiamento potenzialmente rompe qualcosa. Questo è esattamente il motivo per cui non ci sono problemi se non testare il test: non si scherza con il test fino a quando non si cambia intenzionalmente la logica del programma (che richiederebbe di rivisitare il test e testarlo ancora), quindi il tuo è probabile che il test non si interrompa accidentalmente.


-2

Esiste un test di mutazione che valuta e misura l'idoneità e la qualità del test.

Possiamo usarlo per valutare "il test" stesso.

In breve, possiamo valutare il nostro test (ad esempio TestA) testando TestA può trovare la differenza tra il codice e i suoi codici di mutazione (codice molto simile ma leggermente diverso con il codice originale).

Se TestA non riesce a trovare la differenza tra il codice e i suoi codici di mutazione, significa che TestA ha regolamenti troppo approssimativi per testare il codice originale.

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.