2013-04-02 12 views
7

Attualmente sto studiando come dovremmo eseguire i nostri test in un progetto imminente. Per trovare i bug all'inizio del processo di sviluppo, gli sviluppatori scriveranno test di unità prima del codice effettivo (TDDish). I test unitari si concentreranno, come dovrebbero, sull'unità (un metodo in questo caso) in isolamento, quindi le dipendenze saranno prese in giro ecc.Transizione efficace dalle prove delle unità ai test di integrazione

Ora, vorrei anche testare queste unità quando interagiscono con altre unità e stavo pensando che ci dovrebbe essere una buona pratica efficace per fare questo poiché i test unitari sono già stati scritti. Il mio pensiero è che i test unitari saranno riutilizzati ma gli oggetti derisi saranno rimossi e sostituiti con quelli reali. Le idee diverse che ho adesso sono:

  • Utilizzare una bandiera globale in ciascuna classe di test che decida se utilizzare o meno oggetti fittizi. Questo approccio richiederà diverse istruzioni if
  • Utilizzare una classe factory che crea un "instanceWithMocks" o "instanceWithoutMocks". Questo approccio potrebbe essere problematico per i nuovi sviluppatori da utilizzare e richiede alcune classi aggiuntive
  • Separare i test di integrazione dai test di unità in classi diverse. Ciò però richiede un sacco di codice ridondante e mantenere i casi di test sarà il doppio del lavoro

Il mio modo di vedere tutti questi approcci hanno vantaggi e svantaggi. Quale di questi sarebbe preferibile e perché? E c'è un modo migliore per passare efficacemente dai test unitari ai test di integrazione? O è fatto di solito in qualche altro modo?

risposta

1

Accetto la maggior parte delle altre risposte, che l'univesting deve essere separato da integrationtesting (opzione 3).

Ma io non sono d'accordo alle vostre argomentazioni controindicazioni:

[...] Questo (unità separa dal test di integrazione) sarà comunque richiedono un sacco di codice ridondante e mantenere i casi di test sarà due volte il lavoro.

Generazione di oggetti con i dati di test può essere un sacco di lavoro, ma questo può essere riscritta per test-helper CLASES aka ObjectMother che può essere utilizzato da unità e test di integrazione quindi non c'è bisogno di ridondanza ci

Nei test unitari si controllano le diverse condizioni della classe sotto test.

Per il test di integrazione, non è necessario ricontrollare tutti questi casi speciali. Invece si controlla che i componenti funzionino insieme.

Esempio

Si può avere unità di test per 4 diverse situazioni in cui viene generata un'eccezione. Per l'integrazione non è necessario testare nuovamente tutte e 4 le condizioni Un test di integrazione relativo alle eccezioni è sufficiente per verificare che il sistema integrato possa gestire le eccezioni.

1

Un contenitore IoC come Ninject/Autofac/StructureMap può essere utile per voi qui. I test unitari possono risolvere il sistema sotto test attraverso il contenitore, ed è semplicemente una questione di registrazione se si hanno mock o oggetti reali registrati. Simile al tuo approccio di fabbrica, ma il contenitore IoC è la fabbrica. I nuovi sviluppatori avrebbero bisogno di un po 'di formazione per capire, ma questo è il caso di qualsiasi sistema complesso. Lo svantaggio di questo è che gli scenari di registrazione possono diventare piuttosto complicati, ma è difficile dire per un dato sistema se sarebbero anche complicato senza provarlo. Sospetto che questa sia la ragione per cui non hai trovato risposte che sembrano definitive.

5

vorrei andare per la terza opzione

  • separato i test di integrazione dei test di unità in diversi classi. Ciò però richiede un sacco di codice ridondante e mantenendo i test sarà il doppio del lavoro

Questo è perché i test unitari e test di integrazione hanno scopi diversi. Un test unitario mostra che un singolo pezzo di funzionalità funziona isolatamente. Un test di integrazione mostra che diverse funzionalità funzionano ancora quando interagiscono tra loro.

Quindi per un test di unità si vuole prendere in giro le cose in modo che si sta solo testando l'un pezzo di funzionalità.

Per un test di integrazione simulare il meno possibile.

Li avrei in progetti separati. Ciò che funziona bene al mio posto è di avere un progetto di unit test usando NUnit e Moq. Questo è scritto TDD mentre il codice è scritto.I test di integrazione sono Specflow/Selenium e i file delle funzionalità vengono scritti con l'aiuto del proprietario del prodotto nella sessione di pianificazione, in modo che possiamo verificare che stiamo offrendo ciò che il proprietario desidera.

Questo crea lavoro extra a breve termine, ma porta a meno bug, manutenzione più semplice e requisiti di corrispondenza di consegna.

1

I test di integrazione devono essere di classi diverse rispetto ai test di unità poiché si sta verificando un comportamento diverso. Il modo in cui penso ai test di integrazione è che sono quelli che esegui quando cerchi di fare in modo che tutto funzioni insieme. Utilizzerebbero gli input per porzioni dell'applicazione e assicurandosi che l'output previsto venga restituito.

1

Penso che si stia rovinando lo scopo dei test unitari e di integrazione. Il test delle unità è per testare una singola classe - questa è un'API di basso livello. Il test di integrazione sta testando come le classi cooperano. Questa è un'altra API di livello superiore. Normalmente, non è possibile riutilizzare i test unitari nei test di integrazione poiché rappresentano un diverso livello di visualizzazione del sistema. L'utilizzo del contesto di primavera può essere d'aiuto nella configurazione dell'ambiente per i test di integrazione.

1

Non sono sicuro che riutilizzare i test di unità con oggetti reali anziché con i mock è l'approccio giusto per implementare i test di integrazione.

Lo scopo di un test di unità è quello di verificare la correttezza di base di un oggetto in isolamento dal mondo esterno. I mazzi sono lì per assicurare quell'isolamento. Se li sostituisci per implementazioni reali, in realtà finirai per testare qualcosa di completamente diverso - la correttezza di grandi porzioni della stessa catena di oggetti, e la testerai in modo ridondante molte volte.

Effettuando test di integrazione distinti dai test di unità, sarete in grado di scegliere le parti del sistema che volete verificare - generalmente, è una buona idea testare parti che implicano la configurazione, I/O, interazioni con terzi -party sistemi, l'interfaccia utente o qualsiasi altra cosa che i test unitari hanno difficoltà a coprire.

Problemi correlati