JUnit 4 e TestNG costumavam ser comparáveis. Quais são os prós e os contras das duas estruturas de teste?
JUnit 4 e TestNG costumavam ser comparáveis. Quais são os prós e os contras das duas estruturas de teste?
Respostas:
Eu estava comparando TestNG e JUnit4 hoje, e a principal vantagem que posso apontar com minha experiência limitada em frameworks de teste é que TestNG tem uma maneira mais elegante de lidar com testes parametrizados com o conceito de provedor de dados.
Pelo que eu posso dizer com JUnit4, você deve criar uma classe de teste separada para cada conjunto de parâmetros com o qual deseja testar (executado com @RunWith(Parameterized.class)
). Com TestNG, você pode ter vários provedores de dados em uma única classe de teste, portanto, você pode manter todos os seus testes para uma única classe em uma única classe de teste também.
Até agora, essa é a única coisa que posso apontar como um benefício do TestNG em relação ao JUnit4.
Intellij IDEA inclui suporte para TestNG e JUnit fora da caixa. No entanto, o Eclipse só oferece suporte a JUnit fora da caixa e precisa de um plug-in TestNG instalado para fazê-lo funcionar.
No entanto, um problema mais irritante que encontrei com TestNG é que suas classes de teste precisam ser estendidas PowerMockTestCase
se você estiver usando o PowerMock para simular dependências em seus testes. Aparentemente, há maneiras de configurar a fábrica de objetos que sua estrutura de teste precisa saber ao usar o PowerMock por meio de um método especial ou por meio da testng.xml
definição de suíte, mas parecem estar quebradas no momento. Eu não gosto de ter classes de teste estendendo classes de framework de teste, parece hackear.
Se você não usa o PowerMock, isso não é um problema, mas no geral tenho a impressão de que o JUnit4 é melhor suportado.
Com base na minha experiência com ambas as estruturas, o testng tem alguns recursos convenientes que a equipe JUnit recusou implementar por vários anos. Eu prefiro JUnit por esse motivo. Converter para o teste é fácil, pois basicamente suporta quase tudo no JUnit (há até um plug-in conversor para o eclipse), converter de volta para o JUnit não é tão bom por causa desses recursos ausentes.
No teste, os @BeforeClass
métodos não são estáticos e são executados antes da execução dos testes dessa classe, e não quando a classe de teste é carregada (o comportamento JUnit). Certa vez, tive um projeto JUnit em que todos os testes de banco de dados (algumas dezenas) inicializaram o banco de dados logo no início, o que foi um comportamento bastante idiota. Houve muito debate a favor e contra isso na comunidade JUnit. A essência disso é que cada método de teste deve ter seu próprio dispositivo de teste e, portanto, você não deve ter um método do estilo beforeAll que seja não estático, porque isso permitiria que você definisse uma variável de instância sorrateiramente uma vez e depois a usasse em todos os seus testes. Válido, mas realmente irritante para testes de integração. TestNG dá aos usuários a escolha aqui. O Junit não faz isso, por design, o que é irritante.
Provedores de dados de teste são um pouco mais flexíveis do que o equivalente em JUnit. Você pode especificar por teste qual método de provedor de dados deve fornecer a entrada em vez de ter uma abordagem de tamanho único para toda a classe como no JUnit. Portanto, você pode ter provedores de dados de casos positivos e negativos para seus testes em uma classe. Muito bom ter.
Você pode marcar uma classe com @Test
in testng, o que significa: todo método público é um teste. No Junit, você precisa copiar / colar @Test
em todos os métodos.
Um aborrecimento com ambos é a maneira como o hamcrest é empacotado com JUnit e a maneira como JUnit é empacotado com testng. Existem potes alternativos no maven que não têm esse problema.
Minha grande preocupação com os dois frameworks é que ambos parecem ter parado de evoluir. Os lançamentos são cada vez menos frequentes e tendem a ter cada vez menos características dignas de nota. Todo o movimento do BDD parece ter tido pouco impacto em qualquer uma das estruturas, por exemplo. Além disso, o JUnit poderia simplesmente ter adotado a maior parte do que listei acima. Não há uma boa razão técnica para que o JUnit não consiga implementar nenhuma dessas coisas; as pessoas por trás do JUnit simplesmente optam por não implementar essas coisas. Ambos os projetos parecem carecer de uma visão para direções futuras e parecem estar felizes em fazer apenas pequenos ajustes nos últimos anos.
Eu estava procurando por bons motivos para trocar o TestNG pelo JUnit e achei esses slides de Tomek Kaczanowski abordando essa questão muito bem. Tomek é autor do livro Practical Unit Testing que parece ser muito respeitado por desenvolvedores e testadores.
Se você trabalha em um projeto Java / Scala e o Gradle é sua ferramenta de compilação preferida, lembre-se de que o ScalaTest
framework precisa apenas JUnitRunner
executar seus testes de scala. Em outras palavras, você tem uma escolha:
Você pode usar o Mockito como sua estrutura de simulação. Ele se integra perfeitamente ao TestNG. Você não precisa estender nenhuma classe para usar o Mockito com TestNG. Seu código de teste é menos acoplado dessa maneira e se por algum motivo você precisar usar outras estruturas de simulação, é fácil fazê-lo.
Em poucas palavras ..
Se o seu escopo estiver limitado a testes de unidade detalhados e sem dependências entre eles, o JUnit pode ser usado.
Se o seu escopo requer teste funcional que pode / não pode exigir dependências e compartilhamento de dados (parâmetros) entre os testes, escolha TestNG. Além disso, TestNG pode fazer testes de unidade semelhantes ao JUnit. Assim, você pode ter um conjunto de testes de unidade e um conjunto de testes funcionais.