2009-06-28 7 views
11

Ho letto nei blog che il database non deve essere colpito quando vengono eseguiti i test dell'unità. Capisco la teoria, tuttavia dico di avere procedure di archiviazione complesse che fanno parte di un'operazione di dominio aziendale. Voglio scrivere una serie di test unitari per il codice relativo all'operazione aziendale, tuttavia se sto prendendo in giro il database ho la sensazione che non sto "veramente" testando tutte le parti che fanno parte dell'operazione. Ad esempio, qualcuno potrebbe creare un bug in uno dei codici del database e i test continueranno a funzionare correttamente.Perché non colpire il database all'interno dei test unitari?

Mi piacerebbe sapere se questa linea guida sui test di unità è buona nella pratica. Ho visto il concetto di "test di integrazione", ma non sono sicuro di quali strumenti utilizzare per eseguire i test di integrazione. Ad esempio ¿È giusto creare un test di integrazione usando un framework di test come Nunit?

Grazie

Hugo

risposta

10

si sono semplicemente in una zona grigia semantica.

  • I test di sistema coprono l'intero sistema da end-to-end.
  • I test di unità possono essere utilizzati per descrivere un sottosegmento del ciclo end-to-end.

In questo caso il test di unità di codice dell'applicazione avrebbero/non potrebbero colpire il database, ma si sarebbe/potrebbe avere unit test che copriva il database delle procedure memorizzate ...

Fondamentalmente suddividere l'applicazione in cose da testare lungo partizioni che hanno senso. Se si sceglie la riga di partizione sbagliata si finisce con un grosso problema di manutenzione del codice con oggetti finti e collaudo di prova e cose ...

Un modo comune con le app Web è scrivere una serie di test unitari che testano l'accesso ai dati strato ...

Poi scrivere una serie di test di unità che verificano il livello di applicazione (compreso lo strato di dati) ...

infine scrivere alcuni test di sistema basati su browser ...

l' il trucco consiste nel mettere le informazioni dentro e fuori dal set centrale - il livello dell'applicazione - attraverso l'API e non scavare in il database per vedere se qualcosa ha funzionato. In questo modo i test non si interromperanno se si modifica lo schema dei dati.

Ma a volte (come attualmente sto facendo mentre scrivo questo) dovete esaminare il database per creare una suite di test significativa e significativa (sto testando i protocolli di trasferimento server-server).

Concentrarsi sul modo in cui ottenere la massima copertura del codice e stabilità per l'applicazione, mentre si scrive la quantità minima di scaffold di test ed evitare la fragilità nella suite di test.

+5

Non posso dirvi quante volte ho detto quasi la stessa identica cosa AL NOSTRO GRUPPO Q/A !!! Vedono un grande test e a volte non capiscono che ci sono delle dipendenze. Ho avuto un po 'di curvatura che non è possibile aggiungere lo stesso record più di una volta. Quindi devo convincerli che hanno bisogno di parti di setup e di smantellamento aggiunte ai loro test. (In che modo DARE un programmatore/programmatore basso dice loro come scrivere i test ) –

+0

che è fantastico i tuoi test di scrittura (anche se personalmente amo testare) – Chazt3n

0

Il problema rivolgendosi database nei test è che un cambiamento nel database o un cambiamento nel codice può fallire il test. Normalmente un test unitario dovrebbe puntare il più direttamente possibile al cambiamento che lo ha fatto fallire. Quindi, se si desidera testare il codice per l'accesso al DB, è possibile utilizzare un database di test fisso. In questo modo sei sicuro che il codice che accede al DB è sbagliato perché sai che il database non è cambiato e se vuoi cambiare la configurazione del DB cambia prima il DB di test e vedi il test fallito, quindi correggilo e poi cambia il non testare il DB. In un progetto in cui ho lavorato, abbiamo creato un piccolo database che è stato generato in memoria prima di ogni test.

0

"... il database non deve essere colpito quando l'unità esegue il test ..." - a meno che tu non stia testando gli oggetti di persistenza, naturalmente.

Non so a quali blog si sta citando, ma scommetto che quello che stanno dicendo è che prendersi gioco di alcuni componenti durante i test di integrazione può avere dei vantaggi. Se hai già testato l'unità del livello di persistenza, non è necessario testarlo di nuovo. Il vantaggio di deridere in quel caso ha più a che fare con la riduzione delle dipendenze e dell'incertezza. Ad esempio, è possibile che un'unità abbia testato il proprio codice, impacchettato e ora sia giunto il momento di spostarlo in un ambiente più vicino alla produzione. Se i database di cui hai bisogno non possono essere disponibili (ad esempio, non hai la versione corretta dello schema, i dati mancanti di cui hai bisogno, o semplicemente necessari da un'altra applicazione che ci è arrivata prima), puoi usare i mock per consentire l'integrazione test per procedere senza indugio.

4

Ci sono due ragioni principali per i test unitari non hiting il database:

  • volete che il vostro test di andare il più velocemente possibile
  • Volete testare il codice come una singola unità, non come si integra con altro codice/database.

Nel tuo caso è necessario testare le stored procedure. Quindi è necessario scrivere un test che esegua quelle stored procedure. O puoi eseguirli tramite il tuo codice (test di integrazione) o puoi eseguirli direttamente dal test (una sorta di test di unità). In entrambi i casi è possibile utilizzare Nunit.

2

Bene, il fatto è che se le tue unghie colpiscono il database, non stai testando solo la singola unità di codice, ma invece ne stai colpendo diverse - anche il DAL, le stored procedure, ecc. Ecco perché I sostenitori del TDD dicono di non colpire il database in unittests.

E 'anche il motivo per cui non dovreste tenere molto peso in puro, TDD-concettualizzato, teorico santa U nit T EST. Mentre l'unittesting non è una cosa negativa di per sé, ed è di fatto abbastanza importante assicurare che i programmatori costruiscano ogni componente correttamente - il test di sistema è molto più importante. Nel complesso, potrebbe essere più difficile trovare il metodo esatto che ha causato il fallimento dei test di sistema, sono più realistici e lo verifica effettivamente il sistema.
Il cosiddetto "test dei componenti" - che è più simile al test di sistema, ma per una piccola parte del sistema, end-to-end - mi sembra un buon compromesso.

(Cue le confutazioni TDD ora ... :))

1

Dopo aver scritto Should one test internal implementation, or only test public behaviour? e discutere le risposte della gente, penso che la risposta può dipendere da quante persone sono sul team di sviluppo.

Vantaggi del test con il database:

  • test è più realistico (utilizzando il database effettivo)
  • meno codice di test per scrivere (non c'è bisogno di scrivere un finto del database)

Svantaggi di test con il database:

  • i test non possono essere eseguiti fino a quando i dati livello di accesso di base è scritto
  • Se c'è un errore di bug o di prova, non si sa se il bug è nel codice o nel livello di accesso al database

Gli svantaggi sono particolarmente importante se (ma forse solo se) la persona che scrive il livello superiore non è la stessa della persona che scrive il livello di accesso al database.

1

YMHO C'è un po 'di problema semantico e un po' di problemi tecnici qui.

Un test di unità dovrebbe testare una piccola parte del codice, isolatamente, per controllarlo senza altro codice. Un Test unitario fallito dovrebbe implicare che solo una piccola parte del codice dovrà essere ispezionata corretta (tipicamente, il codice che implementa la funzionalità e l'unit test stesso).

Esistono altri ambiti di test per verificare la funzionalità del sistema nel suo complesso (test di sistema) o test funzionali per convalidare funzionalità complete o test di integrazione per verificare interazioni, test di regressione per verificare l'assenza di test già corretti ecc.

Una strategia di test deve essere concepita per ogni progetto, ma in generale avere diverse categorie aiuta molto. Così unit test dovrebbero essere limitati a testare le più piccole possibili unità di codice, e utilizzare altre procedure di prova per testare la funzionalità, l'integrazione ecc

La parte semantica è se è corretto di utilizzare una libreria unit test da eseguire un po 'di test funzionale, immagino che non sia così grave se si mantengono separate le rigorose unit test ei test funzionali (anche se condividono lo strumento di test)

Problemi correlati