Dove devo tracciare la linea tra test unitari e test di integrazione? Dovrebbero essere separati?

9

Ho un piccolo framework MVC su cui ho lavorato. La sua base di codice sicuramente non è grande, ma non è più solo un paio di classi. Alla fine ho deciso di fare il grande passo e iniziare a scrivere test per questo (sì, so che avrei dovuto farlo per tutto il tempo, ma l'API era super instabile fino ad ora)

Ad ogni modo, il mio piano è quello di renderlo estremamente facile da testare, inclusi i test di integrazione. Un test di integrazione di esempio andrebbe su questa linea:

Oggetto di richiesta HTTP falso - > Quadro MVC - > Oggetto risposta HTTP - > controlla che la risposta sia corretta

Dato che tutto ciò è fattibile senza alcun stato o strumenti speciali (automazione del browser, ecc.), potrei farlo con facilità con normali framework di test unitari (io uso NUnit).

Ora la grande domanda. Dove dovrei esattamente tracciare la linea tra test unitari e test di integrazione? Dovrei testare solo una lezione alla volta (il più possibile) con i test unitari? Inoltre, i test di integrazione dovrebbero essere inseriti nello stesso progetto di test del mio progetto di test unitario?

    
posta Earlz 29.10.2012 - 05:03
fonte

3 risposte

18

Integrazione e test di unità

Dovresti mantenere i tuoi test unitari e i tuoi test di integrazione completamente separati. I test di unità dovrebbero testare una cosa e una cosa solo e in completo isolamento del resto del sistema. Un'unità è definita in modo approssimativo, ma in genere si riduce a un metodo oa una funzione.

Ha senso fare test per ogni unità in modo che tu sappia che i loro algoritmi sono implementati correttamente e sai immediatamente cosa è andato storto dove, se l'implementazione è difettosa.

Dato che esegui il test in completo isolamento durante il test dell'unità, usi oggetti stub e mock per comportarti come il resto del tuo applicazione. È qui che entrano in gioco i test di integrazione. Testare tutte le unità in isolamento è grande, ma è necessario sapere se le unità stanno effettivamente lavorando insieme.

Questo significa sapere se un modello è effettivamente memorizzato in un database o se un avvertimento viene realmente emesso dopo che l'algoritmo X fallisce.

Sviluppo guidato dal test

Facendo un passo indietro e guardando Test Driven Development (TDD) ci sono diverse cose da tenere in considerazione.

  1. scrivi il tuo test unitario prima di scrivere effettivamente il codice che lo fa passare.
  2. Fai passare il test, scrivi solo il codice sufficiente per realizzare questo.
  3. Ora che il test è passato, è tempo di fare un passo indietro. C'è qualcosa da refactoring con questa nuova funzionalità in atto? Puoi farlo in modo sicuro poiché tutto è coperto dai test.

Integrazione prima vs Integrazione ultima

I test di integrazione si inseriscono in questo ciclo TDD in due modi. Conosco persone a cui piace scriverle in anticipo. Chiamano un test di integrazione un test end-to-end e definiscono un test end-to-end come un test che verifica completamente l'intero percorso di un caso d'uso (si pensi di creare un'applicazione, eseguirne l'avvio, andare a un controller, eseguirlo, verificando il risultato, l'output, ecc ...). Quindi iniziano con il loro primo test di unità, lo fanno passare, aggiungono un secondo, lo fanno passare, ecc ... Lentamente passano sempre più parti del test di integrazione fino a quando la funzione non è terminata.

L'altro stile sta creando un test dell'unità caratteristica per unità di test e aggiungendo i test di integrazione ritenuti necessari in seguito. La grande differenza tra questi due è che nel caso del test di integrazione prima devi pensare al design di un'applicazione. Questo tipo di disaccordo con la premessa che TDD riguarda tanto la progettazione delle applicazioni quanto il testing.

pratici

Al mio lavoro abbiamo tutti i nostri test nello stesso progetto. Vi sono tuttavia diversi gruppi. Lo strumento di integrazione continua esegue prima quelli che sono contrassegnati come test di unità. Solo se quelli che riescono sono più lenti (perché fanno richieste reali, usano veri database, ecc.) Vengono eseguiti anche test di integrazione.

Di solito usiamo un file di test per una classe tra l'altro.

Lettura suggerita

  1. Crescere il software orientato agli oggetti, guidato dai test Questo libro è un ottimo esempio della prima metodologia del test di integrazione
  2. L'arte del testing unitario, con esempi in dot.net sui test unitari, con esempi in dot.net: D Ottimo libro sui principi alla base del test unitario.
  3. Robert C. Martin su TDD (Articoli gratuiti): leggi i primi due articoli che ha collegato anche lì.
risposta data 29.10.2012 - 08:57
fonte
1

Ciò che è importante in qualsiasi strategia di test, è la copertura di test - cioè essere in grado di dimostrare che tutta la funzionalità è in fase di test.

In generale, e a meno che tu non abbia requisiti specifici in contrario (ad es. DO178 Livello A, IEC61508 SIL 4 ecc.) che non sembra essere il caso nella tua situazione, quindi se puoi testare la funzione completa di classe o modulo (e dimostrare di avere) a livello di sistema, quindi il test a livello di sistema è adeguato. E così via. Il test delle unità è necessario solo quando non hai coperto ulteriormente il test.

Where exactly should I draw the line between unit tests and integration tests?

Dato che i test di integrazione sono solitamente più facili, più veloci e più economici, traccia la linea il più lontano possibile ...

Should I only test one class at a time(as much as possible) with unit tests?

Dipende dall'ambito, ancora ... per definizione, un test unitario sta testando una singola unità. Ma se riesci a testare completamente un modulo completo in una volta sola, se lo desideri, fallo. In effetti, stai eseguendo diversi test unitari in un colpo.

Also, should integration tests be placed in the same testing project as my unit testing project?

Nessuna ragione fondamentale perché no ... a meno che il test di livello superiore non venga eseguito da un tester indipendente, a quel punto dovresti pubblicare solo un eseguibile e una strumentazione minima.

    
risposta data 29.10.2012 - 08:24
fonte
0

Quando ho dei piccoli progetti, inserisco tutti i test nello stesso progetto. Dal momento che un progetto più grande avrebbe queste divisioni, mi limito a garantire che sarebbe possibile metterli a parte se fosse necessario.

Con i test unitari di solito testo solo una classe (SUT) in un file.

    
risposta data 29.10.2012 - 05:14
fonte

Leggi altre domande sui tag