Am I Test unitario o integrazione Verifica le mie stored procedure?

8

Recentemente ho avuto molte occasioni in cui ho avuto bisogno di mantenere complesse procedure e funzioni memorizzate. Erano già rotte, di solito in modo abbastanza sottile - c'erano pochissime occasioni in cui si chiamava SP con parametri validi e semplicemente non funzionava.

La mia soluzione era di evolvere un framwork che eseguisse le stored procedure all'interno di una transazione, dopo aver inizializzato il database alle condizioni iniziali di cui avevo bisogno, quindi testando il risultato atteso, anche all'interno della stessa transazione. La transazione è stata annullata alla fine del test.

Questo ha funzionato molto bene. Ma alcuni chiamerebbero questo "test di integrazione" poiché implica l'integrazione con il database. Lo chiamo unit test, dal momento che ho testato singoli componenti e singoli casi di test per quei componenti, e dal momento che ho controllato completamente lo stato iniziale del database.

Ma dove dovrebbe essere tracciata la linea? Questo test di integrazione o test di unità? C'è una ragione pratica per cui questo tipo di test è una cattiva idea? Se questo è "solo" test di integrazione, qualcuno ha suggerimenti su come eseguire "unit test" su queste stored procedure?

Aggiornamento, 3 1/2 anni dopo. Nel mio progetto attuale, ho iniziato a utilizzare i test delle unità SSDT, con successo, anche se potrebbero essere migliori. Vedi Verifica del codice del database utilizzando i test dell'unità SQL Server . Questi in genere distribuiscono il progetto del database nell'istanza di SQL Server LocalDB, pertanto rimuove qualsiasi domanda sull'ambiente del database che interessa il test. Compilo il database con i dati richiesti durante il Pre-Test, che rimuove le domande sul contenuto del database. In effetti, utilizzo le istruzioni MERGE per fare ciò, assicurando che tutti i dati che non sono necessari per il test corrente vengano rimossi, inseriti o aggiornati dal database prima del test. Hanno problemi:

  • Non sono veloci
  • Non è possibile riutilizzare le condizioni di prova
  • Non è possibile riutilizzare i pre-test (a meno che non li rendiate comuni a tutti i test di un progetto)
  • L'interfaccia utente potrebbe essere migliorata

Uno dei motivi per i problemi di cui sopra è che non mi sono ancora lamentato di loro. Raccomando a chiunque sia interessato di provare questa funzione e quindi lamentarsi. Ecco come sono fatti i miglioramenti.

    
posta John Saunders 06.06.2011 - 07:03
fonte

6 risposte

7

Il punto di test unitario non è quello di far venire una fata magica di prova unitaria e convalidare la tua opinione. È per testare i blocchi più piccoli e più semplici del tuo sistema, quindi non stai testando alcune funzionalità più estese e sei inciampato perché qualcosa non ha funzionato come pensavi. Quindi puoi abbatterlo ulteriormente? Non penso che tu possa, nel qual caso:

(a) Sembra un test unitario per me, e (b) Non importa se si tratta di un test unitario o meno, perché mette alla prova ciò che è necessario testare, che è il punto di usare i test unitari in primo luogo!

Se ritieni che le procedure siano troppo complesse, potresti volerle suddividere in parti più piccole (nelle procedure del database o nel codice), ma per farlo ovviamente vorrai avere questi test al loro posto!

    
risposta data 06.06.2011 - 10:53
fonte
7

Il test unitario per definizione ruota intorno al test di una "unità" di codice nel suo ambiente o piattaforma funzionante. La piattaforma utilizzata è un database, quindi è necessario utilizzarlo, non è integrativo.

Una domanda migliore è perché ti interessa. Finché è automatizzato e aggiunge valore, tieni a mente il tuo test in un test unitario, un test di accettazione, un test del fumo o un test funzionale?

Nel mio lavoro, al momento utilizziamo il framework di test unitario per fare lo Sviluppo Test Driven Development (ATDD). Alcuni test sono integrativi, altri no. Quasi nessuno di questi è un test unitario, ma non ci interessa fino a quando:

  • il test aggiunge valore
  • il test non ha fallimenti falliti o successi (è per lo più deterministico)
  • il test è automatizzato

Aggiorna

È tutta una questione di costi e benefici. Più parti mobili hai, maggiore è il rischio di avere un test non deterministico. I test di unità classiche hanno la minor quantità di parti mobili, e quindi la minima possibilità di essere non deterministici. Il compromesso è che non stai testando i punti di integrazione (codice, database, fs, rete, ecc.). Tutti questi sono utili per essere inclusi in un test, purché il rischio di errore falso o di successo sia sufficientemente basso.

I test forniscono valore in ciò che non sono quello che sono. La chiave è la frequenza con cui si avranno fallimenti falliti e successo. Se ho falsi errori per 2 ore al mese perché questa è la finestra di manutenzione della rete, allora il valore dei test è evidente. Quando falliscono è ovvio che c'è qualcosa di sbagliato nella risorsa in rete, non in un test particolare. E ora hai più copertura di test proprio perché stai testando questi punti di integrazione.

    
risposta data 06.06.2011 - 09:15
fonte
2

Penso che dipenda da dove provengono i dati. Se stai creando le condizioni di test nel prefisso di test, penso che sia ragionevole chiamarlo test unitario. In caso contrario, si tratterà di argomenti pignoli su ciò che conta come "preesistente" per un test unitario. Proprio come i test delle unità di database si basano sull'esistenza di tabelle di database e così via, i test di unità al di fuori del database si basano su definizioni di classi e spesso su istanze di quei clsss. Non è male, è realistico.

    
risposta data 06.06.2011 - 07:48
fonte
1

Ritengo che si tratti di test di integrazione:

  1. È molto più lento di un test di unità dovrebbe essere.
  2. Non esercita una singola unità atomica di codice - esercita la tua procedura, il server del database, lo stack di rete, ecc.
  3. Non sarà facile rilevare dove si è verificato l'errore se il test fallisce. Dovrai controllare manualmente ciascun errore per vedere se si tratta di un errore di sistema esterno o del tuo codice.

Tuttavia, i test che descrivi hanno un valore inestimabile. Recentemente abbiamo iniziato ad aggiungere test proprio così, per testare procedure memorizzate che è impossibile testare manualmente in determinati ambienti. Non conosco un altro modo per avere test automatici per le stored procedure.

Quindi, questi test sono una grande idea, ma chiamali test di integrazione: usa una categoria di test o un suffisso per distinguerli dai normali test unitari. In questo modo, puoi contrassegnare gli errori del test di integrazione in modo diverso dai guasti del test dell'unità nell'automazione della build.

    
risposta data 06.06.2011 - 13:21
fonte
0

Is this integration testing or unit testing?

Dove viene eseguito il test? Sul database o tramite test harness basato su codice (JUnit)?

Sul database, è probabile che sia un test unitario (in quanto è autonomo), un'imbracatura di test simile a JUnit quindi si connette a un database esterno e quindi a un test di integrazione.

If this is "only" integration testing

Perché le virgolette? I test di integrazione non sono una specie di bestia che non dovresti mai fare.

does anyone have suggestions on how to do actual "unit tests" on these stored procedures?

In genere trovo che l'unica unità ragionevole per una procedura memorizzata sia il codice chiamante¹ e la procedura. Quindi, l'integrazione verifica il set completo in una serie di test che assomigliano ai test unitari.

A better question is why do you care [about the name].

Come ti permette di dividere i test. I test di integrazione richiedono più tempo per essere eseguiti, richiedono un'ulteriore configurazione e un probabile accesso a una risorsa condivisa da molti test (ad esempio il database).

1) Il codice chiamante avrà ulteriori test di unità, se necessario.

    
risposta data 06.06.2011 - 13:48
fonte
-1

Microtest è un termine utile che può aiutarti a eludere il dibattito sulla terminologia e se il test è un test unitario o meno.

Una definizione comune di unit test include che il sistema sotto test è una piccola unità di funzionalità e devi essere in grado di eseguire tutti i test su di esso in memoria, senza l'aiuto di file system, reti o motori di database . Se hai bisogno di un vero motore di database per eseguirlo, allora non è un test di unità.

Sebbene questa definizione funzioni molto bene per tutti i livelli dell'applicazione, non è molto utile per il livello di accesso al database più basso. Dobbiamo riconoscere che è speciale. Se i test verificano solo piccole unità di archiviazione / recupero / aggiornamento / eliminazione delle funzionalità, i test sono chiaramente preziosi quanto i test di unità "rigorosi" scritti nei livelli superiori del sistema.

    
risposta data 06.06.2011 - 13:09
fonte

Leggi altre domande sui tag