In che modo i test di integrazione criticano il design?


38

Sto leggendo sul post del blog di JB Rainsberger sui test integrati e mi chiedo in che modo un test di integrazione è più duro con il nostro design?

Scriviamo più test integrati, che sono più grandi e non criticano il nostro design con la stessa severità con cui fanno i microtest


3
La domanda è confusa. "in che modo un test di integrazione è più duro" ... "test integrati, che sono più grandi e non criticano il nostro progetto così duramente" - e adesso?
AnoE,


"test di integrazione"! = "test integrato". Lo so. Neanche a me piace, ma è quello che significano quelle parole. "test di integrazione" = "test che controllano i punti di integrazione (senza integrare le cose)", mentre "test integrati" = "test (più grandi) che integrano le cose e controllano il tutto integrato come un'unica cosa". In questo modo, questi termini diventano opposti l'uno rispetto all'altro.
JB Rainsberger,

Risposte:


46

I microtest possono contribuire a un buon design . Scrivendo buoni piccoli test, stai deliberatamente testando una piccola quantità di codice e riempiendo i suoi spazi vuoti con oggetti finti . Ciò porta a un basso accoppiamento (le cose non dipendono l'una dall'altra) e ad un'elevata coesione (le cose che appartengono insieme rimangono insieme). In questo modo, quando torni indietro e apporti modifiche, è facile trovare ciò che è responsabile di ciò che stai cercando e hai meno probabilità di interrompere le cose nel fare il cambiamento. Questo non risolverà tutto il tuo design ma può aiutarti.

In questo contesto, JB Rainsberger sta notando che se hai difficoltà a scrivere un unit test, probabilmente hai un problema con il tuo design che sta causando la difficoltà, e quindi i test criticano implicitamente il design. Suppone che questa sia una buona cosa, perché senza i piccoli test aiutano a mantenere la tua architettura in linea è facile allontanarsi da buoni modelli di progettazione - che i test integrati non cattureranno.

Aggiornamento : come Rainsberger nota di seguito, non intendeva che i microtest fossero sinonimo di unit test. Ha anche fornito una risposta dettagliata che può darti un'idea più approfondita di ciò che stava comunicando.


2
Concordo con la tua risposta in linea di principio, ma non sul modo in cui la stai articolando. È improbabile che qualcuno che ponga questa particolare domanda sappia cosa significano i termini "beffardo", "accoppiamento" e "coesione" e non hai definito questi termini nella tua risposta.
Robert Harvey,

3
Va meglio, ma stai dando ai test unitari più credito di quanto penso siano effettivamente dovuti. I test unitari informano principalmente la testabilità del tuo codice. È meno chiaro se rendere testabile il tuo codice conferisca automaticamente migliori caratteristiche di coesione e accoppiamento, sebbene sia certamente un'influenza positiva. Inoltre, penso che tu abbia "l'alta coesione" confusa con il "principio della responsabilità singola"; coesione significa "cose ​​che appartengono insieme" (vedi l' articolo di Wikipedia ).
Robert Harvey,

10
Infine, "micro-test" non è il termine preferito. Adoro quando i blogger definiscono i propri termini tecnici.
Robert Harvey,

2
@RubberDuck: microtest (circa 16.900 risultati) vs test unitari (circa 193.000.000 di risultati) . Neanche vicino. Anche se si mescolano unità e test insieme si ottengono comunque 14 milioni di risultati.
Robert Harvey,

5
Per favore, non equiparare "microtest" e "unit test" (vedi la mia risposta per alcuni dettagli); altrimenti, ho l'impressione che tu abbia capito cosa ho cercato di descrivere.
JB Rainsberger,

28

La versione estremamente breve: test più piccoli, poiché eseguono parti più piccole del sistema, limitano naturalmente ciò che i programmatori possono scrivere, e quindi questo crea un'opportunità per un feedback più nitido (più facile da notare / più difficile da ignorare). Consentitemi di aggiungere che ciò non porta necessariamente a una progettazione migliore, ma piuttosto crea l'opportunità di notare prima i rischi di progettazione.

In primo luogo, per chiarire, quando dico "microtest" intendo "un piccolo test" e niente di più. Uso questo termine perché non intendo "unit test": non voglio essere coinvolto in dibattiti su ciò che costituisce una "unità". Non mi interessa (almeno non qui / ora). Due persone probabilmente si accorderanno più facilmente su "piccole" di quanto non farebbero su "unità", così ho gradualmente deciso di adottare "microtest" come termine standard emergente per questa idea.

Test più grandi, ovvero test che eseguono parti più grandi del sistema nella loro parte "azione", tendono a non criticare il progetto in modo chiaro né completo come i test più piccoli. Immagina l'insieme di tutte le basi di codice che potrebbero superare un determinato gruppo di test, il che significa che potrei riorganizzare il codice e passerebbe comunque quei test. Per test più grandi, questo set è più grande; per test più piccoli, questo set è più piccolo. Detto in altro modo, i test più piccoli limitano maggiormente il progetto, quindi un numero inferiore di progetti può farli passare. In questo modo, i microtest possono criticare maggiormente il design.

Dico "più duramente" per evocare l'immagine di un amico che ti dice direttamente ciò che non vuoi sentire, ma ha bisogno di sentire, e che ti urla per trasmettere urgenza in modo che le altre persone potrebbero non sentirsi a proprio agio facendo. I test integrati, d'altra parte, mantengono il silenzio e accennano ai problemi solo quando non hai più tempo né energia per affrontarli. I test integrati rendono troppo facile eliminare i problemi di progettazione sotto il tappeto.

Con test più grandi (come i test integrati), i programmatori tendono principalmente a mettersi nei guai attraverso la sciattezza: hanno abbastanza libertà di scrivere codice aggrovigliato che in qualche modo supera i test, ma la loro comprensione di quel codice svanisce rapidamente nel momento in cui passano all'attività successiva e altri hanno indebita difficoltà a leggere il design aggrovigliato. Qui sta il rischio di affidarsi a test integrati. Con test più piccoli (come i microtest), i programmatori tendono principalmente a mettersi nei guai a causa di specifiche eccessive: vincolano eccessivamente i test aggiungendo dettagli irrilevanti, di solito copiando / incollando dal test precedente, e così facendo si dipingono relativamente rapidamente in un angolo. Buone notizie: Trovo molto più semplice e sicuro rimuovere i dettagli estranei dai test dopo diverse ore o giorni dopo averli scritti di quanti ne trovo per separare il codice di produzione aggrovigliato mesi o anni dopo averlo scritto. Man mano che gli errori vanno, l'eccessiva specificazione fa più rapidamente danni sempre più evidenti e il programmatore di allerta vede in precedenza che devono riparare le cose. Lo considero un punto di forza: noto prima i problemi e li risolvo prima che tali problemi strozzassero la nostra capacità di aggiungere funzionalità.


Cosa fai riguardo al problema che i test unitari si basano più sui loro mock che sul codice reale, portando al problema dei test che sembrano passare ma che in realtà non funzionano perché nessuno ha mantenuto i mock in linea con la realtà.
Zan Lynx,


9

Vuol dire che una buona progettazione del software è meglio informata dai test unitari rispetto ai test di integrazione.

Ecco perché. La scrittura di unit test ti costringe a scrivere codice che è testabile in unità. Il codice unit-testable tende ad essere un design migliore rispetto al codice che non ha unit test.

I test di integrazione non informano il tuo codice allo stesso modo perché stai solo testando il livello esterno del tuo software, non le interfacce interne che collegano il tuo software insieme.

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.