Separação de classes JUnit em pacote de teste especial?

118

Estou aprendendo os conceitos de Desenvolvimento Orientado a Testes lendo os artigos do Craftsman (clique em Craftsman em Por Tópico ) recomendados em uma resposta à minha pergunta anterior, "Projeto de amostra para aprender JUnit e engenharia de software adequada" . Eu amo isso até agora!

Mas agora quero sentar e experimentar eu mesmo. Tenho uma pergunta que espero precisar apenas de uma resposta simples.

Como você organiza suas classes de teste JUnit e seu código real? Estou falando principalmente sobre a estrutura do pacote, mas quaisquer outros conceitos importantes também seriam úteis.

Você coloca classes de teste em org.myname.project.test. * E o código normal em org.myname.project. *? Você coloca as classes de teste ao lado das classes normais? Você prefere prefixar os nomes das classes com Teste em vez de sufocá-los?

Sei que parece o tipo de coisa com a qual não devo me preocupar tão cedo, mas sou uma pessoa muito centrada na organização. Sou quase o tipo de pessoa que passa mais tempo descobrindo métodos para manter o controle do que deve ser feito, em vez de realmente fazer as coisas.

E eu tenho um projeto que está dividido em pacotes, mas ficou uma bagunça. Em vez de tentar refatorar tudo e escrever testes, quero começar do zero, testes primeiro e tudo. Mas primeiro preciso saber para onde vão meus testes.


editar: Eu esqueci totalmente do Maven, mas parece que a maioria de vocês está usando! No passado, eu tinha um caso de uso específico em que o Maven quebrou completamente comigo, mas o Ant me deu a flexibilidade de que precisava, então acabei me apegando ao Ant, mas estou pensando que talvez só estivesse usando a abordagem errada. Acho que vou dar outra chance ao Maven porque parece que vai funcionar bem com o desenvolvimento orientado a testes.

Ricket
fonte
1
possível duplicata de Onde devo colocar meus testes JUnit?
mmmmmm

Respostas:

154

Eu prefiro colocar as classes de teste no mesmo pacote que as classes do projeto que elas testam, mas em um diretório físico diferente, como:

myproject/src/com/foo/Bar.java
myproject/test/com/foo/BarTest.java

Em um projeto Maven, seria assim:

myproject/src/main/java/com/foo/Bar.java
myproject/src/test/java/com/foo/BarTest.java

O ponto principal nisso é que minhas classes de teste podem acessar (e testar!) Classes e membros de escopo de pacote.

Como mostra o exemplo acima, minhas classes de teste têm o nome da classe testada mais Testcomo um sufixo. Isso ajuda a encontrá-los rapidamente - não é muito engraçado tentar pesquisar entre algumas centenas de classes de teste, cujo nome começa com Test...

Atualização inspirada no comentário de @Ricket: desta forma, as classes de teste (normalmente) aparecem logo após seu amigo testado em uma lista alfabética de nomes de classes em relação ao projeto. (Engraçado que estou me beneficiando disso dia a dia, sem ter percebido conscientemente como ...)

Update2: Muitos desenvolvedores (incluindo eu) gostam do Maven, mas parece haver pelo menos tantos que não gostam. IMHO é muito útil para projetos Java "convencionais" (eu colocaria cerca de 90% dos projetos nesta categoria ... mas os outros 10% ainda são uma minoria considerável). É fácil de usar se aceitarmos as convenções do Maven; entretanto, se não, torna a vida uma luta miserável. Maven parece ser difícil de compreender para muitas pessoas socializadas no Ant, pois aparentemente requer uma forma de pensar muito diferente. (Eu mesmo, nunca tendo usado o Ant, não consigo comparar os dois.) Uma coisa é certa: ele torna o teste de unidade (e integração) uma etapa natural de primeira classe no processo, o que ajuda os desenvolvedores a adotar essa prática essencial.

Péter Török
fonte
6
Também concordo com a nota do sufixo. Além disso, como as classes de teste são separadas em uma pasta física diferente, não há necessidade de tentar prefixar com Test em alguma tentativa de enganar uma classificação por ordem alfabética em agrupamento, e acho que SomeClassTest lê melhor.
Ricket
Excelentes convenções +1
whiskyierra
1
Uma coisa sobre colocar classes de teste no mesmo pacote: embora permita usar membros privados do pacote (razão pela qual eu uso esse esquema também), também não permite testar a visibilidade automaticamente, esp. se você usa TDD e permite que seu IDE gere os stubs de método necessários. Ele pode gerá-los com visibilidade privada do pacote (NetBeans, estou olhando para você), o que faz seu teste passar perfeitamente (depois de realmente colocar a implementação nesses stubs), mas pode falhar no uso real (se você se esqueceu de adicionar public) .
Sergei Tachenov
Embora essa convenção seja interessante, o que você faz quando o conjunto de testes cresce? Por exemplo, digamos que você tenha 6 métodos na classe, cada método possui 10 testes. Você tem 60 testes em sua classe? Normalmente subdividi a classe de teste (uma classe de teste por método). O problema com isso é que você pode encontrar muitas classes em seu pacote de teste.
mmalmeida de
1
@Thick_propheT no Eclipse: clique com o botão direito no nome do projeto, clique em Novo - Outro ... e, dentro da pasta Java, selecione Pasta de origem. nomeie-o "teste". Então, se você deseja seguir a convenção acima, adicione um novo pacote a esta pasta de teste com o mesmo nome do pacote da classe para a qual você deseja escrever o caso de teste e, no pacote, adicione um novo Caso de Teste JUnit (localizado em a pasta Java / Junit quando você faz New-Other ...). nesse novo assistente, você pode especificar a classe que está sendo testada e nomear seu caso de teste com o mesmo nome com o sufixo "Teste"
ou
15

Eu coloquei minhas classes de teste no mesmo pacote que eles estão testando, mas em uma pasta de origem ou projeto diferente . Organizar meu código de teste dessa maneira permite que eu facilmente compile e empacote-o separadamente para que os arquivos jar de produção não contenham o código de teste. Ele também permite que o código de teste acesse campos e métodos privados do pacote.

ChrisH
fonte
12

Eu uso o Maven . A estrutura que o Maven promove é: -

src/main/java/org/myname/project/MyClass.java

src/test/java/org/myname/project/TestMyClass.java

ou seja, uma classe de teste com Teste prefixado ao nome da classe em teste está em uma estrutura de diretório paralela ao teste principal.

Uma vantagem de ter as classes de teste no mesmo pacote (embora não necessariamente no diretório) é que você pode aproveitar os métodos de escopo do pacote para inspecionar ou injetar objetos de teste de simulação.

Martin
fonte
18
Achei que fosse <class>Test.java, nãoTest<class>.java
Mike Rylander
2
O Maven aceitará qualquer um dos padrões, de acordo com a documentação do plug-in Maven Surefire .
Elijah Woodward,
3
Eu diria que o <class>Test.javaesquema de nomenclatura faz com que a classe principal e a classe de teste apareçam de perto ao usar os recursos de pesquisa do IDE, o que o torna um pouco melhor do que Test<class>.java.
christopheml
1
@christopheml, concordo, é o que faço agora.
Martin
Isso funcionou para o Intellij. MyClassTest.java não funcionou.
user2761431