2012-05-26 16 views
7

Sto appena iniziando a entrare in test di unità e non vedo un modo semplice per fare un sacco di casi di test a causa dell'interazione con un database.Test di unità - database e dispositivi

Esiste un metodo/processo standard per il test delle unità in cui è richiesto l'accesso al database (lettura e scrittura) per l'asserzione dei test?

Il meglio che riesco a fare finora è disporre di un file di configurazione utilizzato per eseguire il bootstrap della mia app utilizzando una diversa connessione db e quindi utilizzare il metodo di avvio per copiare il db live in un db utilizzato in isolamento per i test?

Sono chiuso? O c'è un approccio migliore a questo?

+0

In questo post del blog ho mostrato un esempio di database di prova/produzione e dispositivi per riempire il database di test utilizzando la lingua Go: https://automationangels.wordpress.com/2015/09/11/fixtures-propagating-test- database-per-unit-test-in-go/Dai un'occhiata, potrebbe essere utile. – WhiteAngel

risposta

10

La logica aziendale non deve interagire direttamente con il database. Invece dovrebbe passare attraverso un livello di accesso ai dati che puoi simulare e fingere nel contesto del test unitario. Guarda in strutture di derisione per fare il beffardo per te. I tuoi test non dovrebbero dipendere affatto da un database. Invece, è necessario specificare i dati restituiti dal proprio livello di accesso ai dati in modo esplicito e quindi assicurarsi che la logica aziendale si comporti correttamente con tali informazioni.

Verificare che il programma funzioni con un DB collegato è più di un test di integrazione e questi hanno molti costi associati. Sono più lenti (quindi è più difficile eseguirli ogni volta che si compila) e sono più complicati (quindi richiedono più tempo e sforzi per essere mantenuti). Se riesci a ottenere test unitari più semplici, ti consiglio di farlo prima. Successivamente è possibile aggiungere test di integrazione che potrebbero utilizzare anche il DB, ma si otterrà il massimo dall'aggiunta di test di unità più semplici.

+0

Ciao Oleski, grazie. Questo ha senso, anche se nella mia situazione l'app è strettamente collegata al database. Si tratta di un carrello e-commerce personalizzato. Esistono molte situazioni che richiedono l'accesso al database, ad esempio l'aggiunta di un articolo allo shopping richiede che questo sia archiviato nel database ecc. Quindi non sono sicuro di come deridere che –

+3

@ user1189880 Uno dei grandi vantaggi di avere test nel mio mente, è che ti costringe a refactoring il codice per renderlo più testabile.Se puoi refactoring il codice, sarà molto meglio a lungo termine. Se non puoi refactoring per qualsiasi motivo, vorrei creare una diversa istanza di database che viene cancellata e popolata con i dati prima che ogni test venga eseguito. – Oleksi

3

Per quanto riguarda il test unitario, penso che qualsiasi cosa funzioni per voi in pratica è la strada da percorrere. È importante che i test unitari diano un certo valore e migliorino la qualità del tuo sistema e la tua capacità di svilupparlo e mantenerlo.

Ti suggerirei probabilmente di non voler copiare il db live sul db di prova. Probabilmente non ci sono garanzie che il tuo database live contenga dati adatti che possano far funzionare costantemente i tuoi unit test. I test unitari dovrebbero verificare che il tuo codice funzioni, non dovrebbero verificare che il database live contenga dati appropriati che li faccia passare, perché dato che è in diretta, gli utenti potrebbero cambiarne il contenuto in modo che i test falliscano .

Il codice di test dell'unità stesso dovrebbe probabilmente compilare il db di test con i dati richiesti che simulano gli scenari per cui si desidera scrivere i test unitari. Ho rovinato un po 'di codice rubino su rotaie qualche anno fa; il framework di test per questo avrebbe una classe di test che configurasse il db con alcuni dati falsi, quindi sarebbero stati scritti più metodi di test della classe per funzionare contro quei dati, e il metodo di rimozione eliminerebbe i dati dal database. Quindi, diverse classi di test (oa volte le persone chiamano fixtures) verrebbero eseguite contro una determinata configurazione di dati, il che significa che è possibile eseguire una serie di test sullo stesso set di dati anziché crearlo per ogni caso di test che si desidera eseguire. L'impostazione dei dati per ogni test potrebbe finire per rallentare i test, in modo da annoiarsi ad aspettare che vengano eseguiti e smettere di disturbarli.

+1

Strettamente parlando, questo non sarebbe più un test unitario. Sarebbe un test di integrazione e i test di integrazione hanno molti costi associati. Ad esempio, sono molto più lenti e molto più complicati. Probabilmente l'OP dovrebbe cercare di implementare prima i test unitari. – Oleksi

+1

Tutto dipende da dove si disegnano i confini tra le unità. Devi tagliare pezzi di funzionalità isolati dal tuo programma per testarli. Potrebbero essere espressioni, affermazioni, funzioni, insiemi di funzioni, classi, ecc. Fondamentalmente ... qualunque cosa tu senta ti dà il più botto per te. –

+1

Sono d'accordo sulla convenzione sembra essere che un test unitario dovrebbe testare le cose all'interno di un processo; il testing a livello di classe sembra essere la convenzione per i linguaggi orientati agli oggetti. Il test unitario come definito accademicamente sembra una buona cosa da mirare, ma se scrivere e mantenere i test unitari finisce col prendere troppo tempo rispetto ai benefici che danno, allora è necessario un equilibrio migliore. E sono pronto a rilassare la definizione di unit test. :) –