2013-07-26 18 views
5

Dopo aver letto il software orientato agli oggetti in crescita guidato dai test, ho appreso dell'isolamento del test e della fragilità del test. L'idea che ogni test dovrebbe essere molto specifico per un pezzo di codice o funzionalità e la sovrapposizione della copertura del codice con i test dovrebbe essere ridotta al minimo. L'ideale implicito che ogni modifica del codice dovrebbe comportare la rottura di un solo test. Evitare di passare il tempo trascorso attraverso più test non funzionanti per confermare che una modifica è la causa e se viene riparata dalle modifiche del test.Cosa dovrebbe essere deriso per un test di integrazione?

Ora questo sembra abbastanza semplice per i test di unità, sono molto isolati per loro natura. Tuttavia, quando presentato dai test di integrazione, sembra difficile evitare di eseguire più test nell'esercitare gli stessi percorsi di codice, in particolare quando vengono eseguiti in aggiunta ai test delle unità.

Quindi la mia domanda è: quali sono le dipendenze da prendere in giro durante i test di integrazione? Dovrebbe essere deriso qualcosa? Si deve testare un singolo percorso di esecuzione e si devono prendere in giro tutti gli effetti collaterali non direttamente rilevanti per questo percorso di codice?

Mi sto prendendo gioco dell'idea di eseguire test di integrazione pairwise. Prova una relazione tra due oggetti e prendi in giro tutto il resto. Quindi i cambiamenti in uno di questi oggetti dovrebbero avere un impatto minimo su altri test di integrazione, oltre a formare una catena completa di test end-to-end per mezzo di coppie.

Grazie per qualsiasi info ..

Modifica: tanto per chiarire, praticamente sto chiedendo: "Come devo fare per evitare un gran numero di non superano le prove integrazioni durante il normale corso dello sviluppo?". Il che presumo si ottiene usando dei mock, e perché ho chiesto a cosa deridere.

Aggiornamento: ho trovato un discorso molto interessante sui test di integrazione di J.B.Rainsberger, che ritengo risponda abbastanza bene, anche se forse un po 'controverso. Il titolo è "I test di integrazione sono una truffa", quindi, come puoi intuire, non difende affatto i test di integrazione (test di tipo end-to-end). L'argomento è che i test di integrazione saranno sempre molto al di sotto della quantità necessaria per testare accuratamente le possibili interazioni (a causa dell'esplosione combinatoria) e potrebbero dare una falsa sicurezza. Invece lui raccomanda ciò che chiama test di collaborazione e test di contratto. È un discorso di 90 minuti e sfortunatamente la lavagna non è molto chiara e non ci sono esempi di codice, quindi mi sto ancora prendendo in giro. Quando avrò una chiara spiegazione lo scriverò qui! A meno che qualcun altro non mi picchi ..

Ecco un breve riepilogo dei test di contratto. Sembra asserzioni di tipo Design by Contract, che a mio avviso potrebbero/sarebbero implementate in un modello di interfaccia non virtuale in C++.

http://thecodewhisperer.tumblr.com/post/1325859246/in-brief-contract-tests

test di integrazione sono un discorso video di truffa: http://www.infoq.com/presentations/integration-tests-scam

Sommario:

test di integrazione sono una truffa. Probabilmente stai scrivendo il 2-5% dei test di integrazione che devi testare a fondo. Probabilmente sei il test di duplicazione dell'unità in tutto il luogo. I tuoi test di integrazione probabilmente si duplicano l'un l'altro dappertutto. Quando un test di integrazione fallisce, chissà cosa è rotto?Scopri l'attacco su due fronti che risolve il problema: test di collaborazione e test contrattuali.

+1

Mentre devo ancora leggere GOOS (vergogna su di me), sono abbastanza certo che non si tratta di test di integrazione quando dice che solo un test dovrebbe fallire per una modifica. –

+0

Vedo, quindi pensi che la fragilità del test si applichi maggiormente ai test unitari rispetto ai test di integrazione? I test di integrazione sarebbero considerati intrinsecamente più fragili e si prevede che falliscano più spesso? – NitrousUK

+1

No, al contrario. I test di integrazione testano un'immagine più ampia, quindi finché la funzionalità testata non cambia, non si suppone che falliscano. –

risposta

1

Per i test di integrazione si deve deridere l'importo minimo delle dipendenze per ottenere il lavoro di prova, ma non meno :-)

Dal momento che l'integrazione delle componenti del sistema è ovviamente la cosa che si desidera verificare durante i test di integrazione, è necessario utilizzare le implementazioni reali il più possibile. Tuttavia, ci sono alcuni aspetti che ovviamente si vogliono prendere in giro, dal momento che non si desidera che i test di integrazione inizino ad inviare per posta gli utenti, ad esempio. Quando non prendi in giro queste dipendenze, ovviamente fai finta troppo poco.

Ciò non significa che non si dovrebbe consentire a un test di integrazione di inviare mail, ma almeno si desidera sostituire il componente di posta con uno che invierà solo posta ad alcune caselle di posta interna di test.

+0

Il problema che ho è che, in teoria, potrei prendere in giro tutto e il test potrebbe funzionare. Come un test per diversi oggetti da collaborare per calcolare un valore, potrei semplicemente avere un finto restituire quel valore. Forse si potrebbe usare una sorta di approccio in stile TDD, per prendere in giro tutto, per farlo funzionare, quindi espandere gradualmente il test di integrazione fino a quando i mock non sono sufficienti e richiede codice reale, con la copertura del codice totale come obiettivo finale? Io donno ... mi dà il mal di testa a pensarci qualche volta – NitrousUK

+1

No, spedito, il software funzionante è l'obiettivo finale. :) Un livello ragionevolmente elevato di copertura del codice può aiutarti a "lavorare". Mirare al 100% non aiuta a spedire e può nuocere al "lavoro". –

+0

Se esiste un tale obiettivo come copertura totale, non è la copertura * codice * totale ma la copertura * funzionalità * totale, cioè ogni funzione è coperta dai test. –

1

I test di unità dovrebbero avere oggetti fittizi, ma i test di integrazione dovrebbero avere pochi o eventuali mock (altrimenti cosa si sta integrando?) Penso che sia eccessivo fare il mocking a coppie; ciò comporterà un'esplosione di test che potrebbero richiedere molto tempo e un sacco di codice copia e incolla che sarà difficile da modificare se i requisiti cambiano o se verranno aggiunte nuove funzionalità in un secondo momento.

Penso che non ci siano scherzi nei test di integrazione. Dovresti avere tutto deriso nei test unitari per sapere che ogni singola unità funziona come previsto in isolamento. Il test di integrazione verifica che tutto funzioni insieme.

+0

Il problema principale che sto cercando di risolvere è quando c'è un cambiamento valido, come si evita di avere un numero elevato di test di integrazione falliti? Senza derisioni, tutto ciò che tocca il cambiamento fallirà e richiederà attenzione. – NitrousUK

+0

A seconda di cosa è cambiato penso che sia una buona cosa che i test di integrazione falliscano. Se cambia un'interfaccia ad una delle dipendenze, il test di integrazione DOVREBBE fallire poiché stiamo testando che stiamo comunicando correttamente con le nostre dipendenze. – dkatzel

+0

Ma la mia domanda per voi sarebbe, quanti dovrebbero fallire? Qual è un numero accettabile?In teoria, se ci sono centinaia di test, e tutti fanno affidamento su alcuni componenti essenziali, come un database, allora se quel database cambia, forse centinaia di test potrebbero fallire. – NitrousUK

1

Per i test di integrazione mi propongo di prendere in giro il servizio piuttosto che la rappresentazione ad esempio utilizzando mirage anziché un'API REST di terze parti e Dumpster anziché un vero server SMTP.

Ciò significa che tutti i livelli del codice sono stati testati, ma nessuno dei terzi è stato testato in modo da essere libero di refactoring senza preoccuparsi che i test falliscano.

0

La discussione del modello di prova Contratto/Collaboratore (descritto da JB Rainsberger in "Test di integrazione è una truffa" menzionato nella domanda precedente). In relazione alla domanda qui - ho interpretato il suo discorso nel senso che quando si possiede il codice sia per il lato del servizio che per quello del client, non è necessario alcun test di integrazione. Invece dovresti essere in grado di fare affidamento su finte che implementano un contratto.

Il discorso è un buon riferimento per la descrizione di alto livello del modello ma non entra nei dettagli (almeno per me) su come definire o fare riferimento a un contratto da un collaboratore.

Un esempio comune della necessità del modello Contratto/Collaboratore è tra il server/client di un'API (di cui si possiede il codice di entrambi). Ecco come ho implementato è:

Definire il contratto:

prima definire lo schema API, se il vostro API utilizza JSON si potrebbe considerare JSONSchema. La definizione dello schema può essere considerata il "Contratto" dell'API.(E come nota a margine, se siete in procinto di farlo, assicurarsi di sapere su RAML o Swagger dal momento che in sostanza fanno scrivere API JSONSchema molto più facile)

Crea apparecchi che implementano il contratto:

  • Sul lato server, prendere in giro le richieste del client per consentire il test dell'unità delle richieste/risposte. Per fare ciò creerai dispositivi di richiesta del cliente (detti anche mock). Una volta definita l'API, convalidare i dispositivi contro JSONSchema per assicurarsi che siano conformi. Esistono molti validatori di schemi: attualmente utilizzo AJV (Javascript) e jsonschema (Python), ma la maggior parte delle lingue dovrebbe avere un'implementazione.

  • Sul lato client (s) è probabile che prendiate in giro le risposte del server per consentire il test dell'unità delle richieste. Segui lo stesso schema del server, convalidando le soluzioni di richiesta e risposta tramite JSONSchema.

Se sia il client e il server stanno convalidando i loro apparecchi contro il contratto, quindi ogni volta che le modifiche API contratto, l'scaduti implementazioni su entrambi i lati non riuscirà convalida JSONSchema e saprete è il momento di aggiornare i tuoi dispositivi e forse il codice che si basa su quegli impianti.

Problemi correlati