TDD con funzioni di manipolazione dati e SQL


14

Mentre sono un programmatore professionista, non sono mai stato addestrato formalmente in ingegneria del software. Dato che visito spesso qui e SO, ho notato una tendenza a scrivere unit test quando possibile e, man mano che il mio software diventa più complesso e sofisticato, vedo i test automatizzati come una buona idea nell'aiutare il debugging.

Tuttavia, la maggior parte del mio lavoro prevede la scrittura di SQL complessi e l'elaborazione dell'output in qualche modo. Come scriveresti un test per assicurarti che il tuo SQL restituisse i dati corretti, per esempio? Quindi, dire se i dati non erano sotto il tuo controllo (ad es. Quello di un sistema di terze parti), come puoi testare in modo efficiente le tue routine di elaborazione senza dover scrivere a mano risme di dati fittizi?

La migliore soluzione a cui riesco a pensare è quella di visualizzare i dati che, insieme, coprono la maggior parte dei casi. Posso quindi unire quelle viste con il mio SQL per vedere se restituisce i record corretti ed elaborare manualmente le viste per vedere se le mie funzioni, ecc. Stanno facendo quello che dovrebbero. Tuttavia, sembra eccessivo e debole; in particolare la ricerca di dati per testare contro ...


Risposte:


6

Una regola importante per testare tutto ciò che è correlato al database è isolarlo completamente dal resto dell'applicazione.

L' architettura delle porte e degli adattatori è un ottimo esempio. Il database è considerato come un plug-in esterno tramite un adattatore per l'applicazione. Lo stesso vale per tutti i sottosistemi di terze parti. Per testare come la tua app si comporterebbe e interpretare le risposte dei sottosistemi di terze parti l'unico modo in cui so come testare è quello di stub le risposte di questo singolo sottosistema. Non intendo necessariamente che dovresti scrivere manualmente tutti gli oggetti dati. È possibile adottare facilmente l'approccio dell'utilizzo dei test basati sui dati.

Per quanto riguarda il test del modo in cui l'applicazione interagisce con il database, è possibile falsificare gli adattatori del database per utilizzare ad esempio un database in memoria.

Ora testare le query del database. Prima di tutto le query complesse dovrebbero essere scomposte in query più facili, semplici e prevedibili. Lo stesso che faresti per una classe di grassi o per una funzione di grasso. Esistono strumenti che possono aiutarti a testare il tuo database come Dbunit. Un approccio semplice che a volte adotto è quello di utilizzare il concetto di test di caratterizzazione. Quindi vorrei mettere il database in uno stato noto, eseguire tutte le query che devo scrivere, salvare l'output in un posto (file, memoria) e considerare questo output come quello corretto. Le prossime sessioni confronterebbero il loro output con questo, quindi questo mi offrirebbe sicuramente il test di regressione di cui ho bisogno. In effetti, il primo output non è garantito per essere corretto, ma il problema di regressione può essere risolto in questo modo. Se le tue query sono ben scomposte, puoi testarle individualmente verso il database che si trova in uno stato noto.


3

Questa è una domanda interessante perché il database è di solito la parte falsificata durante il test dell'unità dell'applicazione. Si spera che la logica del motore di database stesso sia ben testata dal provider, ma ovviamente le query, lo schema e le procedure memorizzate sono codice che deve essere testato e protetto contro la regressione. Questo è spesso lasciato al test di integrazione che non è TDD.

Le visualizzazioni sarebbero probabilmente un modo difficile per farlo perché non prestano realmente al test il primo test automatico a luce rossa e a luce verde di un aspetto per test che è preferito nel TDD. Inoltre, con le visualizzazioni non è possibile scrivere il test prima del codice. Un approccio migliore sarebbe quello di scrivere procedure memorizzate in cui è possibile aggiungere la logica "assert" nella procedura (ad es. Usando le istruzioni "if") per testare l'output per errore. È necessario testare solo una cosa in ogni test unitario per isolare l'unità, e il metodo SP sarebbe più adatto a questo. Inoltre, con SP è possibile eseguire l'intera suite come script mentre si sviluppa il codice iniziale e successivamente durante il test delle regressioni durante il refactoring.

Inoltre, tenere presente che i test devono essere ripetibili e saranno necessari alcuni script per inizializzare e ridurre lo stato del database per garantire che lo stato sia lo stesso per ciascun test unitario.

Per la tua domanda sui dati che non sono sotto il tuo controllo, questa è un'area difficile. Penso che farai meglio a deriderlo con dati falsi e testare il più possibile le condizioni di eccezione e limite per i test unitari. Altrimenti rientrerà maggiormente nella categoria dei test di integrazione (che è anche una buona cosa da fare). Per i test di integrazione è possibile eseguire i test con i dati di terze parti e lasciare che generi un output iniziale e per i test successivi (ad es. Dopo il refactoring) assicurarsi che tali output ripetano l'output noto iniziale.


Perché non puoi scrivere un test per una vista che non è stata ancora codificata?
JeffO,

Non se stai usando la vista come meccanismo per il test come proposto dall'OP.
Chiavi in ​​mano il

1

Ad un certo punto avrai bisogno di dati di prova. Se stai utilizzando un sistema di terze parti, lo schema è già stato creato, ma dovrai affrontare le modifiche future. Spero che tu possa ottenere queste modifiche dalla documentazione di aggiornamento, ma potresti essere costretto a confrontare tu stesso le versioni del database.

I set di risultati previsti possono essere salvati in tabelle di database o file / fogli di calcolo esterni. Ho anche visto CHECKSUM usato o confronto. Quando provi una vista / sproc, otterrai un errore poiché non esistono. Quindi si crea l'oggetto con un codice sufficiente per eseguire almeno (SELECT -1 come [wrong_data];) e si otterrà un errore perché non corrisponde al set di risultati. Una volta abbinati, hai il tuo via libera.

Ho iniziato a lavorare con i proprietari del progetto e chiedo loro di deridere i report in un foglio di calcolo e provare a trovare dati parziali per me (potresti inserire i dati dei risultati in una tabella di test). All'inizio c'è stato qualche respingimento, ma si sono resi conto che avrò creato un rapporto e lo dovranno comunque verificare. Questo ha permesso di risparmiare tempo nel lungo periodo. Se vogliono fare una richiesta di modifica, riescono a ripetere il foglio di calcolo. Ora possono rispondere alla domanda "Quanto sarebbe difficile aggiungere ...?"


1

Se la tua piattaforma di database è SQL Server, esiste uno strumento gratuito molto carino: tSQLt .

tSQLt è un framework di test delle unità di database per Microsoft SQL Server. tSQLt è compatibile con SQL Server 2005 (richiesto Service Pack 2) e versioni successive su tutte le edizioni.

Ho usato con successo per implementare i test a livello di database.

Alcuni degli elementi chiave che lo rendono così utile includono:

  • Capacità di lavorare con tabelle e viste false che riducono le normali impostazioni di installazione
  • I test vengono eseguiti automaticamente nelle transazioni (quindi facilmente rieseguibili)
  • Le tue affermazioni possono fare confronti su tabelle (sia reali che false) in modo da poter vedere se hai modificato facilmente i dati
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.