La versione breve
Il codice
Come parte di TDD, spesso ci ritroviamo con funzioni che seguono questo schema:
function onSendRequestForSelected() {
this.deselectStepsWithRequest();
this.sendRequestForSelected();
}
Ciascuna delle funzioni chiamate internamente ha i propri test di unità.
I test
I nostri test di unità per questa funzione finiscono praticamente per garantire che siano state effettuate le chiamate al corpo della funzione:
expect( iStep.deselectStepsWithRequest ).toHaveBeenCalled();
expect( iStep.sendRequestForSelected ).toHaveBeenCalled();
Il problema
Il problema è:
- I nostri test finiscono per testare chiamate di funzione anziché comportamento .
- Non siamo sicuri di quale sia esattamente lo scopo di questi test: proteggono da nient'altro che da eventuali modifiche future.
- Né servono come documentazione design .
- Testano chiaramente come piuttosto che cosa .
La versione lunga
Punto di partenza
Iniziamo con il test:
it( 'should send a request for each of the selected steps', ... )
E poi implementa:
function onSendRequestForSelected() { ... }
Fin qui tutto bene.
Nuovo requisito, refactoring
Quindi ci rendiamo conto che è necessario deselezionare i passaggi che hanno già una richiesta.
Quindi refactor:
it( 'should send a request for each of the selected steps', ... )
diventa il test per
function sendRequestForSelected() { ... }
e crea
it( 'should deselect steps that already has a request', ... )
implementato da
function deselectStepsWithRequest() { ... }
Il test dei rifiuti
e quindi introdurre:
function onSendRequestForSelected() {
this.deselectStepsWithRequest();
this.sendRequestForSelected();
}
ma non ho idea di come testarlo.
it( 'should send a request for each of the selected steps', ... )
ha poco senso poiché il test stesso assicura solo che venga chiamata una funzione.
it( 'should call sendRequestForSelected()', ... )
sembra un test dei rifiuti.
La domanda
Quindi sembra che tu abbia due opzioni, nessuna è l'ideale. Qual è il migliore?
Dato TDD iniziamo con:
it( 'should deselect steps that already has a request', ... )
it( 'should send a request for each of the selected steps', ... )
function onSendRequestForSelected() {
...
}
Opzione 1
it( 'should deselect steps that already has a request', ... )
it( 'should send a request for each of the selected steps', ... )
function onSendRequestForSelected() {
this.deselectStepsWithRequest();
this.sendRequestForSelected();
}
I problemi:
- Le funzioni secondarie attuali non sono test (se lo sarebbero sarebbero ridondanti). Pericoloso se verranno riutilizzati (considerarli necessari per altre funzioni).
Opzione 2
// No test
function onSendRequestForSelected() {
// Test for each of the following
this.deselectStepsWithRequest();
this.sendRequestForSelected();
}
I problemi:
- Questo non è veramente TDD; non è così che abbiamo iniziato.
- Nessun test da utilizzare come documentazione di progettazione. Non definiamo il comportamento.
In forma grafica
Dove vengono rilasciati i test?
- I test di F1 e F2 produrranno solo test ridondanti per S2.
- I test per S1, S2 e S3 non testeranno il comportamento di F1 e F2.