Testare il codice in generale non è facile. Se lo fosse, lo avremmo fatto tutto molto tempo fa, e non avremmo fatto così tanto solo negli ultimi 10-15 anni. Una delle maggiori difficoltà è sempre stata nel determinare come testare il codice che è stato scritto in modo coeso, ben ponderato e testabile senza interrompere l'incapsulamento. Il preside BDD suggerisce che ci concentriamo quasi interamente sul comportamento, e in qualche modo sembra suggerire che non devi davvero preoccuparti dei dettagli interiori in misura così grande, ma questo può spesso rendere le cose abbastanza difficili da testare se ci sono molti metodi privati che fanno "cose" in un modo molto nascosto, in quanto può aumentare la complessità complessiva del test per gestire tutti i possibili risultati a un livello più pubblico.
Il deridere può aiutare in una certa misura, ma di nuovo è focalizzato abbastanza esternamente. L'iniezione delle dipendenze può anche funzionare abbastanza bene, sempre con simulazioni o doppie di prova, ma ciò può anche richiedere che tu esponga elementi tramite un'interfaccia o direttamente, che altrimenti avresti preferito preferire rimanere nascosto - questo è particolarmente vero se desideri avere un buon livello di sicurezza paranoico su certe classi all'interno del tuo sistema.
Per me, la giuria non ha ancora deciso se progettare le tue lezioni in modo che siano più facilmente verificabili. Questo può creare problemi se ti trovi nella necessità di fornire nuovi test mantenendo il codice legacy. Accetto che dovresti essere in grado di provare assolutamente tutto in un sistema, eppure non mi piace l'idea di esporre - anche indirettamente - gli interni privati di una classe, solo per poter scrivere un test per loro.
Per me, la soluzione è sempre stata quella di adottare un approccio abbastanza pragmatico e combinare una serie di tecniche per soddisfare ogni situazione specifica. Uso molti doppi di test ereditati per esporre proprietà e comportamenti interni per i miei test. Prendo in giro tutto ciò che può essere collegato alle mie lezioni e, laddove ciò non comprometta la sicurezza delle mie lezioni, fornirò un mezzo per sovrascrivere o iniettare comportamenti ai fini del test. Prenderò anche in considerazione la possibilità di fornire un'interfaccia più guidata dagli eventi se ciò contribuirà a migliorare la capacità di testare il codice
Dove trovo qualsiasi codice " non verificabile " , cerco di vedere se riesco a refactoring per rendere le cose più testabili. Dove hai un sacco di codice privato nascosto dietro le quinte, spesso troverai nuove classi in attesa di essere lanciate. Queste classi potrebbero essere utilizzate internamente, ma spesso possono essere testate indipendentemente con comportamenti meno privati e spesso successivamente con livelli di accesso e complessità inferiori. Una cosa che devo fare attenzione, tuttavia, è scrivere il codice di produzione con il codice di test integrato. Può essere allettante creare " test bugs " che comportino l'inclusione di orrori come questo if testing then ...
, il che indica un problema di test non completamente decostruito e non completamente risolto.
Potresti trovare utile leggere il libro xUnit Test Patterns di Gerard Meszaros , che copre tutto questo genere di cose in modo molto più dettagliato di quanto io possa entrare qui. Probabilmente non faccio tutto ciò che suggerisce, ma aiuta a chiarire alcune delle situazioni di test più complicate da affrontare. Alla fine della giornata, vuoi essere in grado di soddisfare i tuoi requisiti di test pur applicando i tuoi progetti preferiti e aiuta a comprendere meglio tutte le opzioni al fine di decidere meglio dove potresti dover scendere a compromessi.