Che qui non scrivere unit test abbastanza? Voglio dire altro da me? In qualche modo, non importa quanto sia buona la mia copertura di test si sono caduto come sempre ci sono alcune parti mancanti. In parte questo è perché le pratiche di unit test tende ad essere uno di quei dibattiti religiosi e se si ascolta numero sufficiente di persone, è facile convincersi che si sta facendo è sbagliato.
Un settore che è sempre stato un po 'difficile sta sperimentando qualcosa con una dipendenza database. In parte, ciò è dovuto al fatto quei test spesso finiscono per essere dipendente stesso di dati che, naturalmente, può essere altamente volatile. Ma è anche filosoficamente contestata nel senso che se uno unit test è quello di valutare un'unità distinta di codice sul livello applicazione, allora probabilmente non dovrebbe avere dipendenze livello dati.
Il problema, naturalmente, è che stiamo ancora scrivendo un sacco di logica nel livello dati.ORM Fancy sono fantastici e io sostengo il loro utilizzo nella misura massima che è pratico, ma ci sono ancora un sacco di casi d'uso per la scrittura logica di business nel database e si vuole veramente che, per essere verificabile. Inoltre, naturalmente, c'è tutto questo altro universo alternativo di persone che lavorano completamente in database e non hanno accesso agli strumenti di test molti di noi utilizzano regolarmente all'interno di Visual Studio, chiamiamoli i "cittadini di seconda classe di unit test".
Questo è dove prova SQL Red Gate entra in gioco è interamente auto-contenute in SSMS e tutto ciò che fa è la logica di business test nel database, proprio come quei cugini di prima classe in Visual Studio. Ed è totalmente rocce.
Caso d'uso
Questo non è uno di quei arioso-fiabe situazioni ipotetiche, ho davvero bisogno di spostare una certa logica nel DB così ho potuto eseguire query su ASafaWeb indipendentemente dal livello applicazione. Quello che volevo fare era scrivere una piccola funzione di accertare se una voce nel registro qualcuno aveva suggerito di eseguire una scansione contro un sito Web ASP.NET o no. Ho già in questa logica nel mio app web e sembra che in questo modo:
public static bool ? { / / Nessuna informazione a tutti dovrebbe (si spera) che il sito è configurato per mantenere le intestazioni in silenzio. Potrebbe andare in entrambi i casi quindi dovremo tornare null. se (( string IsNullOrEmpty (server). | server.Contains ( "nginx" )) && (XPoweredBy == nullo | |! xPoweredBy.Any ()) && string . IsNullOrEmpty (xAspNetVersion) && string . IsNullOrEmpty (xAspNetMvcVersion) && string . IsNullOrEmpty (aspNetVersion)) { restituire null ; } return (! stringa . IsNullOrEmpty (server) && (server.Contains ( "Microsoft-IIS" ))) | | (! XPoweredBy = null && xPoweredBy.Any (x => x == "ASP.NET" )) | |! string . IsNullOrEmpty (xAspNetVersion) | |! string . IsNullOrEmpty (xAspNetMvcVersion) | |! string IsNullOrEmpty (aspNetVersion).; }
Questo è semplicemente guardando le intestazioni di risposta e fare un guesstimation se il sito è ASP.NET o meno. No info (nginx o un server che esegue quadri che supporta multipli) significa che non ho idea e restituisce null (la prima serie di condizioni), mentre qualsiasi cosa che suggerisce IIS o ASP.NET è presente restituisce true (la seconda serie di condizioni) . Ci sono poi una serie di prove scritte intorno a questo in un progetto di test Visual Studio.
Installazione e configurazione di test SQL
Il primo passo è quello di andare a mettere le mani su di test SQL Red Gate . E 'in anteprima 2, è attualmente libero, just do it! Una volta installato e al fuoco fino SSMS, nuove cose iniziano a comparire:
Prenderemo il database di esempio semplicemente perché è un buon punto di riferimento di come fare le cose per bene:
E qui andiamo, il corridore di prova viene caricato con il database di esempio:
Io non entrerò nel merito di quello che sta succedendo qui, eseguirlo su voi stessi e dare un'occhiata dentro se siete interessati. Invece, voglio aggiungere il mio database ASafaWeb ed effettivamente iniziare a testare la mia TSQL. Quando aggiungo il database, ho un dialogo bello chiaro spiegando che cosa sta per accadere:
Ora, questo probabilmente non sarà per tutti, posso immagine che alcune persone non essere felice con un mucchio di nuove procedure, funzioni e altri oggetti che compaiono nel loro database incontaminata. Ma naturalmente si può facilmente escludere quelli di distribuzione al momento della pubblicazione via SQL Compare come ho conosciuto da fare .
Un'ultima cosa - se prendiamo il valore predefinito e includono SQL Cop test di analisi statica, siamo in grado di validare alcuni buoni principi di progettazione DB. Suoni la pena:
Run che, ecco quello che ora abbiamo:
Quali sono quindi carica il DB Up in the runner test:
Come potete vedere, abbiamo ottenuto solo prove di Cop SQL lì per ora, ma cerchiamo di dare loro un run in ogni caso:
Uh oh, questo significa che il mio SQL non va bene? Sto DB destinato alla dannazione eterna? Fortunatamente, se diamo uno sguardo ai messaggi dal canale di prova si scopre che niente di tutto questo è colpa mia:
Si scopre che Microsoft si sta portato a un'attività tramite EXEC sp_executesql anziché in un paio di procedure di appartenenza del loro provider memorizzati, che è apparentemente una brutta cosa . Poi abbiamo ELMAH essere scoperti usando ROWCOUNT SET che èapparentemente destinato ad essere obsoleto (quasi cinque anni e ancora funziona bene in SQL08 ...)
Comunque, niente di tutto questo è il mio codice e non ho intenzione di andare modificare il codice generato da altre parti. Andiamo sul bit interessante.
Scrivere i test
Il primo test di base che voglio veramente è effettivamente la prima condizione stavo testando da tale codice C # di precedenza, nessuna intestazione a tutti dovrebbe restituire nulla perché non abbiamo niente da confermare o negare la presenza di ASP.NET e IIS.Facciamo scrivono che nella "New Test" il dialogo:
Lavorare sulle precedenti nel database di esempio, ho intenzione di creare una classe dedicata test chiamato "AspNetSiteTests". In questo modo si crea uno schema con lo stesso nome e una volta che il test è stato creato, siamo tornati in buoni TSQL vecchio con un modello di Test pronti:
- Comments qui sono associati con il test. - Per esempi di casi di test, vedere: http://tsqlt.org/user-guide/tsqlt-tutorial/~~V ALTER PROCEDURE [AspNetSiteTests] . [test nessuna intestazione restituisce null] AS BEGIN - Montare - Questa sezione è per il codice che imposta l'ambiente. Spesso - Contiene le chiamate a metodi come tSQLt.FakeTable e tSQLt.SpyProcedure - Insieme con inserti di dati pertinenti. - Per ulteriori informazioni, vedere http://tsqlt.org/user-guide/isolating~~V - dipendenze / - Atto - Eseguire il codice sotto test come una stored procedure, una funzione o una vista - E catturare i risultati in variabili o tabelle. - Assert - Confrontare i valori previsti ed effettivi, o tSQLt.Fail chiamata in un IF dichiarazione. - Disponibile afferma: tSQLt.AssertEquals, tSQLt.AssertEqualsString, tSQLt.AssertEqualsTable - Per un elenco completo, vedere: http://tsqlt.org/user-guide/assertions/ EXEC tSQLt . Fail 'TODO: Implementare questo test.' END ;
Questo dovrebbe essere abbastanza familiare a coloro che hanno trascorso un po 'di tempo a scrivere i test prima, abbiamo il classico organizzare (o di "assemblare" in questo caso), atto, affermano modello e, naturalmente, è impostato a fallire perché non è ancora fare qualcosa.Naturalmente prima di poter fare qualsiasi cosa abbiamo bisogno di qualcosa per farlo funzionare in modo contro la facciamo solo creare una nuova funzione di valore scalare che non fa altro che dichiara i parametri corretti e resi nulli.
ALTER ) RETURNS bit AS BEGIN EXEC tSQLt . Fail RETURN NULL END
Non sono convinto che chiamare tSQLt . Fail è davvero la cosa più intelligente da fare qui, ma ovviamente una sorta di eccezione deve essere gettato (in NotImplementedException pensiero. NET), e non è possibile RaiseError in una funzione. In ogni caso, è solo temporanea in modo che possiamo avere i nostri test scritto e francamente mi sono più interessato a far funzionare le cose più risucchiato in quel dibattito unit testing religiosa ho accennato in precedenza. Ecco il primo test semplice scriverò fare in modo che se tutto è null allora il risultato è nullo:
ALTER PROCEDURE [AspNetSiteTests] . [test nessuna intestazione restituisce null] AS BEGIN - Montare DECLARE @ Server NVARCHAR ( 250 ) = NULL; DECLARE @ XAspNetVersion nvarchar ( 50 ) = NULL; DECLARE @ XAspNetMvcVersion nvarchar ( 50 ) = NULL; DECLARE @ XPoweredBy nvarchar ( 300 ) = NULL; --Act DECLARE @IsAspNetSite BIT; SET @IsAspNetSite = dbo.IsAspNetWebsite(@Server, @XAspNetVersion, @XAspNetMvcVersion, @XPoweredBy); - Assert EXEC tSQLt . assertEquals NULL, @ IsAspNetSite ; END ;
Ora possiamo andare avanti ed eseguire questo nel test runner:
Ottimo, questo è esattamente il tipo di flusso di lavoro ci si aspetterebbe quando si scrivono i test prima di nuovo in Visual Studio. Facciamo scrivere il resto di loro prima di poter realmente attuare la funzione di:
Ora possiamo andare avanti con l'effettiva implementazione del metodo e passare attraverso l'intero rosso, verde, ciclo di refactoring. Come ho iniziato ad attuare la funzione, mi salta al test runner, dare un vortice e guardare le prove a poco a poco iniziano a passare:
E naturalmente c'è qualche prolissità sul motivo per cui le cose vanno male, una volta drill-down dei messaggi di prova SQL:
E questo è davvero - mantenere attuazione test e fare le cose verde, proprio come si farebbe indietro nel buon vecchio di Visual Studio.
Ma aspettate - c'è di più!
Mentre io non avevo bisogno di approfondire questa area solo per scrivere test contro una funzione semplice, Test SQL ha un supporto eccellente per affrontare la volatilità dei dati. Mi spiego: ci sono molti usi programmatici di TSQL che hanno una dipendenza dello stato dei dati. Ad esempio, una procedura stored viene eseguito su un tavolo e fa calcoli basati sui dati che è in là.
La sfida qui è in qualche modo simile a quello che abbiamo affrontato per molti anni durante la scrittura di unit test in Visual Studio in che quando le prove diventano dipendenti sullo stato dei dati si corre il rischio reale dei dati, non essere sempre in attesa che stato. Inoltre alla fine di dover pulire dopo voi stessi e cercando di ottenere tutti i dati in uno stato piacevole prevedibile prima di eseguire i test più. E 'un campo minato.
Il modo in cui SQL gestisce questo test è quello di consentire la creazione di tabelle falsi impalamento, che tutti gli attributi della cosa reale e consentono di pasticciare con essa il desiderio del vostro cuore senza modificare i dati persistenti. È quindi possibile affermare che la tabella corrisponde a un falso pre-stato definito previsto. Il modo migliore per ottenere la testa intorno a questo è quello di dare un'occhiata al video introduttivo Red Gate dove Grant Fritchey ti guida attraverso di essa (tabelle finte sono disponibili in tutto il marchio di 5 minuti):
Un'altra risorsa è il degno Simple-Talk articolo sulla base di test di prova di database di SQL Unità con TeamCity Continuous Integration . Sono stato un fan di integrazione degli strumenti di cancello rosso con TeamCity in passato, quindi questo si allinea molto al mio modo di pensare.
Riassunto
Come tutti gli altri bit cancello rosso, quello che mi piace di test SQL è che è estremamente pratico e si integra perfettamente nel vostro modo di lavorare durante la creazione di banche dati; è proprio lì in SSMS ed è molto facilmente accessibile. Non ci sono fumo e specchi o la magia in corso in background, è molto facile vedere esattamente come la cosa è mettere insieme e quello che sta facendo sotto le coperte.
Test di SQL ha un senso per tutti i motivi stessi che l'unità di prova i vostri progetti di Visual Studio fa, avere la certezza che il codice sta facendo ciò che si intende oggi e in futuro è assolutamente inestimabile. Inoltre è possibile eliminare il tutto in controllo del codice sorgente SQL e condividere i test con il team quindi escludere quando si genera script per il cambio e la pubblicazione via SQL Confronta. Nizza.
Io non sono molto sicuro della roadmap futura Red Gate per il prodotto, ma soprattutto mentre è gratis dico entrare e mettere le mani su di esso. Avevo tutto attivo e funzionante con i miei propri test al letteralmente circa 20 minuti - hanno a go!
Nessun commento:
Posta un commento