Qual è la differenza tra test unitari, funzionali, di accettazione e di integrazione? [chiuso]


799

Qual è la differenza tra test unitari, funzionali, di accettazione e di integrazione (e qualsiasi altro tipo di test che non ho menzionato)?



1
Penso che hai dimenticato di includere il test di carico!
Talk is Cheap Mostrami il codice

Risposte:


1350

A seconda di dove guardi, otterrai risposte leggermente diverse. Ho letto molto sull'argomento, ed ecco la mia distillazione; di nuovo, questi sono leggermente lanosi e altri potrebbero non essere d'accordo.

Test unitari

Verifica la più piccola unità di funzionalità, in genere un metodo / funzione (ad esempio, data una classe con uno stato particolare, la chiamata del metodo x sulla classe dovrebbe causare y). I test unitari dovrebbero essere focalizzati su una caratteristica particolare (ad esempio, chiamare il metodo pop quando lo stack è vuoto dovrebbe lanciare un InvalidOperationException). Tutto ciò che tocca dovrebbe essere fatto in memoria; ciò significa che il codice test e il codice testato non dovrebbero:

  • Chiama in collaboratori (non banali)
  • Accedi alla rete
  • Hit un database
  • Usa il file system
  • Accendi un filo
  • eccetera.

Qualsiasi tipo di dipendenza che è lenta / difficile da comprendere / inizializzare / manipolare dovrebbe essere cancellata / derisa / qualunque cosa usando le tecniche appropriate in modo da poter concentrarsi su ciò che l'unità di codice sta facendo, non su ciò che fanno le sue dipendenze.

In breve, i test unitari sono quanto più semplici possibili, facili da eseguire il debug, affidabili (a causa di fattori esterni ridotti), rapidi da eseguire e aiutano a dimostrare che i più piccoli elementi costitutivi del programma funzionano come previsto prima che vengano messi insieme. L'avvertenza è che, anche se puoi dimostrare che funzionano perfettamente in isolamento, le unità di codice possono esplodere quando combinate, il che ci porta a ...

Test di integrazione

I test di integrazione si basano su test unitari combinando le unità di codice e verificando che la combinazione risultante funzioni correttamente. Questo può essere sia l'interno di un sistema, sia la combinazione di più sistemi per fare qualcosa di utile. Inoltre, un'altra cosa che differenzia i test di integrazione dai test unitari è l'ambiente. I test di integrazione possono e utilizzano i thread, accedono al database o fanno tutto il necessario per garantire che tutto il codice e le diverse modifiche all'ambiente funzionino correttamente.

Se hai creato un codice di serializzazione e l'unità ha testato le sue parti interne senza toccare il disco, come fai a sapere che funzionerà durante il caricamento e il salvataggio su disco? Forse hai dimenticato di svuotare e gettare i filestream. Forse i tuoi permessi sui file non sono corretti e hai testato le viscere usando nei flussi di memoria. L'unico modo per scoprirlo con certezza è testarlo "davvero" utilizzando un ambiente più vicino alla produzione.

Il vantaggio principale è che troveranno bug che i test unitari non possono come ad esempio i bug di cablaggio (ad esempio un'istanza di classe A riceve inaspettatamente un'istanza nulla di B) e bug di ambiente (funziona bene sulla mia macchina a CPU singola, ma il mio la macchina a 4 core del collega non può superare i test). Lo svantaggio principale è che i test di integrazione toccano più codice, sono meno affidabili, i guasti sono più difficili da diagnosticare e i test sono più difficili da mantenere.

Inoltre, i test di integrazione non dimostrano necessariamente che funzioni complete. L'utente potrebbe non preoccuparsi dei dettagli interni dei miei programmi, ma lo faccio!

Test funzionali

I test funzionali verificano la correttezza di una particolare funzionalità confrontando i risultati per un determinato input con le specifiche. I test funzionali non riguardano se stessi con risultati intermedi o effetti collaterali, ma solo il risultato (a loro non importa che dopo aver fatto x, l'oggetto y abbia lo stato z). Sono scritti per testare parte delle specifiche, ad esempio "chiamando la funzione Square (x) con l'argomento 2 restituisce 4".

Test di accettazione

Il test di accettazione sembra essere diviso in due tipi:

Il test di accettazione standard prevede l'esecuzione di test su tutto il sistema (ad es. Utilizzo della pagina Web tramite un browser Web) per verificare se la funzionalità dell'applicazione soddisfa le specifiche. Ad esempio "facendo clic sull'icona di uno zoom si dovrebbe ingrandire la vista del documento del 25%". Non esiste un vero continuum di risultati, solo un risultato positivo o negativo.

Il vantaggio è che i test sono descritti in un inglese semplice e garantisce che il software, nel suo insieme, sia completo. Lo svantaggio è che hai spostato di un altro livello la piramide dei test. I test di accettazione toccano montagne di codice, quindi rintracciare un fallimento può essere complicato.

Inoltre, nello sviluppo agile del software, i test di accettazione dell'utente comportano la creazione di test per rispecchiare le storie degli utenti create da / per il cliente del software durante lo sviluppo. Se i test superano, significa che il software deve soddisfare i requisiti del cliente e le storie possono essere considerate complete. Una suite di test di accettazione è fondamentalmente una specifica eseguibile scritta in una lingua specifica del dominio che descrive i test nella lingua utilizzata dagli utenti del sistema.

Conclusione

Sono tutti complementari. A volte è vantaggioso concentrarsi su un tipo o evitarli del tutto. La differenza principale per me è che alcuni dei test guardano le cose dal punto di vista di un programmatore, mentre altri usano un focus cliente / utente finale.


19
+1. @Mark Simpson I test funzionali e di accettazione potrebbero essere riassunti come "test di sistema"? Dove si inseriscono i test end-to-end? (troppo vocabolario troppo diverso per i miei gusti)
Torsten Engelbrecht

3
@Franz Stavo parlando della capacità e della facilità con cui è possibile ridurre il rischio isolando le unità di codice e testandole. Hai ragione però, il linguaggio che ho usato era un po 'sciolto, poiché i test non possono dimostrare che il codice sia privo di bug.
Mark Simpson l'

15
Nonostante i voti positivi, questo è completamente sbagliato. I test unitari non testano nemmeno i collaboratori "banali"; qualsiasi dipendenza iniettata deve essere derisa. I test funzionali non testano il "comportamento"; testano solo la "funzione", ovvero "f (A) restituisce B". Se gli effetti collaterali sono importanti, è "comportamentale". Se questi includono chiamate di sistema, sono anche test di "sistema", come nei "test di sistema comportamentali". (Vedi testerab @ sotto.) I test di "accettazione" sono un sottoinsieme di "test di sistema comportamentale" che coprono l'intero stack. "Integrazione" verifica verso l'alto, simulando l'utilizzo effettivo; verifica che tutte le dipendenze possano essere integrate nella pratica.
cdunn2001

7
@ cdunn2001: non ti preoccupare, le critiche costruttive sono sempre buone :) Il tuo commento mi ha insegnato alcune cose che non sapevo e ha ripulito la mia terminologia. Sono sempre desideroso di apprendere nuove cose dagli sviluppatori che desiderano testare. Ricordo la prima volta che ho scoperto il blog di Miško Hevery - è stato come un tesoro :)
Mark Simpson

11
@MarkSimpson anche se la tua risposta è molto buona, vorrei un po 'più di dettaglio riguardo ai test funzionali. Voglio dire, nella tua risposta, per me, è difficile distinguere tra test funzionali e test unitari. Spero che tu abbia tempo per questo, continua così!
Andrei Sandulescu,

90

L'importante è che tu sappia cosa significano quei termini per i tuoi colleghi. Diversi gruppi avranno definizioni leggermente diverse di ciò che significano quando dicono test "end-to-end" completi, per esempio.

Di recente mi sono imbattuto nel sistema di denominazione di Google per i loro test e mi piace piuttosto: ignorano gli argomenti semplicemente usando Small, Medium e Large. Per decidere in quale categoria rientra un test, prendono in considerazione alcuni fattori: quanto tempo richiede l'esecuzione, accede alla rete, al database, al filesystem, ai sistemi esterni e così via.

http://googletesting.blogspot.com/2010/12/test-sizes.html

Immagino che la differenza tra Small, Medium e Large per il tuo posto di lavoro attuale possa variare da quella di Google.

Tuttavia, non si tratta solo di portata, ma di scopo. Il punto di Mark sulle diverse prospettive per i test, ad esempio programmatore vs cliente / utente finale, è davvero importante.


6
+1 per la cosa di denominazione dei test di Google in quanto aiuta a dare un po 'di prospettiva sul perché varie organizzazioni / persone hanno definizioni diverse per i test.
Mark Simpson,

Questo è anche un bell'articolo che spiega perché dovresti usare diversi livelli di test e cosa ne ottieni: kentcdodds.com/blog/unit-vs-integration-vs-e2e-tests
testerab

63

http://martinfowler.com/articles/microservice-testing/

Il post sul blog di Martin Fowler parla delle strategie per testare il codice (specialmente in un'architettura di micro-servizi) ma la maggior parte si applica a qualsiasi applicazione.

Citerò dalla sua diapositiva di riepilogo:

  • Test unitari: esercita i più piccoli software testabili nell'applicazione per determinare se si comportano come previsto.
  • Test di integrazione: verifica i percorsi di comunicazione e le interazioni tra i componenti per rilevare i difetti di interfaccia.
  • Test dei componenti: limitare l'ambito del software esercitato a una parte del sistema in prova, manipolando il sistema attraverso interfacce di codice interne e utilizzando doppi test per isolare il codice in prova da altri componenti.
  • Prove contrattuali: verificare le interazioni al limite di un servizio esterno affermando che soddisfa il contratto previsto da un servizio di consumo.
  • Test end-to-end: verifica che un sistema soddisfi i requisiti esterni e raggiunga i suoi obiettivi, testando l'intero sistema, da un capo all'altro.

A proposito, questo è un ottimo articolo. Tuttavia, non capisco completamente a cosa servano i test di contratto. Non sono ridondanti alla luce dei test sui componenti e sull'integrazione?
Wheleph,

In alcune lingue (che utilizza Mr Fowler) è possibile implementare un'interfaccia non esposta quando si utilizza la definizione standard di una classe, ad esempio void IMyInterface.MyMethod (). Che a sua volta avrebbe logicamente i propri test. Anche se a quel punto stai tornando indietro verso BDD .. Che ironicamente anche il signor Fowler ha avuto una presa di terra.
Skarsnik,

2
non è l'articolo di Fowler a proposito, appena pubblicato lì. I test di contratto sono test che vengono effettuati dopo che i clienti iniziano a utilizzare il servizio, quindi si scrivono test che controllano se non si è rotto qualcosa per quel particolare cliente, ovvero si cambia l'API del servizio.
Rafał Łużyński,

L'unità @wheleph, i test di integrazione e dei componenti parlano principalmente per gli interni del software che sono pesantemente controllabili dallo sviluppatore. Un problema nei primi tre significa cambiare l'origine per risolvere il problema. - I test di contratto toccano ciò che ti è stato promesso in termini di funzionalità, ma potresti non essere in grado di cambiare direttamente a causa di un difetto. Ciò richiede l'aggiunta di codice di supporto per aggirare quei possibili problemi invece di correggere semplicemente il difetto. - Quindi aggireresti un servizio web che ti restituisce json malformato anche se le specifiche del contratto ti dicevano che aveva una certa struttura.
Yemi Bedu,

31

Test unitari - Come suggerisce il nome, questo metodo verifica a livello di oggetto. I singoli componenti software sono testati per eventuali errori. La conoscenza del programma è necessaria per questo test e i codici di test vengono creati per verificare se il software si comporta come previsto.

Test funzionali - Viene eseguito senza alcuna conoscenza del funzionamento interno del sistema. Il tester tenterà di utilizzare il sistema semplicemente seguendo i requisiti, fornendo input diversi e testando gli output generati. Questo test è anche noto come test a scatola chiusa o scatola nera.

Test di accettazione : si tratta dell'ultimo test condotto prima che il software venga consegnato al client. Viene eseguito per garantire che il software sviluppato soddisfi tutti i requisiti del cliente. Esistono due tipi di test di accettazione: uno che viene eseguito dai membri del team di sviluppo, noto come test di accettazione interno (test Alpha) e l'altro che viene eseguito dal cliente o dall'utente finale noto come (beta test)

Test di integrazione : i singoli moduli già sottoposti a test di unità sono integrati tra loro. Generalmente vengono seguiti i due approcci:

1) Top-Down
2) Bottom-Up


Cosa intendi con top-down e bottom-up? Il test di integrazione è uguale al test end-to-end?
tamj0rd2,

18

Questo è molto semplice

  1. Test unitari: sono i test effettivamente eseguiti dagli sviluppatori con conoscenze di codifica. Questo test viene eseguito in fase di codifica ed è parte del test in white box. Quando un software arriva per lo sviluppo, viene sviluppato nel pezzo di codice o sezioni di codice noto come unità. E i test individuali di queste unità hanno chiamato test unitari eseguiti dagli sviluppatori per scoprire alcuni tipi di errori umani come la mancanza di copertura delle dichiarazioni, ecc.

  2. Test funzionali: questo test viene eseguito durante la fase di test (QA) ed è parte del test black box. L'esecuzione effettiva dei casi di test scritti in precedenza. Questo test viene effettivamente eseguito dai tester, trovano il risultato effettivo di qualsiasi funzionalità nel sito e confrontano questo risultato con il risultato previsto. Se hanno trovato qualche disparità, questo è un bug.

  3. Test di accettazione: noto come UAT. E ciò è stato effettivamente fatto dal tester, nonché da sviluppatori, team di gestione, autore, scrittori e tutti coloro che sono coinvolti in questo progetto. Per garantire che il progetto sia finalmente pronto per essere consegnato senza bug.

  4. Test di integrazione: le unità di codice (spiegate al punto 1) sono integrate tra loro per completare il progetto. Queste unità di codice possono essere scritte in diverse tecnologie di codifica o possono avere versioni diverse, quindi questo test viene eseguito dagli sviluppatori per garantire che tutte le unità del codice siano compatibili con altre e che non vi siano problemi di integrazione.


1
@OlegTsyba la risposta è arrivata 4 anni dopo la risposta alla domanda.
bentesha,

1
Non dovremmo mai iniziare una risposta con "Questo è molto semplice", soprattutto se si tratta di un argomento complesso come questo.
milosmns

6

Sono nuovo al test del codice. I test unitari sembrano principalmente una perdita di tempo. Pensavo di fare test di unità ma stavo facendo test di integrazione e poi ho letto di test di unità e sembra sciocco, forse per le persone con poca esperienza? C'è una possibilità che mi manchi una specie di punto.
PixMach

Se l' unità è definita in senso lato, allora si sta eseguendo correttamente il test dell'unità. Mi oppongo ai dettagli di implementazione dei test. Una classe privata non dovrebbe essere "unit-test". Tuttavia, se hai diverse classi pubbliche, potresti essere tentato di deriderne una mentre ne provi un'altra. Questo è il vero dibattito. L' Unità (a) è la tua intera biblioteca? (b) ogni classe pubblica all'interno della biblioteca? O (c), ogni metodo pubblico all'interno di ogni classe? Preferisco testare una determinata libreria come componente integrato, ma deridere o falsare dipendenze esterne (a meno che non siano veloci e affidabili). Quindi penso di essere con te.
cdunn2001,

1
@PixMach: in realtà è il contrario. Non avere (buoni) test unitari in atto, ti fa perdere molto tempo, se tu (o qualcun altro) dovessi cambiare quel codice in futuro. Se hai esperienza nel mantenere il codice con e senza unit test, conoscerai la differenza. L'idea è che se un test unitario si interrompe, dovresti sapere esattamente quale parte del codice deve essere corretta. I test di accettazione / integrazione su larga scala spesso ti dicono solo: non funziona. E poi devi iniziare il debug della vecchia scuola ...
Goodsquirrel

@Goodsquirrel, dipende da ciò che chiami "unità". Questo è il problema. I test errati verranno eliminati durante il refactoring. I buoni test saranno ancora utili. I test non validi non aggiungono alcun valore e si frappongono. I buoni test sono auto-documentati e molto apprezzati. Diventiamo specifici. Ho un metodo privato per restituire un valore se un altro valore è True, altrimenti un valore predefinito. (Codice legacy.) Questo metodo dovrebbe essere testato? Dico di no Un altro metodo privato restituisce l'ennesimo numero di Fibonacci. Dovrebbe essere testato? Io dico si.
cdunn2001,

1
Il più piccolo codice esposto . Grande differenza.
cdunn2001,

5

Ti spiegherò questo con un esempio pratico e senza roba teorica:

Uno sviluppatore scrive il codice. Nessuna GUI è ancora implementata. Il test a questo livello verifica che le funzioni funzionino correttamente e che i tipi di dati siano corretti. Questa fase di test si chiama Unit testing.

Quando viene sviluppata una GUI e l'applicazione viene assegnata a un tester, verifica i requisiti aziendali con un client ed esegue i diversi scenari. Questo si chiama test funzionale. Qui stiamo mappando i requisiti del cliente con i flussi delle applicazioni.

Test di integrazione: supponiamo che la nostra applicazione abbia due moduli: risorse umane e finanza. Il modulo HR è stato consegnato e testato in precedenza. Ora la finanza è sviluppata ed è disponibile per il test. Le funzionalità interdipendenti sono ora disponibili anche, quindi in questa fase testerai i punti di comunicazione tra i due e verificherai che funzionino come richiesto nei requisiti.

Il test di regressione è un'altra fase importante, che viene eseguita dopo ogni nuovo sviluppo o correzione di errori. Il suo scopo è verificare funzioni precedentemente funzionanti.


1
"Uno sviluppatore scrive il codice. Nessuna GUI è ancora implementata. Il test a questo livello verifica che le funzioni funzionino correttamente e che i tipi di dati siano corretti. Questa fase del test si chiama Unit testing" Questo non è vero. La GUI è in realtà solo un "plug-in". Puoi già scrivere test E2E nell'output dell'API. (o qualsiasi oggetto di risposta generato)
user3790897

4

unit test: test di singoli moduli o componenti indipendenti in un'applicazione sono noti per essere unit test, i test unitari saranno eseguiti dallo sviluppatore.

test di integrazione: combinando tutti i moduli e testando l'applicazione per verificare che la comunicazione e il flusso di dati tra i moduli funzionino correttamente o meno, questo test viene eseguito anche dagli sviluppatori.

test funzionale che verifica la funzionalità individuale di un'applicazione è un test funzionale

test di accettazione questo test viene eseguito dall'utente finale o dal cliente, indipendentemente dal fatto che l'applicazione di compilazione sia conforme ai requisiti del cliente e che le specifiche del cliente siano note come test di accettazione

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.