Convenção de nomenclatura para pacotes de teste

11

Na verdade, estamos nomeando nossos pacotes de teste exatamente como seus equivalentes de teste. Então, acabamos com esta estrutura:

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

Eu sempre senti que isso não é muito inteligente, pois você não pode distinguir entre "teste" e "testar" se fornecido apenas com o nome do pacote. Por outro lado, não encontrei realmente um caso em que isso importe de alguma forma. É uma boa prática ter as mesmas convenções de nomenclatura para os dois pacotes (para os casos de teste e as classes de origem)? Caso contrário, qual seria uma abordagem melhor?

OddDev
fonte
1
Não faço ideia se é uma boa prática, mas é popular. A outra opção (para colocar "Test" no nome do pacote, nomes de métodos etc.) cheira um pouco demais à "nomeação Smurf". Como você diz, é difícil pensar em um caso em que não é possível "distinguir entre" teste "e" testar "se apenas for fornecido o nome do pacote" seria um problema.
David Arno
@DavidArno Obrigado pela sua contribuição :) Como evitar os nomes de smurf, então? Quero dizer que acabaríamos com com.hello.world.test.helloWorld.java, não é?
OddDev 19/08/19
O problema "smurf" é mais quando você tem um método XXXTest()em com.hello.world.test.helloWorldTest.java. O conselho geral seria exibir apenas "Teste" uma vez no caminho; portanto, (a) use teste no nome do pacote (e nomeie o arquivo de teste da mesma forma que o arquivo em teste) ou (b) torne o nome do pacote o mesmo e adicione "test" ao nome do arquivo / classe.
David Arno
@DavidArno Ah, obrigado pelo esclarecimento! Eu entendi seu primeiro comentário errado. Agora eu entendi.
OddDev 19/08/19
Bem, eu diria que, se não estava claro, eu tenho o meu primeiro comentário errado :)
David Arno

Respostas:

11

Essa é uma boa convenção.

Às vezes, você deseja escrever testes de unidade para classes e métodos privados de pacotes também. Você não poderá chamá-los de uma classe de teste de unidade colocada em outro pacote.

Não deve haver nenhuma confusão sobre ter classes de teste de unidade no mesmo espaço para nome, pois elas não deveriam estar no caminho da classe ao compilar ou executar o código de produção.

Aqui está um exemplo de um pequeno módulo com uma interface pública, uma classe de fábrica pública e duas classes de implementação privadas do pacote:

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

Ocultar as implementações da interface do transmogrificador pode ser uma opção de design válida. Talvez seja da responsabilidade da classe da fábrica escolher a implementação.

Como as implementações são privadas de pacote, é necessário colocar as classes de teste de unidade no mesmo pacote se desejar testá-las diretamente. Se você tiver suas classes de teste de unidade em algum outro pacote, você só terá acesso direto à interface pública e à classe de fábrica de seus testes.

VEM DE ONDE
fonte
1
"Normalmente você deseja escrever testes de unidade para classes e métodos privados de pacotes também". Não! Esta é realmente uma prática ruim. Tipos particulares de pacote são detalhes de implementação e nunca devem ser testados diretamente. Teste apenas APIs públicas.
David Arno
1
@DavidArno Eu discordo. No entanto, substituí a palavra "geralmente" pela palavra "às vezes" para evitar essa discussão específica.
Vem
1
Você pode discordar de tudo o que quiser, mas testar o funcionamento interno de um trecho de código leva a um acoplamento rígido entre o funcionamento interno e os testes e a testes frágeis que quebram facilmente durante a refatoração simples. É uma prática muito ruim.
David Arno
Se eu quiser garantir que todas as implementações do transmogrificador funcionem, não importa o que a fábrica faça, escreverei testes de unidade que testam cada implementação. Observe que as implementações têm uma API pública compartilhada, mesmo que as classes sejam privadas do pacote. Esse teste não deve ser interrompido, a menos que eu mude a API pública. Na verdade, eu provavelmente escreveria um teste genérico para um transmogrificador e o executaria em cada implementação. Embora seja possível obter cada implementação usando a fábrica, é melhor não ter essa dependência ao testar os transmogrificadores.
Vem
Então, um dia, você olha para MapTransmogrifiere ListTransmogrifiere decidem que poderia ser feito em uma classe, para que você criar ListMapTransmogrifier, modificar a fábrica de usar que e excluir as duas classes. O código agora não é compilado, então você precisa modificar todos os testes nos dois MapTransmogrifierTeste ListTransmogrifierTestcompilá-lo. Um teste falha. Isso foi devido à alteração dos testes ou à criação ListMapTransmogrifier? Vem para fora o depurador para descobrir ... alternativamente, quando os testes de usar a fábrica, você fazer isso refactor e todos compila ainda ...
David Arno