Should I spend time prettifying unit tests?
Se la stimolazione significa rendere il test unitario più coerente e più facile da capire allora sì.
Poiché non ho scritto un libro o intervistato molte persone, posso solo passare la mia esperienza personale in questa materia. Recentemente ho trascorso una settimana su un progetto F # facendo diverse centinaia test di unità coerente, più facile da leggere e più completo. Nel processo ho imparato alcune cose e ho sviluppato un filosofia .
- Nel rendere coerente il test unitario, ho iniziato a vedere casi di test che dovevano essere aggiunti per rendere completo il test di una funzione. Poiché il test unitario era coerente, era facile individuare i casi che dovevano essere aggiunti. Fondamentalmente ho provato a spostare i parametri e il risultato di una funzione in un elemento dell'array con tutti i casi di test per una funzione in un array uno dopo il successivo. Ha fatto sì che vedere i pattern di questo input rendesse questa uscita facile perché bastava guardare l'input e l'output, non tutto il sovraccarico necessario per un test case. Poi sono passati i meccanismi del test case estraendo i parametri e il risultato e passandoli attraverso la funzione test.
Ad esempio:
let private butLastValues : (int list * int list)[] = [|
(
// idx 0
// lib.butLast.01
// System.Exception - butlast
[],
[] // Dummy value used as place holder
);
(
// idx 1
// lib.butLast.02
[1],
[]
);
(
// idx 2
// lib.butLast.03
[1; 2],
[1]
);
(
// idx 3
// lib.butLast.04
[1; 2; 3],
[1; 2]
);
|]
[<TestCase(0, TestName = "lib.butLast.01", ExpectedException=typeof<System.Exception>, ExpectedMessage="butlast")>]
[<TestCase(1, TestName = "lib.butLast.02")>]
[<TestCase(2, TestName = "lib.butLast.03")>]
[<TestCase(3, TestName = "lib.butLast.04")>]
[<Test>]
let ''List butlast'' idx =
let (list, _) = butLastValues.[idx]
let (_, result) = butLastValues.[idx]
butlast list
|> should equal result
-
Facendo in modo che il test unitario fosse più facile da leggere, divenne ovvio che erano abbastanza buoni da essere utilizzati per l'apprendimento perché la completezza del test unitario per una funzione divenne migliore di quella della documentazione; è stato un vero esempio di lavoro che non solo ha dimostrato un caso ma ha anche mostrato quale sarebbe stato il risultato, che si tratti di un risultato valido, di un'eccezione o di un mancato completamento.
-
Poiché il nostro progetto era una traduzione del codice OCaml dal "Manuale di Logica Pratica e Automated Reasoning " di John Harrison, abbiamo creato sia una versione di traduzione diretta che una versione ottimizzata. Dopo aver completato il test, è stato più semplice testare ulteriormente il codice ottimizzato e il codice normale utilizzando lo stesso test case.
Quindi, passando il tempo a lavorare con il test dell'unità a mano e in dettaglio, ho imparato di più su come funzionava il codice piuttosto che leggendo il codice. Ho iniziato a vedere i modelli nei dati di test che non sarei stato visto nel codice e ho sfruttato questo per saperne di più su come funzionava il codice.
Se visualizzi il test unitario come qualcosa che dovrebbe essere creato e lasciato in una scatola solo per essere utilizzato da strumenti automatici, penso che manchi qualcosa di significativo.