Ho bisogno di una suite di test unitari per la classe logica aziendale interna? Dal momento che sta per replicare la suite di test di accettazione per il 90% [duplicato]

4

Sono nuovo di TDD e mi sto interrogando su methodolody.

Dato:

Un semplice progetto che implementa la funzionalità di, ad esempio, un calcolatore della console.

Ha la seguente struttura:

  1. Una classe di alto livello abbastanza semplice che prende l'input della console, la delega a una classe buisness-logic e mostra l'output nella console con una formattazione di fantasia.
  2. La classe logica buisness che fa tutti i calcoli e che è relativamente complessa.

Supponiamo inoltre di disporre di una serie completa di test di accettazione per l'intero progetto, che viene eseguita tramite l'interfaccia utente.

Ho bisogno di una suite di test unitari per la classe logica aziendale interna? Dal momento che sta per replicare la suite di test di accettazione per il 90%.

Domande aggiuntive, ma strettamente correlate:

  1. La risposta alla domanda rimarrà la stessa se, ad esempio, la suite di test di accettazione impiega 30 secondi per essere eseguita? 5 minuti? 1 ora?

  2. Se la classe di business logic interna non è ancora implementata, ho bisogno di scrivere quel seme di unit test per guidare il suo sviluppo, o va bene solo con i test di accettazione?

posta Nikolay Rys 12.03.2014 - 08:05
fonte

5 risposte

6

Do I need a suite of unit tests ...

I test unitari non sono di per sé fini - dovresti chiedere "Ho bisogno di una suite di test unitari se voglio raggiungere un determinato obiettivo". Se il tuo obiettivo è solo quello di assicurarti che il software che stai scrivendo si comporti correttamente "come una scatola nera" dall'esterno, hai solo bisogno di test di accettazione.

Ma se il tuo obiettivo è anche che la tua logica di business sia strutturata correttamente in piccoli componenti (invece di una grande "divinità"), e ognuno di quei componenti dovrebbe comportarsi correttamente, allora avrai bisogno di test unitari per ciascuno di essi componenti. La ragione per avere componenti è che questo mantiene il tuo software più evolutivo (diventerà più facile aggiungere nuovi requisiti) e più manutenibile (quando hai aggiunto un nuovo requisito, e hai dovuto cambiare il codice esistente, e i test di accettazione mostrano che tu introdotto un bug, i test unitari potrebbero aiutarti a individuare la causa principale di quell'errore più rapidamente).

Quindi l'essenza è - i test unitari hanno senso solo in presenza di unità .

If the inner business-logic class is not yet developed, do I need write that suit of unit tests to guide its development?

TDD è non su come scrivere una suite di test in anticipo. Si tratta di scrivere test unitari e codice "quasi in parallelo" ("scrivi test - scrivi codice - refactor - risciacqua e ripeti").

EDIT (al tuo commento): se hai test di accettazione, il tuo programma funziona come dovrebbe, non ci sono ragioni dirette per introdurre test di unità ancora .

Ma, non appena devi modificare qualcosa nel tuo codice (probabilmente a causa di nuovi requisiti) e vuoi fare TDD, allora è una buona idea iniziare a scrivere test di unità per esattamente le parti del codice che vuoi cambiare (e non una "suite di test completo").

Forse inizi con un test per una funzione per verificarne il comportamento corrente ("verde"). I test di accettazione ti impediranno di introdurre un bug in questa fase. Quindi si modifica il test o si aggiunge un test aggiuntivo per verificare il comportamento previsto (che rende il test dell'unità "rosso"). Successivamente aggiungi la nuova funzionalità alla tua funzione (che ti rende nuovamente verde). E ora arriva la parte importante: controlli se la tua funzione è diventata così complessa da renderti più efficiente da un refactor ora - cosa che può essere fatta molto facilmente a causa dei test che hai appena introdotto.

Quindi l'idea dei test unitari (in un contesto TDD) è non per duplicare lo scopo dei test di accettazione, ma per aiutarti con la tua vera codifica e miglioramenti di progettazione di basso livello.

    
risposta data 12.03.2014 - 08:44
fonte
1

Supponiamo che tu abbia almeno 3 livelli di codice, un livello di presentazione, un livello di applicazione / dominio e un livello di persistenza.

Poiché il test di accettazione esercita l'intero stack nella tua applicazione, una volta che hai riscontrato un bug, ci sono molti punti in cui il bug potrebbe essere stato introdotto e dopo la prima implementazione iniziale del codice per un singolo caso di test , potrebbero facilmente esserci più bug presenti. Rilevare bug / bug può richiedere una notevole quantità di tempo.

Ma se sviluppi ciascuno di questi livelli in un modo guidato dai test, allora c'è una probabilità molto più alta di trovare i bug in anticipo e la posizione del bug è più isolata. Quindi probabilmente impiegheresti molto meno tempo a sistemare i bug.

Ricorda inoltre che TDD parla di test guida dell'implementazione. Quando pratichi il TDD, cambi costantemente l'attenzione dai test all'implementazione. Questo cambiamento di contesto è salutare per i processi benché è molto più facile scoprire schemi nel codice. Se invece ti concentri esclusivamente sull'implementazione, il tuo cervello tende ad essere bloccato sui dettagli dell'implementazione e non riesce a vedere il quadro generale *.

Quest'ultima parte, non ho scritto un motivo per decidere se dovresti o non dovresti scrivere test unitari per singoli componenti software. Ma più perché hai menzionato TDD come parte della domanda, e volevo mettere a fuoco, che TDD non è solo su come scrivere test di unità - è più di un processo di sviluppo.

Per ulteriori informazioni sul processo di TDD, posso consigliare il libro di Ken Beck: Sviluppo basato su test: per esempio

* Uno dei motivi per cui la programmazione della coppia è efficace è perché la persona che non sta scrivendo è più libera di pensare al quadro generale.

    
risposta data 12.03.2014 - 09:46
fonte
0

Hai più responsabilità nel tuo esempio; tutti dovrebbero essere coperti dai propri test.

  1. Si dice che si prenda l'input della console, quindi probabilmente è necessario qualcosa che analizzi e convalidi gli argomenti. Cosa succede se per esempio non si passano i numeri, ma il testo? Quali sono i limiti superiore e inferiore degli argomenti che sei disposto ad accettare? Ecc ...
  2. Hai le stesse classi di business logic, che puoi facilmente guidare attraverso i test
  3. Hai un formattatore, che può anche essere guidato dai test

Puoi usare i test di accettazione come una sorta di test di alto livello, che scriveresti per primo. Fallisce naturalmente, perché invocherete tutti i tipi di classi che ancora non esistono. Ma a questo punto avrai un'idea approssimativa dei componenti di cui avrai bisogno.
Quindi puoi guidare ciascuno dei singoli componenti attraverso i test e quando hai finito, anche il test di accettazione dovrebbe passare.

    
risposta data 12.03.2014 - 08:45
fonte
0

Se la tua classe di business logic non è ancora stata scritta, i tuoi test di accettazione possono essere completi solo per ciò che è stato scritto e non per quello che farà il programma. Una delle idee di TDD è di scrivere i test in modo tale che non riescano ora, scrivere il codice, e poi vedere se tutti i test passano, quando lo fanno, allora sai che hai finito. Questo funziona solo se i test scritti in modo completo definiscono quali sono i requisiti del progetto, a livello aziendale.

Devi decidere che cosa dovrebbero fare i test.

Il loro scopo è farti sapere quando hai finito di scrivere il codice, nel qual caso devi avere i test completi per definire quali sono i tuoi requisiti, vederli come un'enumerazione di tutti i criteri di accettazione che renderanno il tuo stack titolari felici.

Il punto su di loro è quello di darti confidenza nella qualità dei codici, questo ti permetterà di ridefinire il codice e verificare che faccia ancora quello che dovrebbe. In questo caso è necessario concentrarsi maggiormente sulla verifica delle interfacce tra i componenti, in modo che le modifiche interne possano mostrare lo stesso comportamento esterno.

È il momento di verificare che, durante lo sviluppo, uno sviluppatore non abbia violato i vecchi requisiti o che soddisfi nuovi requisiti, nel qual caso la velocità della suite potrebbe avere un impatto. Se si dispone di un ciclo molto stretto in cui gli sviluppatori possono eseguire i test così rapidamente che lo fanno spesso, con il tempo di una qualità nota molto breve, è necessario includere solo i test che possono essere eseguiti rapidamente. Questi test possono quindi essere suddivisi in diverse suite da eseguire in momenti diversi, ad es. nell'editor dopo il salvataggio, sul commit, accanto a una build, dopo la build, settimanalmente, continuamente ecc.

Is it enough to use those acceptance tests which are already in place, or I need to develop additional unit tests?

Dipende. Qual è il punto di aggiungere questi nuovi test? Per quale obiettivo ti stai sforzando? I test di accettazione sono ottimi da tenere in considerazione se forniscono informazioni aggiuntive, confidenza con il codice e aiutano a identificare i bug. Potresti non essere d'accordo con tutto in questo pezzo ma dai un'occhiata a Why Most Unit Testing è Waste come suggerisce che anche mantenere i vecchi test potrebbe non essere così prezioso. Decidi cosa vuoi e struttura il tuo approccio di prova.

    
risposta data 12.03.2014 - 09:49
fonte
0

"I test di accettazione per l'intero progetto, che vengono eseguiti attraverso l'interfaccia utente" non sono programmabili. Non puoi automatizzarli e fare un'integrazione continua.

Questo è il motivo per cui devi comunque avere test di unist.

Anche la maggior parte delle volte, i "test di accettazione" non verificano casi limite, eccezioni ecc.

    
risposta data 12.03.2014 - 14:20
fonte

Leggi altre domande sui tag