"Sincronizzazione" unit-test per diversi livelli

0

Considerare i test unitari per due (o più) livelli conseguenti in applicazioni Web, backend, ad esempio viste (si tratta di parametri del modulo di analisi, rendering della risposta) e azioni (logica dell'applicazione). Nella vista, le chiamate alle azioni vengono prese in giro. Nelle azioni vengono derise le chiamate al livello sottostante. I test sono veloci, ma sono meno utili di quanto possano essere, perché la connessione tra i livelli richiede la sincronizzazione e i test di integrazione sono lenti e rari (in teoria). Sincronizzazione significa che le funzioni / metodi simulati e derisi sono sincronizzati. Altrimenti verifichiamo una simulazione, che potrebbe facilmente perdere la connessione alla realtà se non aggiornata, e quindi la potenza dei test unitari è diminuita.

La domanda è: qualcuno ha già avuto un'idea su come mantenere le simulazioni di livello superiore con "interfacce" di livello inferiore con l'obiettivo di rendere il test più manutenibile mentre è ancora veloce? Interfacce meno stabili sono ovviamente di interesse.

Ho sempre preferito test funzionali, più integrali perché tendono a catturare più regressioni e bug che test di unità separate. In alcuni casi, la logica applicativa è solo un semplice script di transazione con N azioni, quindi il mocking non offre alcun vantaggio ai test (il test unitario segue da vicino l'implementazione). Tuttavia, quelli sono lenti, quindi sto cercando di venire con un meccanismo, e forse inventando la ruota.

Soprattutto nei linguaggi dinamici di livello superiore, come Python.

Alcuni esempi.

function my_script():
    callA()
    callB()
    callC()

I test appariranno come (pseudocodice):

monkeypatch(callA, dummyA)
monkeypatch(callB, dummyB)
monkeypatch(callC, dummyC)

my_script()

assert dummyB.called_after(dummyA)
assert dummyC.called_after(dummyB)
  • questo non prenderà callD() dovrebbe essere aggiunto a my_script o effetti collaterali all'interno di quelle funzioni o anche cambiamenti nelle loro firme (per esempio, callB modificato per richiedere un parametro). Il test passerà ancora. In questo caso il test dell'unità è inutile.
posta Roman Susi 22.10.2018 - 07:24
fonte

1 risposta

3

Mi piace davvero usare la combinazione di falsi e test che funzionano contro l'implementazione sia reale che falsa. Questo è utile in caso di falsi database o altre API.

Questo è il modo in cui il test contro DB api sarà simile a:

In questo scenario, alcune logiche di business necessitano di un database. Di cosa ha bisogno del database è in Database Api. I test di business logic testano la logica di business insieme a un falso database in memoria, possibilmente solo liste di strutture. Ciò consente ai test di logica aziendale di essere veloci e isolati, anche quando ce ne sono molti. Il secondo set è il test Api del database. Questo set esegue gli stessi test due volte, una volta contro la falsa implementazione e la seconda contro l'implementazione della produzione reale. Ciò garantisce che il comportamento delle due implementazioni sia lo stesso. Ovviamente l'implementazione reale manterrà i dati correttamente, mentre la memoria sarà solo locale per caso d'uso singolo.

Il grande vantaggio di questo progetto è che i test di logica aziendale verranno eseguiti come test di unità veloci, quindi possono essercene molti e possono fare una logica complessa senza preoccuparsi di utilizzare un'implementazione lenta e reale. Mentre i test Databse Api possono solo testare query specifiche e non preoccuparti della logica di business.

    
risposta data 22.10.2018 - 09:30
fonte

Leggi altre domande sui tag