Preferisci test all'interfaccia tramite test sull'implementazione.
It's my understanding that private methods are untestable
Dipende dal tuo ambiente di sviluppo, vedi sotto.
[private methods] shouldn't be worried about because the public API will provide enough information for verifying an object's integrity.
È vero, TDD si concentra sul test dell'interfaccia.
I metodi privati sono dettagli di implementazione che potrebbero cambiare durante ogni ciclo di fattore di fattore. Dovrebbe essere possibile ri-fattore senza cambiare l'interfaccia o il comportamento black-box . In effetti, questo è parte del vantaggio di TDD, la facilità con cui è possibile generare la sicurezza che cambia all'interno di una classe non influirà sugli utenti di quella classe.
Well, it's possible for me to make an object that has only private methods and interacts with other objects by listening to their events. This would be very encapsulated, but completely untestable.
Anche se la classe non ha metodi pubblici, i suoi gestori di eventi sono la interfaccia pubblica , ed è contro quella interfaccia pubblica che tu può testare.
Poiché gli eventi sono l'interfaccia, sono gli eventi che dovrai generare per testare quell'oggetto.
Cerca di utilizzare oggetti fittizi come colla per il tuo sistema di test. Dovrebbe essere possibile creare un semplice oggetto mock che genera un evento e preleva il cambiamento di stato risultante (possibile da un altro oggetto fittizio del ricevitore).
Also, it's considered bad practice to add methods for the sake of testing.
Assolutamente, dovresti essere molto cauto di esporre lo stato interno.
Does this mean TDD is at odds with encapsulation? What is the appropriate balance?
Assolutamente no.
TDD non dovrebbe cambiare l'implementazione delle tue classi se non per semplificarle (applicando YAGNI da un punto precedente).
La migliore pratica con TDD è identica alla migliore pratica senza TDD, basta scoprire perché prima, perché stai usando l'interfaccia mentre la sviluppi.
I'm inclined to make most or all of my methods public now...
Questo sarebbe piuttosto buttare fuori il bambino con l'acqua del bagno.
Non dovresti aver bisogno di per rendere pubblici tutti i metodi in modo da poterti sviluppare in un modo TDD. Vedi le mie note qui sotto per vedere se i tuoi metodi privati non sono realmente testabili.
Un'occhiata più dettagliata ai test dei metodi privati
Se tu devi assolutamente testare un comportamento privato di una classe, a seconda della lingua / ambiente, potresti avere tre opzioni:
- Metti i test nella classe che vuoi testare.
- Metti i test in un altro file di classe / sorgente & esporre i metodi privati che desideri testare come metodi pubblici.
- Utilizzare un ambiente di test che ti consenta di mantenere separati il codice di test e di produzione, consentendo comunque l'accesso al codice di prova ai metodi privati del codice di produzione.
Ovviamente la terza opzione è di gran lunga la migliore.
1) Metti i test nella classe che vuoi testare (non ideale)
L'archiviazione dei casi di test nello stesso file di classe / sorgente del codice di produzione sotto test è l'opzione più semplice. Ma senza molte direttive o annotazioni pre-processore finirai con il codice di prova che gonfia inutilmente il tuo codice di produzione e, a seconda di come hai strutturato il tuo codice, potresti finire per esporre accidentalmente l'implementazione interna agli utenti di quel codice.
2) Esporre i metodi privati che desideri testare come metodi pubblici (non è una buona idea)
Come suggerito, questa pratica è molto scarsa, distrugge l'incapsulamento e esporrà l'implementazione interna agli utenti del codice.
3) Utilizzare un ambiente di test migliore (opzione migliore, se disponibile)
Nel mondo di Eclipse, 3. può essere ottenuto usando frammenti . Nel mondo C #, potremmo utilizzare classi parziali . Altri linguaggi / ambienti hanno spesso funzionalità simili, devi solo trovarlo.
Assumendo ciecamente 1. o 2. sono le uniche opzioni che potrebbero far sì che il software di produzione sia gonfio di codice di test o di interfacce di classe cattive che lavano il loro lino sporco in pubblico. * 8' )
- Tutto sommato - è molto meglio non testare però con l'implementazione privata.