Come dovrei strutturare un test automatizzato con una dipendenza su un endpoint HTTP?

0

Sto cercando di capire meglio i test unitari e i test di integrazione. Capisco che i test unitari dovrebbero essere isolati e le loro dipendenze dovrebbero essere prese in giro. Ma sono un po 'incerto sul miglior approccio per affermare che ogni unità di classe testata si integri con le sue dipendenze.

Ecco un esempio:

Ho una classe chiamata ElasticDocumentFeeder che fondamentalmente richiama l'endpoint HTTP elastico e indicizza un documento. C'è un metodo chiamato AddDocument(Document document, logger)

Questo metodo chiama semplicemente l'endpoint utilizzando il client HTTP .net con un PUT per indicizzare un documento. Se il codice di risposta è diverso da 200, viene registrato un errore.

Voglio scrivere un test che asserisce che se un documento viene rifiutato da elastico, viene registrato l'errore.

Sono riuscito a farlo usando NUnit e Moq e sono in grado di affermare l'invocazione sul logger.

Quello che voglio sapere è: anche se sto testando questa classe, ha una dipendenza. Si aspetta che elastico sia in esecuzione su localhost: 9200. Quindi questo sarebbe considerato un test unitario o un test di integrazione?

So di poter astrarre l'endpoint HTTP in modo che possa simulare un'eccezione generata da elastico. Pensi che questo sarebbe l'approccio più corretto e di conseguenza sarebbe davvero un test unitario? O è bello avere qualcosa come l'elastico in esecuzione con un test unitario per quanto riguarda l'essere pragmatico?

Dovrei avere un test di integrazione end-to-end che copra tutto? Cioè un messaggio verrebbe prelevato da coniglio, quindi verrà effettuata una chiamata per creare un'istanza di MessageProcessor, quindi ElasticDocumentFeeder ecc.? Devo testare ogni classe individualmente contro tutte le sue dipendenze rispetto ai test di integrazione? O è questo tutto eccessivo, come avrei poi bisogno di un'istanza di coniglio e elasticsearch?

    
posta Imran Azad 23.03.2018 - 09:36
fonte

2 risposte

4

La difficoltà nel rispondere a questa domanda è che non esiste una definizione fissa dei test di unità e integrazione.

La migliore definizione che ho trovato è che un test unitario funziona da solo, cioè non ha effetti collaterali o dipendenze esterne stateful e può essere eseguito in parallelo con qualsiasi altro test unitario. C'è un utile addendum a questo, che un test unitario dovrebbe essere veloce. Tutto il resto è quindi un test di integrazione.

Utilizzando la definizione di cui sopra, il test è un test di integrazione.

Quindi passiamo alla domanda, dal momento che si tratta di un test di integrazione, dovrebbe essere meno isolato? Penso che sia folk di Thoughtworks che riassume le strutture derisorie: non sono dannose in sé, ma sono il modo in cui sono (male) utilizzate che possono renderle dannose. Prendere in giro dipendenze esterne che possono rendere i test fragili, come l'accesso ai file o agli URL, è una buona cosa. Tuttavia, è inutile prendere in giro una parte del tuo codice durante il test di un'altra parte. Questo sta portando alla ricerca dell'isolamento estremo.

Tuttavia, dal modo in cui descrivi la tua situazione, non stai cadendo in questa trappola; stai solo minimizzando le interazioni esterne. In quanto tale, sembra un test di integrazione utile, così com'è. Tuttavia (c'è sempre un "tuttavia"), anche il tuo scenario di fare un test end-to-end sembra buono. Quindi direi entrambi. Fai attenzione che il test end-to-end sia lento e fragile e quindi potenzialmente non adatto per essere eseguito insieme alla tua suite di test su ogni build e check-in.

    
risposta data 23.03.2018 - 10:40
fonte
1

Un test unitario tipicamente verifica alcuni aspetti di una classe (in lingue OO). Esiste una scuola di pensiero secondo cui un test unitario verifica alcuni comportamenti su più livelli, ma questo non è corretto (cioè un test di integrazione).

I buoni test unitari hanno un certo numero di caratteristiche, definite dal PRIMO acronimo.

veloce

I test unitari dovrebbero essere veloci

indipendente

Dovrebbe essere possibile eseguirli indipendentemente da qualsiasi dipendenza

ripetibile

Un test dovrebbe essere ripetibile senza eliminazione manuale o impostazione

Auto-controllo

Un test dovrebbe essere in grado di verificare automaticamente il proprio risultato

Timely

I test dovrebbero essere scritti contemporaneamente al codice sotto test (CUT)

    
risposta data 23.03.2018 - 10:56
fonte

Leggi altre domande sui tag