Quando si prova è OK usare un metodo del soggetto per testare un altro metodo del soggetto?

6

Ho due metodi nella stessa classe helper che crea un'immagine ( createImage ) e una che confronta due immagini ( compareImages ).

Image createImage(Data data);
Boolean compareImages(Image from, Image to);

Voglio controllare il ritorno di createImage rispetto a un'immagine esistente. Per fare questo ho bisogno di un metodo esattamente come compareImages .

Va bene usare compareImages per convalidare createImage anche se entrambi appartengono all'oggetto? Questo mi fa male.

    
posta RyanCosans 19.01.2015 - 14:49
fonte

3 risposte

6

È importante capire che un singolo metodo potrebbe non essere la tua "unità". Per dare un esempio forzato, se (per qualche motivo) hai creato una classe con metodi pubblici:

Add(object key, object value);
Get(object key);

che ha appena avvolto un dizionario privato, sarebbe inconcepibile testare solo uno di questi metodi alla volta, indipendentemente dall'altro.

Per la situazione esatta che descrivi, tuttavia, potrebbe non essere così chiaro. Sembra piuttosto che essere intrinsecamente dipendenti l'uno dall'altro per la loro funzione come nell'esempio precedente, i tuoi metodi sono collegati solo in quanto uno può essere utile in un test dell'altro.

In questo caso, potrebbe essere utile iniziare con l'idea di duplicare il metodo B esattamente nel codice di test e chiedendo se questa è una violazione di DRY. Ovviamente stai ripetendo il tuo codice, ma come dimostrato da Mathias Verraes , questo non significa sempre una violazione DRY. Un buon modo di pensare a questo è: quando uno di questi metodi cambia, l'altro richiederà sempre lo stesso cambiamento?

È difficile per me giudicare senza conoscere i metodi esatti, ma è abbastanza probabile che tu voglia, ad esempio, che la tua versione di prova di B non esegua alcuna convalida della versione di produzione o simile. In questo caso, avere due versioni potrebbe andare bene.

Ci sono ulteriori compromessi pratici:

  • Se usi il metodo B nel metodo di test A, un bug nel metodo B potrebbe mascherare un bug nel metodo A, o almeno ti impedirà di conoscere il vero risultato del test del metodo A. Questo è simile al motivo per cui le persone in genere cercano di evitare più affermazioni.

  • D'altra parte, se si effettua una versione di prova del metodo B e si consente di variare indipendentemente dalla versione di produzione, la versione di prova non sarà altrettanto testata, il che potrebbe essere un problema se il metodo è sufficientemente complesso o soggetto a modifiche.

risposta data 19.01.2015 - 15:14
fonte
9

Nonostante la consolidata saggezza nello scrivere i test unitari, Martin Fowler ha detto che la sua idea di un'unità è generalmente

"a bunch of closely related classes and treat them as a single unit. Rarely I might take a subset of methods in a class as a unit."

Quindi non c'è una vera ragione per cui non dovresti sottoporre a test unitario un paio di metodi strettamente correlati come un'unica unità. Ovviamente potresti voler testare il metodo B passando in modo indipendente in 2 immagini che conosci uguali, o sono diverse per assicurarti che funzioni, ma una volta testato - usalo come condizione di test per il tuo metodo di generazione.

Non c'è niente di brutto nell'essere pratico, è brutto quando l'ideologia ti costringe a soffrire.

    
risposta data 19.01.2015 - 14:55
fonte
0

Un test unitario dovrebbe essere in grado di utilizzare qualsiasi codice o logica che sia correttamente testato.

Un test unitario dovrebbe avere una logica minima in esso. Dovrebbe essere semplice per la sua prova e che si può guardare e ragionare su di esso.

Reimplementare un metodo equals viola DRY. In tal modo, introduce la possibilità di avere divergenze uguali e un errore di inserimento nel codice effettivo da testare poiché utilizza ancora una vecchia copia del codice. Aggiunge anche una logica non banale al test dell'unità.

Quindi, tornando al primo punto - se equals è stato testato correttamente, non vi è alcun problema con l'utilizzo in un altro test di unità. In effetti, si dovrebbe incoraggiare il suo uso. Il pericolo di passaggi falsi in questo test sarebbe solo un problema se i test per equals dovessero mancare a tali condizioni e non riuscire a fallire.

Non esporti ad altri bachi nel tuo codice usando più di un valore di codice unitario strettamente definito nel test. Ti esponi solo a non cogliere un bug in un test unitario più che idealmente complesso se il codice che sfrutta non è idealmente testato da solo.

Non farti intrappolare nel dogma di "un test unitario deve essere ..." Se il test ha più senso codice di leveraging scritto che hai già testato, scrivi il test che ha senso.

    
risposta data 26.01.2016 - 22:18
fonte

Leggi altre domande sui tag