Come testare un'app Web (inc percorsi di scrittura) per i test di accettazione o integrazione, senza accesso db?

4

Stiamo riscontrando problemi nel testare percorsi che modificano i dati nella nostra API. Ad esempio il test che cancella una risorsa fallirà se si esegue la seconda volta.

Anche a causa della logica aziendale non è possibile creare o eliminare alcune risorse tramite l'API (poiché vengono create da altri trigger o come utente non è possibile eliminare dati ma solo archivi).

Inoltre non è possibile creare risorse con un particolare ID, generato dall'API, quindi può essere difficile testare alcune situazioni speciali e non tutti i semi di prova consentono di riutilizzare i dati da altre richieste in un secondo momento. E questo potrebbe anche interrompere i test in esecuzione in modo indipendente in quanto creerà dipendenza tra i test.

Anche ridistribuire l'intera applicazione per un test non è l'ideale, poiché rallenterà l'intero sviluppo della nostra applicazione.

Quindi quale sarebbe l'approccio migliore per ri-seminare il db? Stavo pensando di aggiungere un percorso come:

DELETE /all/changes/to/just/test/user/

Ma questo rompe i principi di responsabilità, che l'API non dovrebbe essere responsabile per i test e che questo dovrebbe essere il lavoro dei test.

Aggiornamento:

L'API / web app ha uno stack complicato basato su più microservizi docker, eventi accodati in rabbitMQ, elasticsearch, mongodb, archiviazione di file esterni, autenticazione di terze parti, docker, kubernets, scalabilità orizzontale, ecc.

Quindi non è solo un DB da prendere in giro, e vorremmo avere l'ambiente di test il più vicino possibile alla produzione. Inoltre mi piacerebbe essere in grado di eseguire ed eseguire il debug dei test dall'env locale, mentre li sto creando. Come dover distribuire di nuovo l'intero stack solo per eseguire e eseguire il debug di un test, si otterrebbe un enorme overkill e si rallenterebbe molto lo sviluppo. Inoltre, come bello da usare, vorremmo utilizzare ATDD .

    
posta Stefan Rogin 23.12.2016 - 13:02
fonte

2 risposte

4

Qui ci sono diverse domande quindi proverò a rispondere a quella iniziale di "Ad esempio, il test che cancella una risorsa fallirà se si esegue la seconda volta."

Idealmente una buona pratica è che i test abbiano il proprio database. Potrebbe essere necessario seminare il database con i dati di riferimento, ma per i dati transazionali fondamentali, come quelli coinvolti nei test, le tabelle del database pertinenti devono essere vuote prima e dopo ciascun test. Dovresti creare fabbriche che possono fare questa creazione di dati.

La tua domanda ti chiede cosa fare con i dati una volta completato il test. Come si indica, se non si ha il database vuoto, non è possibile farlo avvenire tramite l'api a meno che non esponga funzionalità di eliminazione.
Se non è possibile ottenere l'accesso al database, sarà necessario scrivere test che confrontino lo stato del database tra test e test di scrittura che creano un nuovo record prima di eliminarlo tramite l'API, ecc. Fondamentalmente si finirebbe per passare un sacco di tempo questo problema e sarebbe peggiorato e complicato nel tempo, ostacolando notevolmente la tua capacità di sviluppare applicazioni. Questo deve essere comunicato molto chiaramente alla direzione. Sappi o sopporta le conseguenze mentre lo sviluppo rallenta e tu sei accusato di ciò. In questo caso, una route di eliminazione che incapsula correttamente problemi come l'integrità referenziale sarebbe sicuramente meglio che scrivere le proprie eliminazioni.

    
risposta data 23.12.2016 - 13:21
fonte
0

Potresti usare un database in-memory o file flat come SQLite. Dovrebbe essere facile da usare nell'ambiente di test.

Se la tua app ha una dipendenza da un particolare database, potrebbe risultare più complicata. In tal caso, non hai altra scelta che dire al tuo manager che non puoi eseguire test di integrazione senza, beh, l'integrazione. Il tuo server CI deve essere completamente in grado di eseguire un'istanza dei tuoi sistemi di database di produzione per il tuo test, in caso contrario questo è un problema serio.

La scelta migliore per i test è quella di impostare i dati di esempio e quindi eseguire il test all'interno di una transazione che viene sempre ripristinata. Quindi ogni test dovrebbe vedere una copia non modificata del database.

Modifica:

Questo vale per tutti i tuoi deps. È necessario disporre di deps nello sviluppo e nel test. Questo è il motivo per cui le persone cercano di minimizzare i loro errori. Rimuovere la dipendenza o renderla presente in dev e test.

    
risposta data 23.12.2016 - 14:52
fonte