TDD con funzioni di manipolazione di dati e SQL

14

Mentre sono un programmatore professionista, non sono mai stato formalmente formato nell'ingegneria del software. Poiché visito spesso qui e SO, ho notato una tendenza a scrivere test delle unità quando possibile e, poiché il mio software diventa più complesso e sofisticato, ritengo che i test automatici siano una buona idea per facilitare il debugging.

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

La soluzione migliore a cui riesco a pensare è quella di visualizzare i dati che, insieme, coprono la maggior parte dei casi. Posso quindi unirmi a queste visualizzazioni con il mio SQL per vedere se restituisce i record corretti e elaborare manualmente le viste per vedere se le mie funzioni, ecc. Stanno facendo ciò che dovrebbero. Tuttavia, sembra eccessivo e flakey; in particolare trovando dati da testare contro ...

    
posta Xophmeister 25.08.2012 - 14:55
fonte

4 risposte

6

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

L'architettura porte e adattatori è un ottimo esempio. Il database è considerato come un plugin esterno attraverso un adattatore alla tua applicazione. Lo stesso vale per tutti i sottosistemi di terze parti. Per verificare come la tua app si comporterà e interpreterà le risposte dei sottosistemi di terze parti, l'unico modo per sapere come testare è lo stub delle risposte di questo singolo sottosistema. Non voglio necessariamente dire che dovresti scrivere manualmente tutti gli oggetti dati. Puoi facilmente adottare l'approccio dell'utilizzo di test basati sui dati.

Per verificare come la vostra applicazione interagisce con il vostro database, potete ad esempio falsificare gli adattatori del database per utilizzare un database in memoria.

Ora testare le query del database. Prima di tutto tutte le query complesse dovrebbero essere scomposte in query più semplici, semplici e prevedibili. Lo stesso si farebbe per una classe grassa o per una funzione grassa. Esistono strumenti che possono aiutarti a testare il tuo database come Dbunit . Un approccio semplice che a volte prendo è di usare il concetto di test di caratterizzazione. Quindi metterei 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 serie confronteranno il loro output con questo, quindi mi offrirebbero sicuramente i test di regressione di cui ho bisogno. In effetti, la prima uscita non è garantita per essere corretta, ma il problema di regressione può essere risolto in questo modo. Se le tue domande sono ben scomposte, puoi testarle individualmente sul database che si trova in uno stato conosciuto.

    
risposta data 25.08.2012 - 15:22
fonte
3

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

Le viste sarebbero probabilmente un modo difficile per farlo perché in realtà non prestano al test il primo test automatico a luce rossa e verde chiaro di un aspetto per test che è preferito in TDD. Inoltre con le viste non puoi scrivere il test prima del codice. Un approccio migliore sarebbe scrivere stored procedure in cui è possibile aggiungere la logica "assert" nella procedura (ad esempio, utilizzando le istruzioni "if") per verificare l'output in caso di errore. È necessario testare solo una cosa per ogni unità di test per isolare l'unità, e il metodo SP sarebbe più adatto per quello. Inoltre, con gli SP puoi eseguire l'intera suite come script mentre sviluppi il codice iniziale e in seguito quando collaudi le regressioni durante il refactoring.

Inoltre, tieni presente che i test devono essere ripetibili e che sono necessari alcuni script per inizializzare e rimuovere lo stato del database per garantire che lo stato sia lo stesso per ogni unità di test.

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

    
risposta data 25.08.2012 - 15:46
fonte
1

A un certo punto ti serviranno dati di test. Se stai utilizzando un sistema di terze parti, lo schema è già stato creato, ma dovrai affrontare le modifiche future. Si spera 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 nelle tabelle del database o in file / fogli di calcolo esterni. Ho persino visto il CHECKSUM usato o il confronto. Quando si verifica una vista / sproc, si verificherà un errore poiché non esistono. Quindi crei l'oggetto con un codice sufficiente per l'esecuzione (SELECT -1 come [wrong_data];) e otterrai un errore perché non corrisponde al set di risultati. Una volta abbinati, hai il tuo semaforo verde.

Ho iniziato a collaborare con i proprietari dei progetti e chiedo loro di simulare i report in un foglio di calcolo e provare a generare dati parziali per me (è possibile inserire i dati dei risultati in una tabella di test). All'inizio ci fu un po 'di pushback, ma si resero conto che avrei creato un rapporto e che dovevano verificarlo comunque. Ciò ha risparmiato tempo a lungo termine. Se vogliono fare una richiesta di modifica, riescono a rifare il foglio di calcolo. Ora possono rispondere alla domanda: "Quanto sarebbe difficile aggiungere ...?"

    
risposta data 26.08.2012 - 14:51
fonte
1

Se la tua piattaforma di database è SQL Server, c'è un ottimo strumento gratuito: tSQLt .

tSQLt is a database unit testing framework for Microsoft SQL Server. tSQLt is compatible with SQL Server 2005 (service pack 2 required) and above on all editions.

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 la normale impostazione implicata
  • I test vengono eseguiti automaticamente nelle transazioni (quindi facilmente ri-eseguibili)
  • Le tue affermazioni possono fare confronti su tabelle (sia reali che false) in modo da poter vedere se hai cambiato facilmente i dati
risposta data 27.08.2012 - 13:19
fonte

Leggi altre domande sui tag