2009-06-21 7 views
5

Sto lavorando a un back-end per un ORM Python open source. La libreria include un set di 450 test case per ogni back-end, il tutto raggruppato in una gigantesca classe di test.Una classe di test può diventare un "oggetto di Dio"?

Per me, che suona come un sacco per una classe, ma non ho mai lavorato su un progetto che ha 450 casi di test (credo che questa libreria è ~ 2000 casi di test che non includono i casi di test per ogni backend). Ho ragione nel ritenere che questo sia un po 'alto (dato che non c'è davvero nessun numero magico al di sopra del quale dovresti rompere qualcosa), o non è un grosso problema per una classe di test avere così tanti test?

E anche se non si tratta di troppi casi di test, come si dovrebbe procedere al refactoring di una classe di test eccessivamente ampia? La maggior parte delle mie conoscenze in materia di refactoring riguarda l'accertamento che siano in atto test per il codice che viene refactored. Non ho mai avuto a che fare con una situazione in cui sono gli stessi test che devono essere sottoposti a refactoring.

EDIT: In precedenza, avevo detto che si trattava di test unitari, il che non è del tutto vero. Questi sono test di integrazione più appropriatamente definiti.

risposta

4

450 test in una classe sembrano molto, ma quanto è grave dipende da come sono organizzati.Se tutti sono veramente indipendenti l'uno dall'altro e dai membri della classe di test, potrebbe non essere un grosso problema, a parte il fatto che deve essere difficile individuare un test specifico.

D'altra parte, se la classe di test ha membri che sono usati solo da alcuni dei test e ignorato da altri, si tratta di un odore test chiamato Obscure prova contenenti tali cause profonde come Generale Fixture e Irrilevante Informazioni (si prega di notare il gergo tecnico - tornerò su questo).

Esistono diversi modi per organizzare i test nelle classi. I modelli più comuni sono Classe di test per classe, Classe di test per caratteristica e Classe di test per dispositivo.

Come i test strutturali sono importanti non solo durante la scrittura dei test, ma anche in seguito per motivi di manutenibilità. Solo per questo motivo, tenderei a dire che sarebbe uno sforzo utile per il refactoring dei test. In TDD, la base del codice di prova è (quasi) importante quanto la vera base di codice e dovrebbe essere trattata con lo stesso tipo di rispetto.

C'è un intero libro su questo argomento, chiamato xUnit Test Patterns: Refactoring Test Code che non posso raccomandare abbastanza. Contiene un linguaggio di pattern completo che tratta di unit test e TDD, e tutti i nomi di pattern che ho usato qui provengono da esso.

+0

"... deve essere difficile individuare un test specifico." Bingo. Questo è esattamente il problema che sto affrontando. –

2

Invece di contare il numero, vorrei considerare se sono efficaci. Cioè, quando si effettua una modifica di una singola riga, quanti test si rompono? Se stai perdendo tempo a riparare una dozzina di test di bork, allora c'è un problema; i test non dovrebbero andare oltre le stesse cose più e più volte, e se lo sono, hanno bisogno di refactoring.

Probabilmente non avrei deciso di eseguire il refactoring di una base di test dall'alto verso il basso, piuttosto di lasciarlo fluire organicamente dal reflex di test-write dello sviluppo guidato da test. Scrivi un test, implementa il tuo miglioramento, e se> 1 test fallisce, refactoring i test

2

Dividi le classi di test in modo che ogni classe si concentri sulla specificazione di un tipo di comportamento. Ad esempio, ho scritto a TDD tutorial dove c'è approssimativamente una classe di test per un tipo di comportamento (in un gioco tetris: blocchi che cadono, pezzi rotanti ecc.).

I test di refactoring sono ugualmente importanti per il refactoring del codice, perché i test dovrebbero fornire un buon valore come documentazione, che documenta l'intento di ciò che il sistema dovrebbe fare. I test sono le specifiche del sistema.

Come Todd Gardner menzionato in his answer, se molti test falliscono a causa della modifica di un metodo, molti test stanno testando lo stesso comportamento e le linee di ciò che ogni test è sfocato. Ne consegue che, quando i test falliscono, è difficile sapere cosa sia stato esattamente rotto, perché molti test apparentemente non correlati falliscono simultaneamente. Inoltre, quando è necessario modificare il comportamento del sistema, è necessario aggiornare anche i test. Ma se le responsabilità dei test non sono chiare, sarà difficile sapere come deve essere modificato un test o quando un test è obsoleto e deve essere rimosso. Potrebbe anche essere necessario cambiare molti test, anche se il cambiamento nel comportamento era piccolo.

450 test in una classe sembrano molto. Cosa testano i test, quali sono i loro nomi? Sono centrati sul comportamento del sistema (una buona cosa), o c'è una relazione 1: 1 tra loro e l'implementazione? Testano molte cose non correlate, quindi sarebbe bene dividere le responsabilità in molte classi di test.

0

Sì, ma una classe di test che è un "oggetto dio" non mi sembra un problema.

+0

Pensi che potresti spiegare un po 'più in dettaglio perché? Voglio dire, una classe non testata che è un oggetto divino è certamente un problema. Come sarebbe una classe di test diversa? –

+0

Se si stanno facendo test di integrazione, dovranno comunque sapere come funziona l'intero sistema. Inoltre, scommetto che molti dei metodi non si parlano affatto. – Joshua

2

Un insieme di test di unità Framework avrà una grande quantità di sovrapposizione nelle funzioni di avvio e configurazione. Cambiare alcuni metodi potrebbe facilmente rompere ogni test in questo caso. Soprattutto e ORM.

Detto questo, i test devono essere raggruppati per funzionalità. Query di tipo X, unioni, join, recupero DDL/schema, cache di recupero, creazione di istruzioni, ecc ...

Problemi correlati