Convenzione di denominazione per i pacchetti di test


11

In realtà stiamo denominando i nostri pacchetti di test proprio come le loro controparti da testare. Quindi finiamo con questa struttura:

src/main/java
    com.hello.world
        helloWorld.java
src/test/java
    com.hello.world
        helloWorldTest.java

Mi è sempre sembrato che questo non sia abbastanza intelligente poiché non puoi distinguere tra "test" e "to-test" se fornito solo con il nome del pacchetto. D'altra parte non ho davvero trovato un caso in cui questo sia importante in qualche modo. È buona norma avere le stesse convenzioni di denominazione per entrambi i pacchetti (per i casi di test e le classi di origine)? In caso contrario, quale sarebbe un approccio migliore?


1
Non ho idea se è una buona pratica, ma è popolare. L'altra opzione (per inserire "Test" nel nome del pacchetto, nei nomi dei metodi, ecc.) Presenta un po 'troppo di "Denominazione dei puffi". Come dici tu, è difficile pensare al caso in cui l'incapacità di "distinguere tra" test "e" to-test "se fornito solo con il nome del pacchetto" sarebbe un problema.
David Arno,

@DavidArno Grazie per il tuo contributo :) Come evitare i nomi dei puffi allora? Voglio dire, finiremmo con com.hello.world.test.helloWorld.java, no?
OddDev,

Il problema "puffo" è maggiore quando si ha un metodo XXXTest()in com.hello.world.test.helloWorldTest.java. Un consiglio generale sarebbe quello di far apparire "Test" solo una volta nel percorso, quindi (a) utilizzare test nel nome del pacchetto (e denominare il file di test uguale al file in prova) oppure (b) rendere il nome del pacchetto il stesso e aggiungi "test" al nome del file / classe.
David Arno,

@DavidArno Ah, grazie per il chiarimento! Ho sbagliato il tuo primo commento. Ora ho capito.
OddDev,

Beh, direi che, se non fosse chiaro, ho sbagliato il mio primo commento :)
David Arno,

Risposte:


11

Questa è una buona convenzione.

A volte si desidera scrivere unit test anche per classi e metodi privati ​​del pacchetto. Non sarai in grado di chiamarli da una classe di unit test inserita in un altro pacchetto.

Non ci dovrebbe essere alcuna confusione sull'avere classi di unit test nello stesso spazio dei nomi in quanto non dovrebbero trovarsi nel percorso della classe durante la compilazione o l'esecuzione del codice di produzione.

Ecco un esempio di un piccolo modulo con un'interfaccia pubblica, una classe factory pubblica e due classi di implementazione pacchetto-private:

src/main/java:
    com.hello.transmogrifier
        public interface Transmogrifier
        public class TransmogrifierFactory
        class MapTransmogrifier implements Transmogrifier
        class ListTransmogrifier implements Transmogrifier

scr/test/java:
    com.hello.transmogrifier
        public class TransmogrifierFactoryTest
        public class MapTransmogrifierTest
        public class ListTransmogrifierTest

Nascondere le implementazioni dell'interfaccia Transmogrifier potrebbe essere una valida scelta progettuale. Forse è responsabilità della classe di fabbrica scegliere l'implementazione.

Poiché le implementazioni sono private del pacchetto, è necessario posizionare le classi di unit test nello stesso pacchetto se si desidera testarle direttamente. Se hai le classi di test unitari in qualche altro pacchetto, dai test puoi solo accedere direttamente all'interfaccia pubblica e alla classe di fabbrica.


1
"Di solito si desidera scrivere unit test anche per classi e metodi privati ​​del pacchetto". No! Questa è davvero una brutta pratica. I tipi privati ​​di pacchetto sono dettagli di implementazione e non devono mai essere testati direttamente. Testare solo API pubbliche.
David Arno,

1
@DavidArno Non sono d'accordo. Tuttavia, ho sostituito la parola "di solito" con la parola "a volte" per evitare quella particolare discussione.
VIENI DAL

1
Potresti non essere d'accordo su tutto ciò che desideri, ma testare il funzionamento interno di un pezzo di codice porta sia a un stretto accoppiamento tra questi meccanismi interni e i test, sia a test fragili che si rompono facilmente anche durante il semplice refactoring. È una brutta pratica.
David Arno,

Se voglio assicurarmi che tutte le implementazioni del mio Transmogrifier funzionino, indipendentemente da ciò che fa la fabbrica, scriverò dei test unitari che testeranno ogni implementazione. Si noti che le implementazioni hanno un'API pubblica condivisa anche se le classi sono private del pacchetto. Questi test non dovrebbero interrompersi se non cambio l'API pubblica. In realtà, probabilmente scriverei un test generico per un Transmogrifier e quindi eseguirlo su ogni implementazione. Sebbene sia possibile ottenere ogni implementazione utilizzando la fabbrica, è meglio non avere tale dipendenza durante il test dei Trasmogrifiers.
VIENI DAL

Poi, un giorno, si guarda MapTransmogrifiere ListTransmogrifiere decidere che potevano essere trasformati in una classe, in modo da creare ListMapTransmogrifier, modificare la fabbrica di utilizzare tale ed eliminare le due classi. Il codice ora non viene compilato, quindi è necessario modificare ogni test in entrambi MapTransmogrifierTeste ListTransmogrifierTestfarlo compilare. Un test fallisce. Ciò è dovuto alla modifica dei test o alla creazione ListMapTransmogrifier? Viene fuori il debugger per scoprire ... in alternativa quando i test usano la fabbrica, fai quel refattore e tutto ancora si compila ...
David Arno
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.