Test unitario automatizzato, test di integrazione o test di accettazione [chiuso]

29

TDD e test di unità sembrano essere il grande rave al momento. Ma è davvero così utile rispetto ad altre forme di test automatici?

Intuitivamente direi che i test di integrazione automatizzati sono molto più utili dei test unitari. Nella mia esperienza, la maggior parte dei bug sembra essere nell'interazione tra i moduli, e non tanto nella logica effettiva (usuale, limitata) di ciascuna unità. Anche le regressioni sono spesso avvenute a causa del cambiamento delle interfacce tra i moduli (e delle pre e post-condizioni modificate).

Sto fraintendendo qualcosa, o perché i test unitari stanno ottenendo una concentrazione così grande rispetto ai test di integrazione? È semplicemente perché si presume che il test di integrazione sia qualcosa che hai e il test unitario è la prossima cosa che dobbiamo imparare ad applicare come sviluppatori?

O forse il test unitario fornisce semplicemente il guadagno più elevato rispetto alla complessità di automatizzarlo?

Che esperienza hai con i test automatici delle unità, i test di integrazione automatizzati e i test di accettazione automatici e nella tua esperienza che cosa ha prodotto il ROI più elevato? e perché?

Se dovessi scegliere solo una forma di test da automatizzare nel tuo prossimo progetto, quale sarebbe?

Grazie in anticipo.

    
posta Bjarke Freund-Hansen 24.01.2011 - 13:25
fonte

7 risposte

34

Un fattore importante che rende estremamente utili i test unitari è feedback rapido .

Considera cosa succede quando la tua app è completamente coperta da test di integrazione / sistema / funzionale (che è già una situazione ideale, lontana dalla realtà nella maggior parte dei negozi di sviluppo). Questi sono spesso gestiti da un team di test dedicato.

  • Apporti una modifica al repository SCM,
  • qualche volta (probabilmente giorni) più tardi i ragazzi del test ricevono una nuova versione interna e iniziano a testarla,
  • trovano un bug e presentano una segnalazione di bug,
  • (nel caso ideale) qualcuno ti assegna il bug report

Tutto ciò potrebbe richiedere giorni o addirittura settimane. A questo punto hai già lavorato ad altre attività, quindi non hai i minimi dettagli del codice scritto in precedenza nella tua mente. Inoltre, in genere non hai alcuna prova diretta di dove sia effettivamente il bug, quindi ci vuole molto tempo per trovare e correggere il bug.

Mentre nel test unitario (TDD)

  • scrivi un test,
  • scrivi del codice per soddisfare il test,
  • il test fallisce ancora,
  • guardi il codice e in genere hai un'esperienza "oops" in pochi secondi (come "oops, ho dimenticato di controllare per quella condizione!"), quindi
  • correggi il bug immediatamente.

Tutto ciò accade in una questione di minuti .

Questo non vuol dire che i test di integrazione / sistema non siano utili; servono solo a scopi diversi. Con test unitari ben scritti puoi catturare una grande percentuale dei bug nel codice prima che arrivano alla fase di integrazione, dove è già molto più costoso trovarli e risolverli. Hai ragione che i test di integrazione sono necessari per catturare quei tipi di bug che sono difficili o impossibili da catturare con i test unitari. Tuttavia, nella mia esperienza quelli sono il tipo più raro; la maggior parte dei bug che ho visto sono causati da omissioni semplici o addirittura banali da qualche parte all'interno di un metodo.

Per non parlare del fatto che il test dell'unità verifica anche le interfacce per usabilità / sicurezza ecc., fornendo così un feedback di vitale importanza per migliorare il tuo design e le tue API. Quale IMHO può ridurre considerevolmente le possibilità di errori di integrazione di moduli / susbsystem: più un'API è più semplice e pulita, minori sono le possibilità di incomprensioni o omissioni.

What are you experience with automated unit testing, automated integration testing, and automated acceptance testing, and in your experience what has yielded the highest ROI? and why?

Il ROI dipende da molti fattori, probabilmente il più importante è se il tuo progetto è greenfield o legacy. Con lo sviluppo di greenfield il mio consiglio (e l'esperienza fino ad ora) è di fare un test di unità TDD dall'inizio. Sono fiducioso che questo sia il metodo più efficace in questo caso.

In un progetto legacy, tuttavia, la creazione di una copertura di test unitaria sufficiente è un'impresa enorme che sarà molto lenta a produrre benefici. Se possibile, è più efficiente cercare di coprire le funzionalità più importanti con test di sistema / funzionali tramite l'interfaccia utente. (Le applicazioni desktop GUI potrebbero essere difficili da testare automaticamente tramite la GUI, sebbene gli strumenti di supporto automatico per i test stiano gradualmente migliorando ...). Questo ti dà una rete di sicurezza grezza ma efficace rapidamente. Quindi puoi iniziare a costruire gradualmente i test unitari intorno alle parti più critiche dell'app.

If you had to pick just one form of testing to automated on your next project, which would it be?

Questa è una domanda teorica e la trovo senza senso. Tutti i tipi di test hanno il loro uso nella casella degli strumenti di un buon ingegnere SW, e tutti questi hanno scenari in cui sono insostituibili.

    
risposta data 24.01.2011 - 13:44
fonte
8

Tutti i tipi di test sono molto importanti e assicurano che i diversi aspetti del sistema siano specifici. Quindi, per lavorare all'indietro, "Se dovessi scegliere un tipo di test ..." non lo farei. Il test delle unità fornisce feedback diversi rispetto ai test di integrazione o ai test interattivi effettuati da una persona.

Ecco il tipo / vantaggio del test che facciamo:

  • Test delle unità: assicura che le unità eseguano il lavoro come ci aspettiamo che facciano. Testiamo sia i fornitori che i contratti dei consumatori per ogni interfaccia e questo è abbastanza facile da automatizzare. Controlliamo anche le nostre condizioni al contorno, ecc.
  • Test di integrazione - assicura che le unità lavorino insieme in concerto. Questo è principalmente per testare il nostro design. Se qualcosa si rompe qui, dobbiamo adattare i nostri test unitari per assicurarci che non accada di nuovo.
  • Test del sistema - assicura che il sistema soddisfi i requisiti / le specifiche. Di solito le persone fanno questo tipo di test.
  • Test di accettazione: il client esegue questa operazione per verificare che il prodotto finale faccia ciò che è pubblicizzato.

Test facoltativo ma consigliato:

  • Test dell'esperienza utente: mentre otteniamo un feedback decente dai test di sistema, l'anteprima di alcune pre-release da parte di persone dal client può davvero aiutare a determinare se è necessario modificare le cose prima che sia troppo tardi.

Giusto per capire perché il test unitario ha un vantaggio rispetto ai test di integrazione, devi capire gli ordini di grandezza di test addizionali che ti occorrono per essere completi. Per ogni risultato possibile per l'unità A, deve esserci un test. Lo stesso vale per l'unità B. Ora, se entrambi lavorano insieme per una soluzione più completa, il numero di test è combinatorio. In breve, per testare ogni permutazione di interazione tra l'unità A e l'unità B, sono necessari i test A * B. Aggiungi nell'unità C e il numero di test per il trio sarebbe A * B * C.

È qui che il concetto di interfacce e di confini degli oggetti diventa molto importante. Le interfacce rappresentano un determinato contratto. Un implementatore di un'interfaccia concorda che si comporterà in un certo modo. Allo stesso modo, un consumatore di un'interfaccia concorda che utilizzerà l'implementazione in un certo modo. Scrivendo un test che raccoglie tutte le classi che implementano un'interfaccia, è possibile verificare facilmente che ogni implementazione osservi i contratti dell'interfaccia. Questa è la metà dell'equazione. L'altra metà è quella di testare il lato del consumatore - che è dove gli oggetti finti entrano in gioco. La simulazione è configurata per garantire che le interazioni siano sempre nello specifico. A questo punto, tutto ciò che serve sono alcuni test di integrazione per assicurarci che i contratti implementatore / consumatore siano corretti.

    
risposta data 24.01.2011 - 14:34
fonte
3

Questi sono strumenti diversi con diversi obiettivi:

  • Il test delle unità è uno strumento di progettazione (TDD) e quasi un prerequisito per il refactoring.

  • I test di integrazione sono ottimi per visualizzare lo stato di avanzamento del progetto, oltre che per evitare i bug di regressione.

Il punto da ricordare è che non puoi davvero progettare con i test di integrazione e non troverai regressioni con i test unitari.

    
risposta data 24.01.2011 - 13:33
fonte
1

Ho usato Selenium estensivamente per i controlli di integrità.

In una grande casa editrice del web, quando è stata creata una nuova versione, in genere sono occorsi circa 3 tester circa un'ora o due per visitare tutte le famiglie di siti e assicurarsi che tutto fosse OK, secondo lo script di test. Con Selenium, siamo stati in grado di automatizzare i test e distribuirli su più macchine e browser. Attualmente, quando vengono eseguiti gli script di test, occorrono 3 PC per circa 10 minuti per fare automaticamente la stessa cosa E sputare un bel report.

Il bello del selenio è che puoi collegarlo a quadri di test unitari come XUnit, TestNG o MSTest.

Nella mia esperienza, è stato estremamente prezioso, tuttavia l'impostazione di qualcosa del genere dipende molto dal tuo progetto e dal tuo team, quindi il ROI varierà sicuramente.

    
risposta data 24.01.2011 - 15:27
fonte
1

Il miglior ROI di solito è il primo test che può trovare quel tipo di bug.

Il test delle unità dovrebbe trovare la maggior parte dei bug che si trovano in un solo metodo, o forse un componente. Trova bug che di solito possono essere risolti in pochi minuti, con tempi di risposta totali inferiori a un'ora. Test molto economici, bug MOLTO poco costosi da trovare e risolvere! Se questi bug hanno reso il test di integrazione, il turn-around potrebbe essere più simile a un giorno (le prove di test spesso si verificano ogni notte), supponendo che il bug non sia occluso da un altro bug; inoltre ci sono probabilmente più bug introdotti da quando è stato scritto un altro codice contro il codice buggy iniziale; più eventuali riprogettazioni avranno un impatto su più pezzi di codice. Inoltre, far passare più errori significa dover eseguire molte più esecuzioni di test prima che i test di integrazione possano essere completati. I test di unità scadenti sono spesso al centro di lunghi, onerosi, costosi cicli di integrazione del test. Saltare il test delle unità potrebbe dimezzare i tempi di sviluppo, ma il test richiederà da 4 a 4 volte di più, l'intero progetto raddoppierà di lunghezza e la qualità sarà inferiore se si eseguisse il test IME dell'unità.

Il test di integrazione è di solito il primo vero test che può trovare bug di integrazione (anche se i processi di revisione possono trovare alcuni bug prima che il software sia scritto, o prima che il codice vada a testare). Volete trovare questi bug prima di iniziare a mostrare il software all'utente o al rilascio, dal momento che la risoluzione dei bug all'ultimo momento (o hot-fix!) È molto costoso. Non è possibile trovare questi bug in precedenza, quando sarebbero più economici da sistemare, perché è necessario integrare più componenti di lavoro (per definizione). I test di integrazione vengono rallentati quando i bug che non hanno nulla a che fare con i pezzi interagenti (come errori minori) devono essere risolti prima di poter iniziare anche i test più interessanti.

I test di accettazione degli utenti assicurano che il software faccia ciò che il cliente desidera (anche se il cliente si spera sia stato coinvolto per tutto il tempo, per ridurre il rischio di trovare un enorme divario tra aspettative e software reale alla fine del progetto - Molto costoso!). Quando arrivi a questa fase di test, dovresti davvero credere che la maggior parte degli errori nel tuo prodotto, rispetto alle specifiche, siano già stati trovati. I test di accettazione degli utenti riguardano più che il prodotto si adatta alle esigenze del cliente piuttosto che assicurarsi che non ci siano errori rispetto alle specifiche.

Se solo automatizzassi un tipo di test, sarebbe un test unitario. I test di integrazione possono essere eseguiti manualmente e sono stati eseguiti da molte importanti aziende per anni. È più dispendioso in termini di tempo fare manualmente un lavoro che potrebbe essere fatto da un computer più e più volte, e molto più costoso per la maggior parte dei progetti, per non dire noioso e soggetto a errori, ma può essere fatto. I test di accettazione degli utenti sono spesso manuali, dal momento che gli utenti spesso non sanno come automatizzare i loro test mentre continuano a testare ciò che gli interessa. I test unitari DEVONO essere automatizzati. È necessario essere in grado di eseguire tutti i test delle unità in pochi secondi su richiesta con la frequenza richiesta ogni pochi minuti. Gli umani non riescono nemmeno ad avvicinarsi ai test manuali. Per non parlare del fatto che i test unitari sono nel codice e non possono essere eseguiti senza chiamarli tramite codice, cioè automatizzandoli. Il test delle unità manualmente è semplicemente impossibile.

Una cosa da tenere a mente è che questo è un forum principalmente per sviluppatori, non tester. I test di integrazione vengono principalmente implementati dai tester. Il test delle unità è implementato dagli sviluppatori. Naturalmente, gli sviluppatori parlano più dei test unitari rispetto ad altri tipi di test. Questo non significa che non pensano che altri test siano importanti. Significa semplicemente che in realtà non lo fanno (o lo fanno meno spesso).

    
risposta data 24.01.2011 - 20:46
fonte
1

Mi sento come se i test di accettazione fossero i primi in questo scenario.

Se un commit interrompe i test di accettazione, deve essere risolto.

I test di accettazione indicano dove si trova il tuo software, i test unitari no.

Pertanto i test unitari possono fornire un senso di sicurezza molto falso.

    
risposta data 27.11.2012 - 18:14
fonte
0

La domanda non è tanto più importante, quanto ciò che può essere automatizzato ed eseguito rapidamente.

I test unitari mostrano se un piccolo componente è adatto allo scopo in un modo particolare e in genere sono piccoli e veloci da eseguire. Essendo piccoli, di solito sono ragionevolmente facili da automatizzare.

I test di integrazione mostrano se i componenti funzionano insieme. Di solito sono molto più grandi e potrebbero non essere facili da automatizzare. Possono impiegare più tempo a correre. C'è un valore nel riuscire a eseguirli automaticamente, ma è un compito più grande e non verranno eseguiti così spesso.

I test di accettazione mostrano se un progetto è accettabile o meno. Questo è normalmente impossibile da automatizzare completamente (anche se i test automatici possono svolgere un ruolo), poiché è normalmente impossibile stabilire i requisiti esatti e completi in un problema formale che è meno complicato del codice sorgente stesso. I test di accettazione di solito includono i potenziali utenti che fanno cose con il sistema e osservano che i risultati sono soddisfacenti sotto tutti gli aspetti, che di solito è in parte soggettivo. Poiché i test di accettazione vengono generalmente eseguiti una sola volta (i clienti di solito desiderano eseguire autonomamente test di accettazione separati) non vale la pena automatizzare.

    
risposta data 24.01.2011 - 16:18
fonte

Leggi altre domande sui tag