Garanta a qualidade do seu código Java com JUnit: Uma visão geral da ferramenta essencial para desenvolvedores

Por Gaspar Barancelli Junior em 22 de agosto de 2023

JUnit é uma estrutura de teste de unidade para a linguagem de programação Java. É uma das ferramentas de teste mais populares e amplamente utilizadas para desenvolvimento de software em Java.

O JUnit permite que os desenvolvedores escrevam testes automatizados para suas classes Java. Esses testes podem ser executados automaticamente em um ambiente controlado, para verificar se as classes Java funcionam corretamente em diferentes cenários e situações.

Os testes podem ser organizados em suites de teste, que agrupam testes relacionados. O JUnit também fornece uma série de recursos para verificar o comportamento e o estado de objetos durante a execução do teste, como a comparação de valores, a exceção esperada e a verificação de que os métodos foram chamados.

Por exemplo, se você escreveu um programa que calcula a média de notas, você pode usar o JUnit para testar se ele está calculando corretamente a média para diferentes conjuntos de notas. O JUnit também permite que você verifique se o programa está lidando corretamente com situações inesperadas, como quando as notas não são números válidos.

O JUnit é muito útil porque permite que os programadores detectem e corrijam erros em seus programas antes de liberá-los para uso. Dessa forma, os usuários não precisam lidar com problemas que poderiam ser evitados, e o programa pode ser mais confiável e eficiente.

O JUnit é uma ferramenta de código aberto, distribuída sob a Licença Pública Geral GNU (GPL). É uma das ferramentas mais populares para testes unitários em Java, e é amplamente utilizada em projetos de desenvolvimento de software em todo o mundo.

Configuração

Maven

Para adicionar o JUnit em um projeto Maven, você deve seguir os seguintes passos:

  1. Abra o arquivo pom.xml do seu projeto.

  2. Adicione a dependência do JUnit no bloco de dependências do Maven, conforme o exemplo abaixo:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>
Gradle

Para adicionar o JUnit em um projeto Gradle, você deve seguir os seguintes passos:

  1. Abra o arquivo build.gradle do seu projeto.

  2. Adicione a dependência do JUnit no bloco de dependências do Gradle, conforme o exemplo abaixo:

testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.2'

É importante notar que esta versão requer o Java 8 para funcionar.

Arquitetura

A arquitetura do JUnit 5 é composta por vários componentes que trabalham juntos para oferecer uma plataforma de teste de unidade moderna e flexível para a linguagem Java. A arquitetura pode ser dividida em três partes principais: a Plataforma JUnit, o JUnit Jupiter e o JUnit Vintage.

Plataforma JUnit

A Plataforma JUnit é a base da arquitetura do JUnit 5. Ela é responsável por fornecer um ambiente de tempo de execução para a execução dos testes. A Plataforma JUnit é altamente flexível e pode ser integrada com várias ferramentas e frameworks de teste, incluindo Maven, Gradle, Ant e Eclipse. A plataforma é composta por um conjunto de APIs que permitem que as ferramentas de construção executem e relatem os testes.

JUnit Jupiter

O JUnit Jupiter é o novo modelo de programação de teste introduzido no JUnit 5. Ele oferece suporte a recursos avançados de teste, como anotações personalizadas, extensões, testes parametrizados e suporte a diferentes mecanismos de assertivas. O JUnit Jupiter também fornece uma API de extensão flexível que permite que os desenvolvedores estendam o comportamento do JUnit com recursos personalizados.

JUnit Vintage

O JUnit Vintage é responsável por fornecer compatibilidade com versões anteriores do JUnit. Ele permite que os testes escritos usando as versões antigas do JUnit (como JUnit 3 e JUnit 4) sejam executados no novo ambiente de tempo de execução do JUnit 5. O JUnit Vintage também fornece suporte a recursos mais antigos do JUnit, como o uso de asserções de estilo antigo e a execução de testes com o método de nomeação padrão.

Anotações Básicas

@Test

Anotação utilizada para indicar que um método é um teste. Este método deve ser público, sem parâmetros de entrada e sem retorno.

Exemplo:

@Test
void meuTeste() {
   // código do teste
}
@BeforeEach

Anotação utilizada para indicar que um método deve ser executado antes de cada teste. Este método pode ser usado para inicializar variáveis ou objetos que serão usados nos testes.

Exemplo:

@BeforeEach
void inicializar() {
   // inicialização dos objetos ou variáveis
}
@AfterEach

Anotação utilizada para indicar que um método deve ser executado após cada teste. Este método pode ser usado para limpar objetos ou variáveis que foram usados nos testes.

Exemplo:

@AfterEach
void limpar() {
   // limpeza dos objetos ou variáveis
}
@BeforeAll

Anotação utilizada para indicar que um método deve ser executado antes de todos os testes. Este método pode ser usado para inicializar recursos compartilhados entre os testes.

Exemplo:

@BeforeAll
static void inicializarRecursosCompartilhados() {
   // inicialização dos recursos compartilhados
}
@AfterAll

Anotação utilizada para indicar que um método deve ser executado após todos os testes. Este método pode ser usado para limpar recursos compartilhados entre os testes.

Exemplo:

@AfterAll
static void limparRecursosCompartilhados() {
   // limpeza dos recursos compartilhados
}
@DisplayName

Anotação utilizada para especificar um nome amigável para um teste. O nome fornecido será usado nos relatórios de teste em vez do nome do método de teste. Essa anotação pode ser útil para tornar os nomes dos testes mais legíveis e descritivos.

Exemplo:

@Test
@DisplayName("Teste de soma")
void testarSoma() {
   // código do teste
}
@Disabled

Anotação utilizada para desabilitar um teste. Quando essa anotação é usada, o teste não será executado durante a execução do conjunto de testes. Isso pode ser útil quando o teste ainda não está pronto ou não está passando e deve ser trabalhado mais tarde.

Exemplo:

@Test
@Disabled("Teste ainda não implementado")
void testeNaoImplementado() {
   // código do teste
}

Afirmações e Suposições

No JUnit 5, você pode realizar afirmações e suposições nos seus testes usando as classes de asserção Assertions e Assumptions.

Assertions

As afirmações são usadas para verificar se um valor é igual, maior, menor ou diferente de outro valor esperado. Para realizar afirmações no JUnit 5, você pode usar os métodos estáticos fornecidos pela classe Assertions, tais como:

  • assertEquals: verifica se dois objetos são iguais.

  • assertNotEquals: verifica se dois objetos não são iguais.

  • assertTrue: verifica se uma condição é verdadeira.

  • assertFalse: verifica se uma condição é falsa.

  • assertNull: verifica se um objeto é nulo.

  • assertNotNull: verifica se um objeto não é nulo.

  • assertThrows: verifica se um método lança uma exceção específica.

Exemplo de como usar a classe Assertions para realizar afirmações no JUnit 5:

@Test
void testarSoma() {
   int resultado = 2 + 2;
   Assertions.assertEquals(4, resultado);
}
Assumptions

As suposições são usadas para verificar se uma condição é verdadeira antes de executar um teste. Se a suposição falhar, o teste será interrompido e marcado como "ignorado". Para realizar suposições no JUnit 5, você pode usar os métodos estáticos fornecidos pela classe Assumptions, tais como:

  • assumeTrue: verifica se uma condição é verdadeira.

  • assumeFalse: verifica se uma condição é falsa.

  • assumeNotNull: verifica se um objeto não é nulo.

Exemplo de como usar a classe Assumptions para realizar suposições no JUnit 5:

@Test
void testarMultiplicacao() {
   boolean isExecutado = Boolean.valueOf(System.getProperty("executado"));
   Assumptions.assumeTrue(isExecutado);
   int resultado = 2 * 2;
   Assertions.assertEquals(4, resultado);
}

Usando asserções e suposições, você pode escrever testes mais robustos e confiáveis que verificam o comportamento do código e asseguram que ele está funcionando corretamente.

Teste de exceção

No JUnit 5, você pode testar erros em seus testes com o método assertThrows fornecido pela classe Assertions.

O método assertThrows verifica se um método lançou uma exceção específica durante a sua execução. O método aceita dois argumentos: a classe da exceção esperada e uma expressão lambda que contém o código a ser testado.

Exemplo de como usar o método assertThrows para testar uma exceção no JUnit 5:

@Test
void testarDivisaoPorZero() {
   assertThrows(ArithmeticException.class, () -> {
       int resultado = 10 / 0;
   });
}

Neste exemplo, o método assertThrows verifica se uma exceção da classe ArithmeticException é lançada quando tentamos dividir 10 por 0. Se a exceção não for lançada, o teste falhará.

Conjuntos de teste

No JUnit 5, você pode configurar um conjunto de testes usando a anotação @RunWith e a classe @SelectClasses.

A anotação @RunWith é usada para especificar o runner que será usado para executar os testes. No caso do JUnit 5, o runner padrão é o JUnitPlatform.

A classe @SelectClasses é usada para especificar quais classes de teste devem ser executadas como parte da suíte de testes.

Exemplo de como configurar uma suite de testes no JUnit 5:

import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.runner.RunWith;

@RunWith(JUnitPlatform.class)
@SelectClasses({TesteCalculadora.class, TesteMatematica.class})
public class SuiteDeTestes {
    // vazio
}

Neste exemplo, a classe SuiteDeTestes é configurada como uma suite de testes usando a anotação @RunWith e a classe JUnitPlatform. A anotação @SelectClasses é usada para especificar as classes de teste que serão executadas como parte da suíte de testes. Neste caso, as classes TesteCalculadora e TesteMatematica serão executadas.

testes dinâmicos

Os testes dinâmicos são uma nova funcionalidade introduzida no JUnit 5 que permitem a criação de testes de forma mais flexível e dinâmica.

Para criar testes dinâmicos no JUnit 5, você deve seguir os seguintes passos:

  1. Anote a classe de teste com a anotação @TestFactory.

  2. Crie um método na classe de teste que retorna um objeto do tipo Stream<DynamicTest>. Esse método deve conter a lógica para criar os testes dinâmicos e retorná-los como um stream.

  3. Crie os testes dinâmicos usando o método DynamicTest.dynamicTest(). Este método recebe o nome do teste e um objeto Executable que contém a lógica do teste.

  4. Retorne os testes dinâmicos como um stream usando o método Stream.of().

Veja um exemplo de como criar testes dinâmicos no JUnit 5:

import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;

import java.util.stream.Stream;

public class TesteCalculadora {

    @TestFactory
    public Stream<DynamicTest> testesDeAdicao() {
        return Stream.of(
            DynamicTest.dynamicTest("Teste 1", () -> assertEquals(4, Calculadora.somar(2, 2))),
            DynamicTest.dynamicTest("Teste 2", () -> assertEquals(0, Calculadora.somar(-2, 2))),
            DynamicTest.dynamicTest("Teste 3", () -> assertEquals(-4, Calculadora.somar(-2, -2)))
        );
    }

}

Neste exemplo, a classe TesteCalculadora contém um método testesDeAdicao() anotado com a anotação @TestFactory. Esse método retorna um stream de testes dinâmicos que testam o método somar() da classe Calculadora.

Cada teste dinâmico é criado usando o método DynamicTest.dynamicTest(), que recebe o nome do teste e um objeto Executable contendo a lógica do teste. Os testes são retornados como um stream usando o método Stream.of().

Ao executar a classe de teste TesteCalculadora, o JUnit 5 executará todos os testes dinâmicos contidos no stream retornado pelo método testesDeAdicao(). Os resultados dos testes serão exibidos na saída padrão do console.

Conclusão

O JUnit é uma ferramenta essencial para garantir a qualidade do código em projetos Java, oferecendo aos desenvolvedores uma estrutura robusta e flexível para criar testes unitários. Com a utilização adequada das anotações e recursos oferecidos pela plataforma, é possível automatizar a execução de testes e verificar se as classes Java estão funcionando corretamente em diferentes cenários e situações. O JUnit 5, em particular, apresenta uma arquitetura moderna e flexível, que oferece suporte a recursos avançados de teste e é compatível com versões anteriores do JUnit. Em suma, o JUnit é uma ferramenta poderosa para garantir a qualidade e confiabilidade do software, além de economizar tempo e recursos de desenvolvimento.

// Compartilhe esse Post

💫
🔥 NOVO APP

Domine o Inglês em 30 dias!

Inteligência Artificial + Repetição Espaçada • Método cientificamente comprovado

✅ Grátis para começar 🚀 Resultados rápidos
×