Perché non vedo molti progetti di test unitari che richiamano e abbattono un DB? (ASP.NET MVC)

3

Vedo tutti gli esempi che dimostrano il codice di test unitario e che simulano le chiamate al DB poiché non si suppone che si tocchi il DB. Ma mi sembra di avere delle attività di set up che usano lo schema reale, carica le tabelle di ricerca e poi le popola con i dati usando i metodi da testare ... In questo modo è più test del mondo reale e tutte le stored procedure sono testate pure ... Ma non ho mai visto nessun esempio come questo ... C'è qualche motivo per cui non capisco perché usare questa tecnica non sia così utile come sembra?

EDIT1: Scusa .. Non avrei dovuto chiamarlo unit test .. sì. Avrò anche dei test unitari per testare il codice. Ma oltre a questo mi sembra una buona idea far apparire e abbattere e DB e avere un codice che modifichi quel DB e faccia asserzioni .. Ma non voglio questo per essere un test dell'interfaccia utente. Voglio solo eseguire molte funzioni CRUD e molte asserzioni ..: la mia domanda è # 1 ha senso ... # 2 come automatizzo tutto all'interno di Visual Studio? Come posso comunicare a VS 2012 di eseguire uno script SQL prima di eseguire i test? c'è qualche API speciale per questo?

    
posta punkouter2018 07.05.2013 - 23:43
fonte

7 risposte

9

Invece di dire "Perché è un test unitario", parliamo di perché potremmo volere un test che non dipenda da un database.

Errori isolati

Vogliamo un test dell'unità in errore per identificare rapidamente dove si trova un problema. L'errore di test dell'unità più stretto ha già due possibili origini, sia l'unità in prova che il test stesso. Ogni dipendenza è un'altra possibile fonte di errore .

Supponendo che non si disponga di dati di database personalizzati per ogni test, si corre il rischio che qualcuno modifichi i dati per un altro test, ma interrompa i propri. Se si dispone di dati per ogni test, la gestione di tutto ciò è diventato un problema. Lo schema cambia? Vai a modificare ogni test di unità.

Errori rapidi

I test unitari dovrebbero essere veloci . Quanto velocemente? Abbastanza veloce da impedire agli sviluppatori di eseguirli regolarmente e non perdere tempo quando lo fai. I test unitari perdono rapidamente molto valore se le persone non li eseguono mai perché impiegano 45 minuti per configurare e abbattere il database più di 1000 volte.

Test con il database

Detto questo, la nostra app utilizza un database . Se non testiamo mai con il database, non sappiamo davvero se l'app funziona. Molti progetti eseguono questo test quando testano l'intero integrato e di solito vengono eseguiti meno spesso dei test unitari. Ad esempio, uno dei miei progetti riguardava diverse applicazioni con test unitari che potevano essere eseguiti in meno di 30 secondi al pezzo, ma i test del sistema integrato duravano 4 ore su una griglia di calcolo.

    
risposta data 08.05.2013 - 04:44
fonte
3

Nonostante molti sviluppatori preferiscano il termine "test di integrazione" invece di "unittests" quando sono coinvolti sistemi esterni come i database test automatici con database sono spesso dolorosi e fragili:

Da Test dell'unità con un database in memoria per una primavera / Hibernate Project

Testing DB code is often painful with any significant number of people. Often you 
either need every developer to have their own database, with it's own uniquely 
inconsistent data and ways of failing, or to use a shared database in which case 
people often manage to produce tests that don't work if more than one person runs 
the tests concurrently. Also testing on a "real" DB is slow and subject to failure 
for reasons not related to your code. 

Con fragile intendo "il test fallisce perché c'è un errore logico nel codice o è perché qualcuno ha cancellato un datarow che è richiesto dal test".

Affinché i test relativi al database possano funzionare è necessario disporre di un set predefinito di contenuto del database che deve essere mantenuto. Abbiamo progetti in cui esiste un database di testing automatico dove gli sviluppatori non sono autorizzati a modificare alcun dato.

L'altra alternativa è che il test automatico genera i dati di test richiesti e lavora con un database in memoria.

    
risposta data 08.05.2013 - 12:06
fonte
2

È perché un test di unità non dovrebbe avere alcuna dipendenza. Deve essere autonomo. Esiste un test unitario per testare una "unità" di logica nel codice trattandolo come una scatola nera. La fonte specifica di dati (database o altro) non dovrebbe avere alcun impatto sulla logica.

Qualsiasi altra cosa, anche se chiamata tramite un quadro di test unitario, non è classificata come test unitario. Sarebbe un diverso tipo di test come un test funzionale.

Vale la pena consultare alcuni dei materiale di Kent Beck su TDD.

    
risposta data 08.05.2013 - 00:04
fonte
1

MSTest ?

Le altre risposte dicono perché è necessario testare da solo, ma poi testare anche le stored procedure del DB - chiamarle con un determinato input in una tabella piena di dati predefiniti e vedere quale risultato viene restituito. Ogni test imposta i dati, chiama il codice di test, quindi esegue il rollback in modo che il DB ritorni allo stato originale.

Questo è facile, usalo in congiunzione con i tuoi test sul lato client. (è solo un peccato che poche persone ne sappiano abbastanza per rendersi conto che il test unitario si applica sia al codice SQL che al codice C #, se solo dividessero il codice sql in stored procedure troverebbero che il test DB fosse facile. Poche persone scrivono un'unità DB appropriata test, il che è sorprendente considerando quanto sia importante l'aspetto del DB per la maggior parte dei programmi).

Ora c'è un problema separato con i test di integrazione, e per questo dovrai configurare un DB con dati di esempio e poi chiamare il tuo client (usando Selenium o simili) in modo da esercitare tutto il fine. Questo non è un test unitario di per sé. È ancora molto utile, e dovresti farlo anche tu - i test unitari verificano solo i piccoli dettagli di piccoli pezzi di codice e ignorano il "quadro più ampio" di come lavorano insieme. I test di integrazione verificheranno che l'intera app funzioni quando tutte queste piccole unità sono collegate.

    
risposta data 08.05.2013 - 14:17
fonte
0

Questo non è orribilmente semplice ma non impossibile. Il più grande ostacolo è scegliere uno strumento e un metodo per posizionare automaticamente il database nello stato desiderato che funzionerà in silenzio dalla riga di comando. Personalmente preferisco roundhouse per questo compito, ma ci sono sicuramente altre opzioni. Nella misura in cui è integrato con Visual Studio, il modo più semplice è quello di creare una configurazione personalizzata e hackerare la chiamata all'eseguibile per creare il database nelle impostazioni di creazione personalizzate.

La prossima domanda è "che tipo di database creare e come testarlo?"

L'approccio che a mio parere ha più senso è quello di distribuire una copia vuota dello schema e quindi fare in modo che ogni test sia responsabile della creazione dei dati di test di cui ha bisogno e di come ripulire se stesso. Ciò richiederà un po 'più di tempo per test, ma ti terrà lontano da preoccupazioni trasversali tra i test.

Infine, come altri hanno indicato, questo sarà lento, quindi se potessi separarlo nel proprio progetto potrebbe valerne la pena.

    
risposta data 09.07.2014 - 15:22
fonte
-1

Il test del database non viene eseguito in Test unità ma in Test integrato.

    
risposta data 08.05.2013 - 14:40
fonte
-2

La definizione di unit test è un test che verifica una singola unità di comportamento in isolamento. Un test che verifica l'integrazione con il database non sta testando né una singola unità né in isolamento, quindi per definizione non è un test unitario.

Chiedere perché non ci sono test unitari che si integrano con il database è come chiedere perché non ci sono numeri dispari divisibili per due: è semplicemente a causa della definizione della parola "numero dispari".

    
risposta data 08.05.2013 - 00:05
fonte

Leggi altre domande sui tag