2010-09-03 4 views
5

Sto leggendo il (ancora beta) rspec book by the prag progs perché sono interessato ai test comportamentali sugli oggetti. Da quanto ho visto finora (avvertenza: dopo aver letto solo per 30 minuti), l'idea di base è che voglio assicurarmi che il mio oggetto si comporti come previsto "esternamente", cioè nel suo output e in relazione ad altri oggetti.Dovrei testare solo le interfacce pubbliche in BDD? (in generale, e in particolare in Ruby)

È vero allora che dovrei essere solo una scatola nera per testare il mio oggetto per garantire il corretto output/interazione con altri oggetti?

Questo può essere completamente sbagliato, ma dato tutto il focus su come il mio oggetto si comporta nel sistema, sembra che questa sia l'ideologia che si potrebbe prendere. Se è così, come ci concentriamo sull'implementazione di un oggetto? Come posso verificare se il mio metodo privato sta facendo ciò che voglio che faccia per tutti i diversi tipi di input?

Suppongo che questa domanda sia valida per tutti i tipi di test ?? Sono ancora abbastanza nuovo per TDD e BDD.

risposta

10

Se vuoi capire meglio il BDD, prova a pensarci senza usare la parola "test".

Invece di scrivere un test, devi scrivere un esempio di come puoi usare la tua classe (e non puoi usarla se non attraverso metodi pubblici). Stai per mostrare perché la tua classe è preziosa per altre classi. Stai definendo la portata delle responsabilità della tua classe, mentre mostri (attraverso i mock) quali responsabilità vengono delegate altrove.

Allo stesso tempo, è possibile chiedersi se le responsabilità sono appropriate e sintonizzare i metodi sulla classe per essere il più intuitivi possibile. Stai cercando un codice che sia facile da capire e da usare, piuttosto che un codice facile da scrivere.

Se riesci a pensare in termini di esempi e fornire valore attraverso il comportamento, creerai un codice che è facile da usare, con esempi e descrizioni che altre persone possono seguire. Rendi il tuo codice sicuro e facile da modificare. Se pensi al testing, lo applicherai in modo che nessuno possa romperlo. Farai fatica a cambiare.

Se è abbastanza complesso che ci siano metodi interni che si desidera testare separatamente, suddividerli in un'altra classe, quindi mostrare perché questa classe è valida e cosa fa per la classe che la utilizza.

Spero che questo aiuti!

+1

buona risposta! molto conciso! – brad

1

Sì, concentrarsi sulla funzionalità esposta della classe. I metodi privati ​​sono solo una parte di una funzione pubblica che testerai. Questo punto è un po 'controverso, ma a mio parere dovrebbe essere sufficiente per testare la funzionalità pubblica di una classe (tutto il resto viola anche il principio OOP).

+0

ya ho pensato a tutto il lato del paradigma.Ovviamente è una caratteristica (se buona o cattiva) del rubino essere in grado di ispezionare all'interno delle nostre classi, ma la maggior parte delle lingue non ti consente nemmeno di farlo. – brad

2

Penso che ci siano due problemi qui.

Uno è quello dal punto di vista BDD, in genere si esegue il test a un livello superiore rispetto dalla prospettiva TDD. Quindi i tuoi test BDD faranno valere una funzionalità più grande rispetto ai tuoi test TDD e dovrebbero sempre essere test "black box".

La seconda è che se si sente la necessità di testare metodi privati, anche a livello di unit test, che potrebbe essere un odore di codice che il codice sta violando la Single Responsibilty Principle e dovrebbe essere refactoring in modo che i metodi che ti interessano possono essere testati come metodi pubblici di una classe diversa. Michael Feathers ha tenuto un interessante discorso su questo recentemente chiamato "The Deep Synergy Between Testability and Good Design".

+1

BDD funziona a livello di unità (con RSpec, in Ruby) nonché a un livello di test di accettazione (con Cucumber). Tendo a differenziare nei mondi Java/C# chiamandoli Scenari (test di accettazione) o Esempi (test di unità). Dovrebbero comunque essere test in black box in entrambi i casi, ma per scale diverse. Se sei interessato, Feature Injection porta BDD ancora più in alto nello spazio di analisi ... – Lunivore

+0

Grazie per il chiarimento Liz - +1 per il tuo commento! Mi piace la distinzione "scenario" rispetto a "esempio". Sono tentato di modificare la mia risposta per chiarire che sto parlando di test di accettazione v. Unit test, ma il resto del thread di questo commento non ha senso. Penso che la seconda parte della mia risposta sia ancora molto valida in termini di odori di codice. – Paddyslacker