Come testare i test?

53

Testiamo il nostro codice per renderlo più corretto (in realtà meno probabilità di essere errato ). Tuttavia, i test sono anche codice - possono anche contenere errori. E se i tuoi test sono buggy, difficilmente riescono a migliorare il tuo codice.

Posso pensare a tre possibili tipi di errori nei test:

  1. Errori logici, quando il programmatore ha frainteso l'attività in corso e i test fanno ciò che pensavano di dover fare, il che è sbagliato;

  2. Errori nel framework di test sottostante (ad es. un'astrazione di derisione leaky);

  3. Bug nei test: il test sta andando leggermente diverso da quello che pensa il programmatore.

Gli errori di tipo (1) sembrano impossibili da prevenire (a meno che il programmatore non ... diventi più intelligente). Tuttavia, (2) e (3) possono essere trattabili. Come gestisci questi tipi di errori? Avete delle strategie speciali per evitarli? Ad esempio, scrivi alcuni test "vuoti" speciali, che controllano solo i presupposti dell'autore del test? Inoltre, come ti avvicini al debug di un caso di test rotto?

    
posta Ryszard Szopa 13.10.2010 - 01:04
fonte

10 risposte

17

I test sono già stati testati. I test sono designati protetti dai bug, perché il test rileva solo le differenze tra il codice e le nostre aspettative. Se ci sono problemi abbiamo un errore. L'errore potrebbe essere nel codice o con la stessa probabilità nei test.

  1. Esistono alcune tecniche che ti impediscono di aggiungere lo stesso bug sia nel codice che nei test:

    1. Il client deve essere una persona diversa dall'implementatore.
    2. Prima scrivi i test e poi il codice (come in Test Driven Development).
  2. Non è necessario testare la piattaforma sottostante. I test non solo esercitano il codice scritto da te, ma eseguono anche il codice dalla piattaforma. Sebbene non sia necessario catturare bug nella piattaforma di test, è molto difficile scrivere codice e test che nascondono sempre un bug nella piattaforma, in altre parole è molto difficile avere un bug sistematico in entrambi i test / codice e nella piattaforma e la probabilità viene ridotta con ogni test creato. Anche se provassi a farlo, avresti un compito molto difficile.

  3. Potrebbero esserci dei bug nei test ma di solito vengono catturati facilmente perché i test sono testati dal codice sviluppato. Tra il codice e i test hai un riscontro di auto-applicazione. Entrambi fanno previsioni su come dovrebbe comportarsi una chiamata specifica di un'interfaccia. Se la risposta è diversa non è necessario avere un bug nel codice. Potresti anche avere un bug nel test.

risposta data 13.10.2010 - 02:06
fonte
24

Prova a rendere i singoli test più piccoli (brevi) possibili.

Questo dovrebbe ridurre le possibilità di creare un bug in primo luogo. Anche se riesci a crearne uno, è più facile da trovare. I test unitari dovrebbero essere piccoli e specifici, con bassa tolleranza per guasti e deviazioni.

Alla fine, probabilmente è solo una questione di esperienza. Più prove scrivi, più diventi migliore, meno possibilità hai di fare test scadenti.

    
risposta data 13.10.2010 - 01:17
fonte
19

Una tattica consiste nel scrivere il test prima del codice testato e assicurarsi che il test fallisca prima per la giusta ragione. Se utilizzi TDD dovresti ottenere almeno questo livello di test dei test.

Un modo più esaustivo per testare la qualità di una suite di test consiste nell'utilizzare test di mutazione .

    
risposta data 13.10.2010 - 04:13
fonte
4

Per n. 1 e n. 3: i test unitari non dovrebbero contenere alcuna logica, se lo fai, probabilmente stai testando più di una cosa nel tuo test unitario. Una buona pratica per il test delle unità è di avere solo un test per unità di test.

Guarda questo video di Roy Osherove per saperne di più su come scrivere bene i test unitari.

    
risposta data 13.10.2010 - 02:29
fonte
3

In termini di # 1 - Penso che sia una buona idea abbinare / revisione del codice per questo aspetto. È facile fare presupposizioni o semplicemente sbagliare le cose, ma se devi spiegare cosa sta facendo il tuo test, qual è il punto, sei più propenso a capire se stai mirando all'obiettivo sbagliato.

    
risposta data 13.10.2010 - 01:34
fonte
2

Ci deve essere un punto in cui si dovrebbe smettere di provare il test unitario. Dovrebbe sapere quando disegnare la linea. Dovremmo scrivere casi di test per testare i casi di test? E i nuovi casi di test scritti per testare i casi di test? Come li testeremo?

if (0 > printf("Hello, world\n")) {
  printf("Printing \"Hello, world\" failed\n");
}

Modifica: aggiornato con spiegazione come suggerito dal commento.

    
risposta data 13.10.2010 - 01:09
fonte
2

Ciao.
Devi applicazioni:

  • Il tuo prodotto
  • Il tuo test per quel prodotto.

Quando esegui test contro il tuo prodotto, in realtà non sei interessato al test stesso, ma in interazione tra il tuo prodotto e i tuoi test. Se il test fallisce, non dice che l'applicazione ha un bug. Dice che l'interazione tra prodotto e test non ha avuto esito positivo . Ora è compito tuo determinare cosa è andato storto. Può essere:

  • l'applicazione non si comporta come previsto (questa aspettativa è espressa nel test)
  • l'applicazione si comporta correttamente, non hai documentato correttamente questo comportamento (nei tuoi test)

Per me i test che falliscono non sono semplici feedback, che questo e quello sono sbagliati . È un indicatore che c'è incoerenza, e ho bisogno di esaminare entrambi per verificare che sia andato storto. Alla fine sono responsabile di verificare che l'applicazione sia corretta, i test sono solo uno strumento per evidenziare le aree che potrebbero valerne la pena.

I test stanno solo controllando alcune parti dell'applicazione. Metto alla prova l'applicazione, provo i test.

    
risposta data 20.02.2011 - 20:16
fonte
2

I test non dovrebbero essere "intelligenti" abbastanza da contenere bug.

Il codice che stai scrivendo implementa una serie di specifiche. (Se X poi Y, a meno che Z nel qual caso Q, etc etc). Tutto il test dovrebbe tentare di realizzare è determinare che X sia realmente Y a meno che Z nel qual caso Q. Questo significa che tutto ciò che un test dovrebbe fare è impostare X e verificare Y.

Ma questo non copre tutti i casi, probabilmente stai dicendo, e avresti ragione. Ma se rendi il test "intelligente" abbastanza per sapere che X dovrebbe essere solo per Y se non per Z, allora stai sostanzialmente ri-implementando la logica di business nel test. Questo è problematico per ragioni che approfondiremo un po 'più in basso. Non dovresti migliorare la copertura del codice rendendo il tuo primo test "più intelligente", dovresti invece aggiungere un secondo test stupido che imposta X e Z e verifica Q. In questo modo avrai due test, uno che copre il caso generale ( a volte noto anche come il percorso felice) e uno che copre il caso limite come test separato.

Ci sono una serie di ragioni per questo, in primo luogo è come si determina se un test fallito è dovuto ad un bug nella logica di business o ad un bug nei test? Ovviamente la risposta è che se i test sono il più semplici possibile è molto improbabile che si nascondano bug. Se ritieni che i test debbano essere sottoposti a test, stai eseguendo un test sbagliato .

Altre ragioni includono il fatto che stai semplicemente replicando lo sforzo (come ho già detto, scrivere un test abbastanza intelligente per esercitare tutte le possibilità in un singolo test è sostanzialmente la replica della logica aziendale che stai provando a testare in primo luogo), se i requisiti cambiano, i test dovrebbero essere facili da modificare per riflettere i nuovi requisiti, i test servono come una sorta di documentazione (sono un modo formale per dire quali sono le specifiche dell'unità in prova) e così via.

TL: DR: Se i tuoi test hanno bisogno di test, stai sbagliando. Scrivi test stupidi .

    
risposta data 13.03.2017 - 14:25
fonte
0

Non una risposta (non ho il privilegio di commentare), ma mi chiedevo se hai dimenticato altre ragioni per sviluppare casi di test ...
Una volta individuati tutti i bug nei test, è possibile eseguire facilmente il test di regressione dell'applicazione. Le suite di test automatizzate potrebbero aiutarti a trovare i problemi prima, prima dell'integrazione. Le modifiche ai requisiti sono relativamente più facili da testare, in quanto le modifiche possono trasformarsi in versioni più recenti e alterate dei casi di test precedenti che passano e i casi più vecchi rimangono per rilevare i problemi.

    
risposta data 20.02.2011 - 20:55
fonte
0

Risposta breve: Il codice di produzione testa i test .

Confronta questo con il modello credito / debito utilizzato in economia. La meccanica è molto semplice - Se il credito differisce dal debito, c'è qualcosa di sbagliato.

Lo stesso vale per i test unitari - Se un test fallisce indica che qualcosa non va. Potrebbe essere il codice di produzione, ma potrebbe anche essere il codice di prova! Quest'ultima parte è importante.

Nota che il tuo tipo (1) bug non può essere trovato dai test unitari. Per evitare questo tipo di bug hai bisogno di altri strumenti.

    
risposta data 27.02.2012 - 15:48
fonte

Leggi altre domande sui tag