JUnit: como evitar “métodos não executáveis” em classes de utilitários de teste


118

Mudei para JUnit4.4 de JUnit3.8. Eu executo meus testes usando formiga, todos os meus testes são executados com sucesso, mas as classes de utilitário de teste falham com o erro "Nenhum método executável". O padrão que estou usando é incluir todas as classes com o nome * Teste * na pasta de teste.

Eu entendo que o corredor não consegue encontrar nenhum método anotado com o atributo @Test. Mas eles não contêm essa anotação porque essas classes não são testes. Surpreendentemente, ao executar esses testes no Eclipse, ele não reclama dessas classes.

No JUnit3.8 não era um problema, pois essas classes de utilitários não estendiam o TestCase, então o executor não tentava executá-los.

Eu sei que posso excluir essas classes específicas no destino junit no script de formigas. Mas não quero alterar o arquivo de compilação a cada nova classe de utilitário que adicionar. Também posso renomear as classes (mas dar bons nomes às classes sempre foi meu talento mais fraco :-))

Existe alguma solução elegante para este problema?


Seus testes funcionam no Eclipse / NetBeans / seu IDE favorito?
guerda

Eu uso eclipse. Na verdade, não há nenhum problema nisso, de alguma forma o eclipse não tenta executar essas classes. Me pergunto como?
LiorH

Não sei se entendemos sua pergunta. Por favor, releia sua pergunta e provavelmente adicione mais algumas informações.
guerda

1
@guerda: A questão parece muito clara para mim. Sua tarefa Ant é encontrar classes que não contenham testes, porque o filtro está pegando a classe de utilitário. Daí minha resposta, que ainda acredito ser inteiramente relevante.
Jon Skeet

LiorH: Obrigado pelo esclarecimento, então minha resposta é
inútil

Respostas:


50

Supondo que você esteja no controle do padrão usado para localizar as classes de teste, sugiro alterá-lo para corresponder em *Testvez de *Test*. Assim TestHelpernão haverá correspondência, mas FooTestsim.


1
Não acho que ajudaria, porque ele mudou para o JUnit 4.4 e isso não deveria importar.
guerda

2
Você parece ter perdido o ponto da minha resposta. Ele possui um filtro de nomes para determinar as classes a serem consideradas como testes. Se ele mudar o filtro, ele pode facilmente excluir as classes auxiliares.
Jon Skeet

1
Sua sugestão é válida, porém verifiquei minhas aulas de testes e algumas começam com Teste e outras terminam com Teste. nenhuma distinção clara entre classes de utilitários e classes de teste reais. Você acha que a convenção que você sugeriu é uma boa prática? (isto é, utils começam com Teste e os testes terminam com Teste)
LiorH,

4
É quase uma convenção sufocar as classes de caso de teste com * Test. Pode ser necessário refatorar renomeando as classes de teste apropriadamente e também renomear os auxiliares para que não usem essa convenção de sufixo.
Spoike,

2
Eu concordo com Spoike - se você não consegue dizer pelo nome da classe se é um teste ou um ajudante, você deve renomear a classe. A convenção é mais “a aula é um teste se e somente se terminar com Teste”. As aulas de utilitários podem ou não começar com Teste - não importa.
Jon Skeet

142

Anote suas classes de utilitários com @Ignore. Isso fará com que o JUnit não tente executá-los como testes.


6
Na verdade, não, não deveria. @Ignore é para desabilitar testes temporariamente.
Alice Young de

1
Desculpe, mas isso é uma má ideia. Você deseja começar a anotar seu código de produção com anotações relacionadas ao teste apenas porque elas podem corresponder a um padrão de teste? A resposta adequada é corrigir os nomes das classes se eles estiverem acionando a correspondência de padrões para os testes. E certifique-se de que o padrão encontre apenas classes que TERMINAM com Teste. Esse é um padrão comumente aceito
Kevin M

Sim, isso é ruim e eu não percebi até depois de contribuir com outro upvote que não posso remover. Torne sua classe base abstrata, então JUnit irá ignorá-la. Veja a resposta de @gmoore abaixo.
Ryan Shillington

83

Meu caso específico apresenta o seguinte cenário. Nossos testes

public class VenueResourceContainerTest extends BaseTixContainerTest

todos estendem

BaseTixContainerTest

e JUnit estava tentando executar BaseTixContainerTest. O pobre BaseTixContainerTest estava apenas tentando configurar o container, configurar o cliente, pedir pizza e relaxar ... cara.

Conforme mencionado anteriormente, você pode anotar a classe com

@Ignore

Mas isso fez com que o JUnit relatasse aquele teste como ignorado (em oposição a completamente ignorado).

Tests run: 4, Failures: 0, Errors: 0, Skipped: 1

Isso meio que me irritou.

Portanto, tornei BaseTixContainerTest abstrato e agora JUnit realmente o ignora.

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

7
Muito melhor do que@Ignore
neworld

Eu tentei a abordagem @Ignore e pensei, bem, isso é bom, então eu li esta resposta e me deu um tapa na testa, "É claro !"
dnuttle,

38

Para evitar que JUnit instancie sua classe base de teste, basta torná-la

public abstract class MyTestBaseClass { ... whatever... }

(@Ignore relata como ignorado, o que reservo para testes temporariamente ignorados.)


3
Os executores JUnit geralmente tentam instanciar classes abstratas também e, em seguida, falham com um erro de instanciação.
Holly Cummins

Funciona perfeitamente para minhas aulas de teste básico
ruX

3
Isso está funcionando por causa do nome (não termina em Teste), não por causa do modificador abstrato. Mude o nome da classe para MyBaseClassTest e ela tentará instanciar conforme mencionado por @HollyCummins (e falhará)
Hutch

No meu caso, deveria ser protected abstract class.
Mystic Lin

18
  1. Se esta é a sua classe de teste base, por exemplo AbstractTest e todos os seus testes estendem isso, então defina esta classe como abstrata
  2. Se for a classe Util, é melhor remover * Teste da classe, renomeá-lo como MyTestUtil ou Utils etc.

10

Tenha cuidado ao usar um preenchimento de código IDE para adicionar a importação @Test.

Tem que ser import org.junit.Teste não import org.testng.annotations.Test, por exemplo. Se você fizer o último, obterá o erro "nenhum método executável".


Isso deve ser um comentário e não uma resposta.
Swaranga Sarma

3
Não vejo por quê. É uma solução válida.
Sridhar Sarnobat

4
O Intellij Idea 2017 estava bagunçando minha mente ao importar org.junit.jupiter.api.Test! mas graças a você está resolvido agora
AmiNadimi

Muito obrigado, fiquei confuso ao obter o problema "nenhum método executável".
Peter S.

7

O Ant agora vem com o skipNonTestsatributo que foi projetado para fazer exatamente o que você parece estar procurando. Não há necessidade de alterar suas classes base para abstrair ou adicionar anotações a elas.


2
Parece que o skipNonTestsatributo só está disponível no ant 1.9+, o que é uma pena, pois parece incrivelmente útil. Também excluirá superclasses de testes abstratos.
Holly Cummins

4

Que tal adicionar um método de teste vazio a essas classes?

public void avoidAnnoyingErrorMessageWhenRunningTestsInAnt() {
    assertTrue(true); // do nothing;
}

8
mas isso aumenta falsamente o número de testes que temos :) não que seja um grande negócio
Sudarshan

1

Em sua classe de teste, se escreveu import org.junit.jupiter.api.Test; exclua-o e escreva import org.junit.Test; Neste caso também funcionou para mim.


1
surpreendentemente, funcionou. executei manualmente na linha de comando do Windows. no entanto, outro problema é que @BeforeAlle @AfterAllnão são executados.
BingLi224

aparentemente, JUnit4 funcionou (com @BeforeClasse @AfterClass, mas JUnit5 não. Referência: junit.org/junit5/docs/current/user-guide/#migrating-from-junit4
BingLi224

0

Eu também estava enfrentando um problema semelhante ("nenhum método executável ..") ao executar a parte mais simples do código (usando @Test, @Before etc.) e não encontrei a solução em lugar nenhum. Eu estava usando Junit4 e Eclipse SDK versão 4.1.2. Resolvi meu problema usando o Eclipse SDK 4.2.2 mais recente. Espero que isso ajude as pessoas que estão lutando com um problema semelhante.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.