JUnit é um framework padrão para testes unitários no ecossistema Java e Kotlin, usado no desenvolvimento Android para verificar a lógica de negócios ao nível de componentes isolados. O framework fornece um conjunto de anotações, métodos de asserção e um Test Runner para descoberta e execução automática de testes. De acordo com JUnit.org, a biblioteca continua sendo a solução mais popular para testes unitários no ecossistema JVM: mais de 70% dos projetos Java usam JUnit em alguma versão.
Principais pontos
JUnit é um framework de código aberto para escrever e executar testes unitários repetíveis em Java e Kotlin. Faz parte do ecossistema xUnit, uma família de frameworks baseados na arquitetura de Kent Beck e Erich Gamma, e é a ferramenta de teste padrão no Android Studio e IntelliJ IDEA.
A principal tarefa do JUnit é isolar um pequeno fragmento de código (método, classe) e verificar seu comportamento em condições controladas. Os testes são escritos como classes Java/Kotlin comuns com anotações, e o framework cuida da descoberta de testes, gerenciamento do ciclo de vida e coleta de estatísticas de execução.
A primeira versão do JUnit apareceu em 1997 e mudou radicalmente a abordagem de desenvolvimento, popularizando as práticas de Test-Driven Development (TDD). Hoje, o JUnit 5 (Jupiter) é a versão atual, completamente redesenhada com uma arquitetura modular compatível com Java 8+ e extensões.
O mecanismo de execução do JUnit é baseado no padrão Test Runner, que escaneia o classpath, encontra métodos com a anotação @Test, cria uma instância da classe de teste e executa os métodos em uma ordem específica. O Test Runner gerencia o ciclo de vida: BeforeAll → BeforeEach → Test → AfterEach → AfterAll.
O JUnit envolve cada método de teste em uma instância de classe separada, garantindo o isolamento entre os testes. Isso significa que os campos da classe não mantêm estado entre diferentes métodos @Test — cada teste começa com um objeto limpo.
O teste mais simples no JUnit é um método com a anotação @Test que chama o código sob teste e verifica o resultado usando uma asserção. Se a asserção falhar, o teste é considerado falho e o JUnit reporta o erro.
@Test
void additionShouldReturnCorrectSum() {
var calculator = new Calculator();
var result = calculator.add(2, 3);
assertEquals(5, result);
}
O Test Runner encontra automaticamente tal método, executa-o e reporta o resultado. Se o método não lançar uma exceção — o teste passa (green). Se uma asserção falhar — o teste falha (red).
As anotações do JUnit definem quando e como o código de teste deve ser executado. No JUnit 5, as anotações estão no pacote org.junit.jupiter.api e cobrem todas as etapas: preparação de dados, execução do teste, limpeza de recursos.
| Anotação | Propósito | Executa |
|---|---|---|
| @Test | Marca um método de teste | Uma vez por chamada |
| @BeforeEach | Preparação antes de cada teste | Antes de cada @Test |
| @BeforeAll | Inicialização única da classe | Uma vez antes de todos os testes |
| @AfterEach | Limpeza após cada teste | Após cada @Test |
| @AfterAll | Finalização única da classe | Uma vez após todos os testes |
| @DisplayName | Nome legível do teste | Decoração |
Considere uma classe de teste completa com um ciclo de vida adequado. O método setUp cria uma nova instância de Calculator antes de cada teste, e tearDown libera recursos — por exemplo, fechando descritores de arquivo ou conexões de banco de dados.
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
void subtractionShouldReturnCorrectResult() {
int result = calculator.subtract(10, 4);
assertEquals(6, result);
}
@AfterEach
void tearDown() {
calculator.reset();
}
}
Asserções são métodos estáticos que comparam o resultado real com o esperado e lançam uma exceção se não coincidirem. O JUnit 5 oferece a classe org.junit.jupiter.api.Assertions com mais de 25 métodos para diferentes cenários de verificação — desde a comparação simples de valores até verificações de tempo limite e asserções agrupadas.
Especial atenção merece o método assertThrows, que permite verificar que o código lida corretamente com situações de erro — divisão por zero, passagem de null, exceder limites.
@Test
void divisionByZeroShouldThrowException() {
Calculator calc = new Calculator();
ArithmeticException exception = assertThrows(
ArithmeticException.class,
() -> calc.divide(10, 0)
);
assertEquals("Cannot divide by zero", exception.getMessage());
}
Testes parametrizados permitem executar o mesmo método de teste com diferentes conjuntos de argumentos. No JUnit 5, isso é feito usando a anotação @ParameterizedTest combinada com uma fonte de dados — @ValueSource, @CsvSource, @MethodSource ou @EnumSource.
Essa abordagem reduz radicalmente a duplicação de código: em vez de dez testes idênticos para valores diferentes, escreve-se um único método parametrizado. De acordo com o Google Testing Blog, a parametrização reduz o volume de código de teste em 40–60% sem perder cobertura.
A anotação @CsvSource passa múltiplas linhas separadas por vírgula para o teste. Cada linha corresponde a uma execução do teste. O JUnit converte automaticamente os valores de string para os tipos necessários: int, long, String e outros.
@ParameterizedTest
@CsvSource({
"1, 1, 2",
"2, 3, 5",
"10, 20, 30",
"-1, 1, 0"
})
void additionWithMultipleInputs(int a, int b, int expected) {
assertEquals(expected, a + b);
}
Quando os dados de entrada são mais complexos que números ou strings simples, usa-se @MethodSource. Ele referencia um método estático que retorna um Stream de argumentos — por exemplo, um Stream de Arguments ou um Stream de objetos User para testar a camada DAO.
No desenvolvimento Android, JUnit é usado junto com AndroidX Test, que fornece extensões para testar Activity, Content Provider e outros componentes Android. O JUnit cuida dos testes unitários executados na JVM sem emulador, enquanto o AndroidX Test cuida dos testes instrumentados no dispositivo.
Para adicionar JUnit 5 a um projeto Android, basta incluir a dependência org.junit.jupiter:junit-jupiter no build.gradle nível de módulo. O plugin AGP do Gradle suporta a execução de testes JUnit 5 na JVM através do Test Runner padrão.
// build.gradle.kts
android {
testOptions {
unitTests.isIncludeAndroidResources = true
}
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.11.0")
testImplementation("androidx.test:core-ktx:1.6.1")
}
Na prática, o JUnit é mais frequentemente usado para testar ViewModel e repositórios — camadas que não requerem contexto Android ou emulador. Esse tipo de teste é executado em milissegundos e pode ser executado centenas de vezes sem perder tempo.
JUnit 5 (Jupiter) não é apenas uma nova versão, mas uma plataforma completamente redesenhada dividida em três módulos: JUnit Platform (execução de testes na JVM), JUnit Jupiter (API para escrever testes) e JUnit Vintage (compatibilidade reversa com JUnit 4). Essa modularidade permite conectar diferentes Test Engines — por exemplo, Spek para Kotlin ou TestNG.
| Característica | JUnit 4 | JUnit 5 |
|---|---|---|
| Pacote | org.junit | org.junit.jupiter |
| Anotação base | @Test (de junit.framework) | @Test (de org.junit.jupiter.api) |
| Before/After | @Before, @After, @BeforeClass | @BeforeEach, @AfterEach, @BeforeAll |
| Parametrizados | @RunWith(Parameterized.class) | @ParameterizedTest + @ValueSource |
| Extensão | @Rule, @ClassRule | @ExtendWith, API mais flexível |
| Java min | Java 5 | Java 8+ |
Migrar do JUnit 4 para o JUnit 5 não requer reescrever todos os testes — basta adicionar JUnit Vintage Engine e os testes antigos continuarão funcionando. Novos testes são recomendados para serem escritos com JUnit 5 para aproveitar extensões, asserções lambda e suporte integrado a parametrização.
Perguntas frequentes
JUnit é um framework para escrever e executar testes, enquanto Mockito é uma biblioteca para criar objetos mock. Eles são usados juntos: JUnit gerencia a execução do teste e Mockito substitui as dependências da classe sob teste.
Sim, o JUnit 5 é totalmente compatível com projetos Android. Para testes unitários, basta adicionar a dependência junit-jupiter no build.gradle. Testes instrumentados continuam funcionando através do AndroidX Test Runner.
No mínimo, uma única anotação @Test antes do método é suficiente. Para inicialização e limpeza, recomenda-se @BeforeEach e @AfterEach, mas não são obrigatórias.
O Test Runner é um componente do JUnit que escaneia o classpath, encontra métodos com a anotação @Test, cria instâncias de classes de teste e executa os testes. No JUnit 5, esse papel é desempenhado pela JUnit Platform com Test Engines conectados.
Use assertThrows(Class, Executable) — ele aceita o tipo de exceção esperada e uma lambda com a chamada do método. O JUnit verifica que a exceção foi realmente lançada e a retorna para inspeção adicional.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também