Database e unità / test di integrazione

25

Ho avuto una discussione con qualcuno sui test di unità / integrazione con le applicazioni web e ho un disaccordo su 1 idea principale. Il problema è che la persona con cui sto parlando pensa che il database su cui è stato eseguito il test dell'unità dovrebbe contenere dati pre-compilati e penso che dovrebbe essere completamente vuoto prima e dopo l'esecuzione dei test.

La mia preoccupazione per i dati pre-compilati nel database è che non c'è modo di assicurarsi che i dati siano mantenuti in buono stato. I test stessi stanno creando, eliminando e modificando i dati nel database, quindi non vedo davvero come avere i dati nel database prima di iniziare i test sia una buona cosa.

Sembra che il modo migliore di testare la funzionalità del database sia la seguente:

  1. In una fase di "configurazione" prima dell'esecuzione effettiva del test, per prima cosa troncare tutte le tabelle nel database
  2. Quindi inserisci tutti i dati necessari per i casi di test che stai per eseguire
  3. Quindi esegui e convalida i casi di test
  4. Poi in una fase di "teardown" tronchi ancora una volta tutte le tabelle nel database

Non vedo nessun altro modo migliore per garantire che i dati su cui stai testando siano un buon test testabile.

Mi sto perdendo qualcosa qui? Non è questo il modo migliore per testare la funzionalità relativa al database? C'è qualche vantaggio nel disporre di un database pre-popolato che esiste sempre nel database (anche prima di iniziare i test o dopo che i test sono stati eseguiti)? Qualsiasi aiuto nelle idee per spiegare il mio processo in modo diverso per ottenere meglio il mio punto di vista sarebbe anche grande (cioè se il mio punto ha dei meriti).

    
posta ryanzec 15.08.2011 - 21:26
fonte

6 risposte

21

Per me i test unitari non dovrebbero occuparsi del database, i test di integrazione riguardano il database.

I test di integrazione che si occupano del database dovrebbero in pratica avere un database vuoto con un approccio di strappo e demolizione, utilizzando un approccio basato sulle transazioni è un buon modo per andare (cioè creare una transazione su setup e rollback su strappo ).

Quello che il tuo amico sembra voler fare è testare da un punto di vista della regressione, cioè avere dati reali lì e vedere come reagisce il sistema, in fin dei conti nessun sistema è perfetto e di solito ci possono essere dati cattivi in giro da qualche parte che fornisce qualche stranezza al tuo modello di dominio.

Le tue best practice sono la strada da percorrere, e quello che tendo a fare, è che se trovo uno scenario per dati errati, scrivi un test di integrazione con un setup up e abbatti con quello scenario esatto.

    
risposta data 15.08.2011 - 21:38
fonte
6

Se i test dipendono dal database, penso che sia più importante che i dati a cui tieni siano in uno stato noto per il test, piuttosto che il database sia vuoto. Una delle misure dei buoni test è che ogni test dovrebbe fallire per una ragione e nessun altro test dovrebbe fallire per lo stesso motivo.

Quindi, se i tuoi test si preoccupano dello stato dei dati, trasferiscono i dati in quello stato noto e restituiscono i dati a quello stato dopo che i test sono stati eseguiti, in modo che i test siano riproducibili.

Se riesci a disaccoppiare i tuoi test dallo stato dei dati per derisione, allora sarebbe anche una buona cosa. Hai detto che stai facendo test di unità / integrazione, ma ovviamente queste due cose dovrebbero essere considerate separatamente. I test delle unità dovrebbero essere disaccoppiati dal database se possibile e i test di integrazione dovrebbero essere testati con il database in uno stato noto.

    
risposta data 15.08.2011 - 21:46
fonte
2

Bene, vedo un vantaggio nell'avere un database prepopolato: non è necessario scrivere il codice che inserirà i dati necessari, poiché è lì. Altrimenti ci sono solo inconvenienti. Forse qualcuno ha modificato i dati del test sul database? Forse qualcuno ha tentato di aggiornare i dati? Ma la cosa peggiore è che un caso di test rovina gravemente il database ... Si finisce per ricreare manualmente l'intero database più volte.

Hai ragione su come dovrebbero essere scritti i test, eccetto che non avrei troncato nulla:

  • fase di configurazione: ottenere una connessione al database e inserire i dati
  • fase di esecuzione
  • fase di rimozione: rimuovere i dati inseriti (troncati)

Ora, questo scenario è ottimo per i test unitari. Quando si ha bisogno di dati per i test di unità e di integrazione, ho scoperto che una grande fase di impostazione comune a tutti i casi di test (abbiamo raggruppato tutti gli "inserti" in un unico metodo statico) può anche funzionare molto bene. È come una via di mezzo tra la tua idea e l'idea del tuo amico. L'unico svantaggio è che devi stare molto attento quando aggiungi alcuni nuovi dati per non rompere i casi di test esistenti (ma se aggiungi come due tre file per tabella come abbiamo fatto, non dovrebbe essere un problema)

    
risposta data 15.08.2011 - 21:46
fonte
1

Penso che sia necessario limitare un esempio al tuo collega e scoprire cosa significano esattamente. Puoi essere entrambi sulla stessa pagina.

Esempio: controllo della tabella transazioni account

  1. Non vorresti testare la visualizzazione di questa tabella per un utente / account senza transazioni?
  2. Prova ad aggiungere il primo record e vedi se riesci a creare un equilibrio.
  3. Crea record quando ci sono già record esistenti e controlla il saldo corrente e qualsiasi altra regola aziendale.
  4. Visualizza la tabella con i record esistenti e tutti gli altri CRUD.

Che tu ottenga questo risultato eseguendo i passaggi 1 e amp; 2 o iniziare con un database già in questo stato (ripristinare un backup?) Non sono sicuro che importi. La tua idea di scriverlo per me semplifica la gestione delle modifiche necessarie (ad esempio se ti sei dimenticato di creare un account amministratore e averne bisogno per un nuovo utente.). I file di script sono più facili da inserire nel controllo del codice sorgente rispetto ad alcuni file di backup. Ciò dipende anche dal fatto che tu distribuisca questa app.

    
risposta data 15.08.2011 - 21:42
fonte
0

Per disegnare aspetti di alcune risposte insieme e aggiungere il mio 2p ...

Nota: i miei commenti si riferiscono al test del database in particolare , e non al test dell'interfaccia utente (anche se ovviamente è simile).

I database hanno bisogno di essere testati come applicazioni front end, ma tendono a essere testati sulla base di "funziona con il front-end?" o 'i rapporti producono il risultato corretto?', che a mio parere sta testando molto tardi nel processo di sviluppo del database e non molto robusto.

Abbiamo un certo numero di clienti che utilizzano test di unità / integrazione / sistema per il loro database di data warehouse in aggiunta al solito UAT / performance / et al. test. Scoprono che con un'integrazione continua e test automatici hanno raccolto molti problemi prima di arrivare al tradizionale UAT, risparmiando così tempo in UAT e aumentando le possibilità di successo UAT.

Sono sicuro che la maggior parte sarebbe d'accordo sul fatto che un rigore simile dovrebbe essere applicato al test del database come al front end o al test del report.

La cosa fondamentale con i test è testare piccole entità semplici, assicurandone la correttezza, prima di procedere a complesse combinazioni di entità, assicurandone la correttezza prima di espandersi al sistema più ampio.

Quindi dando un contesto alla mia risposta ...

Test unità

  • ha un obiettivo di test per dimostrare che l'unità funziona, ad es. una tabella, vista, funzione, stored procedure
  • dovrebbe 'stub' le interfacce per rimuovere le dipendenze esterne
  • fornirà i propri dati. È necessario uno stato iniziale noto dei dati, quindi se esiste una possibilità di pre-test dei dati esistenti, i troncamenti / le eliminazioni dovrebbero verificarsi prima della popolazione
  • funzionerà idealmente nel proprio contesto di esecuzione
  • si risolverà da solo e rimuoverà i dati utilizzati; questo è importante solo quando gli stub non sono usati.

I vantaggi di questa operazione sono la rimozione di tutte le dipendenze esterne dal test e l'esecuzione della più piccola quantità di test per dimostrare la correttezza. Ovviamente, questi test non possono essere eseguiti sul database di produzione. Potrebbe essere che ci siano un certo numero di tipi di test che farai, a seconda del tipo di unità, tra cui:

  • controllo dello schema, alcuni potrebbero chiamarlo test "contratto dati"
  • valori di colonna che passano attraverso
  • l'esercizio di percorsi logici con diversi valori di dati per funzioni, procedure, viste, colonne calcolate
  • test caso limite - NULL, dati non validi, numeri negativi, valori troppo grandi

Test di integrazione (unità)

Ho trovato questo post di SE utile nel parlare di vari tipi di test.

  • ha lo scopo di testare per dimostrare che le unità si integrano insieme
  • eseguito su un numero di unità insieme
  • dovrebbe 'stub' le interfacce per rimuovere le dipendenze esterne
  • fornirà i propri dati, per rimuovere gli effetti delle influenze esterne dei dati
  • funzionerà idealmente nel proprio contesto di esecuzione
  • si risolverà dopo se stesso e rimuoverà i dati creati; questo è importante solo quando gli stub non vengono utilizzati.

Nel passaggio dai test di unità a questi test di integrazione, spesso ci saranno un po 'più di dati, al fine di testare una più ampia varietà di casi di test. Ovviamente, questi test non possono essere eseguiti sul database di produzione.

Questo procede quindi a Test di sistema , Test di integrazione di sistema (ovvero test end-2-end), con aumento dei volumi di dati e aumento dell'ambito. Tutti questi test dovrebbero diventare parte di un quadro di test di regressione. Alcuni di questi test potrebbero essere scelti dagli utenti per essere eseguiti come parte dell'UAT, ma UAT è i test definiti dagli utenti , non così definiti dall'IT - un problema comune!

Quindi ora che ho fornito un contesto, per rispondere alle tue domande reali

    I dati di precompilazione
  • per i test di unità e di integrazione possono causare errori di test spuri e devono essere evitati.
  • L'unico modo per garantire test coerenti è di non fare supposizioni sui dati di origine e di controllarli rigorosamente.
  • è importante un contesto di esecuzione del test separato, per garantire che un tester non sia in conflitto con un altro tester che esegue gli stessi test su un ramo diverso del codice del database controllato all'origine.
risposta data 06.04.2017 - 11:42
fonte
-3

Francamente penso che se si eseguono test unitari senza un database grosso modo delle stesse dimensioni del database di produzione esistente, si avranno molte cose che superano i test e falliscono nella produzione per le prestazioni. Ovviamente sono contrario a peró sviluppare anche un piccolo database locale per questo motivo.

E se il codice è specifico per i dati, come puoi testarlo efficacemente senza dati? Non vedrai se le query hanno restituito i risultati corretti. Perché dovresti anche prendere in considerazione la possibilità di testare su un database vuoto, tutto ciò che ti dice è se la sintassi è corretta, non se la query è corretta. Mi sembra miope. Ho visto troppe cose che girano e superano test che sono categoricamente sbagliati. Non vuoi trovarlo nei test unitari? Lo faccio.

    
risposta data 15.08.2011 - 22:35
fonte