Il test di integrazione dovrebbe offrire più valore dei test unitari? [duplicare]

3

Per fare questa domanda ho bisogno di definire un paio di termini per garantire che tutti quelli che lo leggono si trovino sulla stessa pagina:

  • Il test delle unità è il test di una singola classe con tutte le dipendenze fittate / stubbate in qualche modo.
  • Test di integrazione, in questo contesto, significa integrazione di una selezione di oggetti all'interno di un sistema con alcune potenziali dipendenze derise. Ad esempio, i collaboratori esterni (come un database o una terza parte remota) possono essere falsi, ma i sistemi interni possono anche essere derisi (ad esempio, deridere il meccanismo di autenticazione per funzionare sempre). L'idea è di far ruotare alcune parti del sistema non banali e verificare che si comporti.
  • Il test funzionale sta facendo girare il sistema nel suo insieme e lo spinge a raggiungere i risultati desiderati. Ai fini di questa domanda, potrebbe essere contrario al confronto esterno reale

Dal punto di vista della piramide di test, dovremmo avere un 70% di integrazione dall'unità del 20% al 10% di test funzionali.

Con quanto sopra esposto, la mia domanda è la seguente: ho lavorato in ambienti in cui esiste una vasta suite di test unitari, ma i bug continuano ad emergere in fase di esecuzione a causa di test di integrazione insufficienti / test funzionali inesistenti. Anche con un'eccellente copertura unitaria di una data classe come quella classe viene effettivamente utilizzata / come è cablata nel resto del sistema in genere contiene più bug di quelli che si possono realmente catturare a livello di unità. Di solito questi bug vengono rilevati a livello di test di integrazione / funzionalità.

Garantito dai test unitari è possibile inserire il sistema in più stati e tendono a funzionare molto più rapidamente ma, come rilevatore di bug, cadono rispetto a test di integrazione / livello funzionale che guidano effettivamente i percorsi del codice. Quando sollevo questo punto con gli altri la solita risposta è quella di dire "oh, i test di integrazione sono in realtà trovare test unitari che non hai scritto!", Questo sembra valido a prima vista, ma tutto ciò significa che sto testando il mio codice due volte: una volta a livello di integrazione con copertura completa e una volta a livello di unità in cui non è possibile garantire il livello di copertura. Tuttavia ho bisogno di mantenere entrambi i set.

La mia domanda è se la configurazione del test di integrazione è ridotta al minimo / astratta in una libreria di installazione di test comune, allora perché non usare i test di integrazione come "prima linea" di test sui test unitari? Qual è il valore effettivo di testare tutto due volte?

    
posta ahjmorton 04.10.2017 - 16:01
fonte

3 risposte

5

Questa è la cosa A. Cosa A dà 2 quando gli chiedi il conteggio dopo aver cliccato due volte. Sai cosa A funziona così perché hai appena visto il codice che lo ha fatto fare e l'hai visto fare. Ti senti come se capissi cosa A dovrebbe essere senza nemmeno dover guardare dentro.

Ecco il sistema abcxyz. Quando viene avviato genera una gif che sembra un contachilometri (o una tabellone segnapunti o una visualizzazione del numero di Take-a-Number). Può essere configurato in molti modi selvaggi e meravigliosi. Ma guardando il codice di test di integrazione che lo esercita ... beh ... ci vuole un po 'per capire cosa si aspetta, cosa lo fa contare, dove sta ottenendo queste immagini. Pensi di sapere cosa dovrebbe essere, ma nel momento in cui vai a fare cambiamenti ti rendi conto che devi capire cosa sta usando abcxyz un po 'di più. Quindi guardi il resto del sistema. Continua a leggere ... e leggi ... sospiro ...

Mi piace avere entrambi i test. Mi piace la fiducia che un test unitario mi dà che capisco ciò che l'autore ha davvero pensato fosse importante per A. Quello che l'autore pensava che il mondo esterno si sarebbe aspettato. In realtà trovo i test unitari ben fatti più facili da leggere quindi la definizione della classe.

Mi piace girarmi e usarlo per informare la mia comprensione dei test di integrazione. Farlo senza test unitari ti sembrerà di mangiare la tua cena da 4 portate dopo che è stata messa in un frullatore. Puoi farlo. Ma schifo.

E questo è proprio come leggere il codice, figuriamoci toccarlo.

Non fidarti mai di cose che rendono il codice di scrittura facile da dire su come scrivere codice che sia facile da leggere.

    
risposta data 04.10.2017 - 23:20
fonte
4

Si tratta di uno sviluppo dall'alto verso il basso o dal basso verso l'alto. Quando costruisci una grande macchina, costruisci prima l'intero sistema e poi lo collaudi nel suo insieme, oppure sviluppi e collaudi individualmente ciascun componente prima di assemblare il tutto? La risposta corretta è che tu faccia entrambe le cose. Certamente è necessario testare il sistema nel suo insieme, ma ci sono anche numerosi vantaggi nel testare i componenti individualmente:

  • Puoi sviluppare componenti singolarmente e in parallelo.
  • Scopri gli errori in precedenza (non devi aspettare fino a quando tutta la macchina non è terminata prima del test).
  • È molto più facile individuare l'errore durante il test dei singoli componenti.
  • È possibile testare casi limite e condizioni di errore che potrebbero essere impossibili da replicare nel sistema nel suo complesso (a causa di altre misure di sicurezza).
  • I test sono molto più semplici da scrivere.
  • Test dei componenti individualmente ti costringe a progettare ogni componente con un'interfaccia e un comportamento ben definiti e un numero minimo di dipendenze.
risposta data 04.10.2017 - 16:58
fonte
2

Il vantaggio del crescente livello di dettaglio dei test è che possono identificare il problema esatto, piuttosto che l'esistenza di un problema.

Inoltre, dovresti riflettere sui requisiti dei test e sulla definizione dei requisiti per le singole parti del sistema che potresti testare unitamente.

Ad esempio, supponiamo di avere un BasketPriceCalculator che restituisce il prezzo dei panieri di prodotti in base a offerte e cose. Se metto un unit test per l'offerta 2 per 1 e fallisce, so che c'è un problema con quell'offerta in quella classe. Dove l'integrazione o il test funzionale equivalenti potrebbero fallire se qualsiasi componente della sua catena fallisce.

Inoltre, potrei avere un requisito specificato che il BasketPriceCalculator genera un errore se ci sono più di 7 articoli nel carrello. Vorrei testare questo requisito senza includere le dipendenze, perché è specifico per quel componente, non per il prodotto nel suo complesso, che potrebbe gestire l'errore e prendere qualche altra azione.

Nel complesso sono d'accordo con te. I test di integrazione sono più importanti dei test di unità e non c'è davvero una ragione per cui non si dovrebbero eseguire tutti i test di unità con derisioni derisorie e dipendenze reali. Che faccio con i test basati sui dati.

I test funzionali sono ancora più importanti e anche in questo caso, anche se sono lenti a funzionare, non c'è davvero una ragione per non eseguire tutti gli scenari possibili come un test funzionale. Dopo che tutti i tuoi utenti lo faranno.

Ma in pratica, quando sviluppi qualcosa da zero, non inizi con un'applicazione funzionante per cui puoi scrivere un test funzionale. si inizia con un piccolo componente che calcola il prezzo di un paniere in base ad alcune regole che sono state date. Quindi scrivi prima i test unitari per quel bit.

    
risposta data 04.10.2017 - 16:27
fonte

Leggi altre domande sui tag