12

Nella mia azienda, abbiamo una serie crescente di test di integrazione utilizzando JUnit in un'applicazione Web Java. Ogni test utilizza alcuni file XML esterni specifici per popolare il database con i dati necessari per il test. Il problema è:Manutenzione costosa con dati di test automatizzati

  1. Quando c'è un cambiamento del modello, ci vorrà molto tempo per correggere tutti i file XML (abbiamo centinaia di file XML, molti di loro con ridondanza).
  2. La complessità della creazione di un file XML scoraggia manualmente il programmatore per esplorare diversi scenari.
  3. Non abbiamo un collegamento tra i dati di test e il test (ad esempio, al test non conosco il "nome" dell'utente inserito dall'XML). Potremmo codificare in modo rigido le informazioni di cui abbiamo bisogno, ma aumenterebbe anche il tempo di manutenzione per mantenere sincronizzati sia i dati XML che quelli codificati.

Affrontando questo problema, ho iniziato a pensare di usare il CRUD del proprio sistema per generare i dati di test per ogni test. All'inizio di ogni test eseguirò alcuni metodi per mantenere i dati desiderati per il test. Nella mia visione, sarebbe risolvere tutti i 3 problemi poiché:

  1. Le modifiche apportate al modello di una modifica del CRUD comunque, quindi non sarebbe più necessario per correggere i dati di test.
  2. Sarebbe più semplice costruire, testare i dati perché non dovremmo preoccuparci di cose come l'identificazione id e la chiave esterna dell'entità manualmente.
  3. Avrei tutti i dati importanti nelle variabili con la sincronizzazione garantita dall'IDE.

ma, per me, manca esperienza e conoscenza per iniziare questo approccio. La domanda è: Questa soluzione è efficace? Questo approccio causa altri problemi? Dove posso trovare questo approccio in letteratura? C'è una soluzione migliore ai problemi elencati?

+1

Potrebbe essere una domanda migliore per programmers.stackexchange – NESPowerGlove

+2

Ho una risposta al punto 3: creare file XML che incapsulino sia i dati di test che i risultati previsti. Vorrei anche suggerire di dare un'occhiata a TestNG, che supporta l'alimentazione di più test case in un unico metodo di test. – biziclop

+0

Memorizza i dati di test nel database e genera l'XML da quello. È più semplice modificare i dati in SQL e quindi creare l'XML. – Mike

risposta

1

La chiave per migliorare la manutenzione è mantenere DRY. L'installazione dei dati di test non deve essere ridondante e, se la tecnologia di test non offre alcun mezzo efficace di riutilizzo, si utilizza la tecnologia sbagliata.

La scrittura del codice Java per l'impostazione dei dati di test offre strumenti familiari e utili per migliorare il riutilizzo del codice tra i test. Offre inoltre un migliore supporto per il refactoring rispetto all'XML e rende esplicito il collegamento tra i dati di test e il codice di test, poiché è lo stesso file sorgente (o lo stesso metodo!). Tuttavia, richiede che i test siano scritti e gestiti da programmatori (non analisti aziendali, manager o tester che non conoscono Java).

Pertanto, se i dati dei test sono per lo più creati e gestiti dai programmatori, lo farei in Java, attraverso il livello CRUD (o anche un livello dominio completo) dell'applicazione reale. Se tuttavia la maggior parte dei dati di test proviene da un'esportazione di dati, o è stata creata da persone che non sono programmatori, un approccio puramente basato sui dati può essere più adatto. È anche possibile combinare questi approcci (cioè scegliere la strategia più appropriata per ciascuna entità).

Esperienza personale: il nostro team ha utilizzato i test di integrazione con DBUnit, ma è passato alla configurazione dei dati di test come parte del codice di test utilizzando il nostro livello di accesso ai dati reali. In tal modo, i nostri test sono diventati più rivelatori di intenzione e più facili da mantenere. Lo sforzo di test è stato ridotto, ma la copertura del test è stata migliorata e sono stati scritti più test con meno stimoli. Ciò è stato possibile perché i test sono stati interamente scritti e gestiti dagli sviluppatori.

4

Sembra che il sistema esistente utilizzi qualcosa come DBUnit, dove i test iniziano con un database pulito, il test include una fase di installazione che carica i dati da uno o più file XML nel database, quindi il test viene eseguito su quei dati .

Ecco alcuni dei vantaggi di questo tipo di approccio:

  • Se avete un problema con il livello CRUD allora, che non avrà un impatto l'impostazione dei dati. Quando qualcosa va storto, dovresti ottenere un errore di test per errore, non un errore per ogni impostazione correlata che non riesce.

  • Ogni test può essere molto esplicito su esattamente quali dati sono necessari per eseguire il test. Con un modello di dominio a volte tra cose come associazioni opzionali e caricamento lento, quali oggetti vengono caricati potrebbero non essere certi. (Qui sto pensando in particolare a Hibernate dove molte volte le conseguenze di una mappatura possono essere complicate.) Al contrario, se i dati sono configurati in modo più dichiarativo, affermando quali file vanno in quale tabella, lo stato iniziale è esplicito.

Mantenere i test semplici, espliciti e minimamente accoppiati ad altre parti significa che c'è meno da capire e meno da sbagliare. Se i tuoi test diventano così complicati da rendere meno probabile qualsiasi problema con il codice sotto test rispetto al test, le persone si scoraggeranno dall'eseguire e aggiornare i test.

Con DBUnit è possibile scrivere uno script per automatizzare la creazione del codice XML dal contenuto del database, in modo da poter ricreare lo stato necessario e salvarlo come XML. Non dovrebbe esserci alcuna necessità di generare manualmente i dati del test.

È possibile che i dati di test divengano frammentari e difficili da aggiornare, specialmente se sono stati creati in modo ad-hoc senza alcuna possibilità di riutilizzo. Potresti considerare di tornare indietro attraverso i test e suddividere i dati di configurazione del test in pezzi che puoi riutilizzare.

I punti di dolore che descrivi non mi sembrano come se richiedessero misure estreme come la ripetizione di tutte le impostazioni di prova. Anche se lo fai, vorrai comunque refactoring i dati di test. Forse utilizzare un progetto più piccolo come terreno di prova per cambiamenti più grandi e apportare piccole modifiche incrementali alla maggior parte del codice esistente.

+0

Non ho il tuo secondo punto elenco: perché associare i dati con un singolo test è più difficile in Java che in XML? – meriton

+0

@meriton: Ho provato ad aggiungere un po 'più di dettaglio qui –

+0

@NathanHughes, grazie per aver risposto Il problema principale che hai citato, per me, è stato l'impatto di un problema nella crude influenza su molti test. Per mitigare questo punto, stavo pensando di rendere ogni CRUD utilizzato per costruire dati come test. Quindi ogni test avrebbe eseguito una serie di altri "test crud" per costruire i dati del test. Penso che questo mi darebbe una precisione in cui la causa di test non funzionanti e una maggiore copertura, anche se so che sto infrangendo la regola dell'indipendenza. Cosa ne pensi di questo? E ripetere le impostazioni di tutto il test è troppo estremo come hai detto, stavo pensando a questo nuovo test –

Problemi correlati