JUnit 6.0.0 — O que há de novo, por que migrar e como usar

––– views
Atualizado em 1 de novembro de 2025
JUnit 6.0.0 — O que há de novo, por que migrar e como usar

JUnit 6.0.0 — O que há de novo, por que migrar e como usar

Por Rafael (Software Engineer Java) — guia técnico completo

1. Introdução

O framework de testes JUnit tem sido a principal ferramenta de testes de unidade no ecossistema Java há muitos anos. A versão anterior principal, JUnit 5 (Jupiter/Platform) trouxe uma grande modernização. Agora, com a chegada da versão 6.0.0, temos uma nova etapa de evolução — não apenas continuidade, mas com mudanças importantes para o desenvolvedor Java moderno. A seguir exploramos o que mudou, por que vale a pena migrar, e como aproveitar bem os novos recursos.

Visão geral da versão

A versão 6.0.0 foi lançada em 30 de setembro de 2025.

Alguns destaques dessa versão:

  • O baseline mínimo de Java agora é Java 17 (ou superior) – Java 16 ou inferior não são mais compatíveis.
  • O baseline mínimo de Kotlin é agora Kotlin 2.2.
  • Uma única numeração de versão para os módulos Platform, Jupiter e Vintage (antes havia divergências).
  • Uso de anotações de nulabilidade do JSpecify para indicar parâmetros/retornos que aceitam ou não null.
  • Integração de funcionalidades de Java Flight Recorder (JFR) no módulo junit-platform-launcher.
  • Muitas APIs obsoletas removidas e melhorias de performance, usabilidade e consistência.
  • Em resumo: se você está desenvolvendo em Java moderno (17+), quer tirar proveito de melhores APIs de teste, execução paralela, ordenação determinística, etc., o JUnit 6 traz um pacote muito atraente.

    2. Principais melhorias e mudanças

    Vamos entrar em detalhes nas melhorias/chaves e nas mudanças de quebra (breaking changes) que você deve conhecer antes de migrar.

    2.1 Melhorias gerais (Platform)

  • Novo método Launcher.execute(LauncherExecutionRequest) e LauncherDiscoveryRequestBuilder.forExecution() — isso permite maior flexibilidade para configurar a execução de testes via API do lançador.
  • Seletores adicionais como DiscoverySelectors.selectClasses(…) e selectClassesByName(…) que tornam a seleção de classes para execução de testes mais intuitiva.
  • Suporte formal para cancelamento de execução de testes via CancellationToken. Isso significa que frameworks que controlam execução (ex: IDEs ou ambientes CI) podem abortar testes em curso.
  • Novo modo -fail-fast para o ConsoleLauncher, de modo que a execução para no primeiro teste falho.
  • A ordenação de classes internas @Nested agora é determinística (e segue ClassOrderer.Default e MethodOrderer.Default) quando aplicável.
  • Migração para a biblioteca FastCSV para @CsvSource e @CsvFileSource, melhorando consistência e desempenho ao lidar com CSV malformado.
  • 2.2 Melhorias específicas para JUnit Jupiter (módulo de testes)

  • A anotação @Nested agora herda o @TestMethodOrder da classe de fora para as classes internas, o que melhora previsibilidade em hierarquias de teste.
  • Suporte para métodos de teste e métodos de ciclo de vida suspend do Kotlin — ou seja, se você utiliza Kotlin com corrotinas, pode escrever testes assíncronos suspensos.
  • Uniformização de nomes de exibição (display names) em testes parametrizados — por exemplo, argumentos formatados como name = value, textos entre aspas, caracteres especiais escapados.
  • 2.3 Deprecações e quebras de compatibilidade

  • A versão mínima de Java como dito agora é Java 17 — portanto, se seu projeto estiver em Java 8, 11 ou 16, será necessária atualização.
  • O módulo junit-platform-runner e junit-platform-jfr foram removidos; a funcionalidade que tinham foi incorporada no junit-platform-launcher.
  • Muitos métodos e classes marcadas como obsoletas foram removidas (por exemplo, ClasspathScanningSupport, BlacklistedExceptions, etc.).
  • No módulo Jupiter: MethodOrderer.Alphanumeric, InvocationInterceptor.interceptDynamicTest(…), entre outros, foram removidos.
  • Algumas mudanças em @CsvSource e @CsvFileSource: o atributo lineSeparator foi removido (agora detecta automaticamente) e valores após aspas não são mais permitidos.
  • O módulo junit-jupiter-migrationsupport agora está deprecated e será removido em versões futuras; migração de JUnit 4 para Jupiter deve ser feita com atenção.
  • 2.4 Por que essas mudanças importam para você

    Como engenheiro de software Java (especialmente em ambientes modernos usando Spring Boot, Quarkus, micro-services, etc) você se beneficia de:

  • Menos legado: remoção de APIs antigas ajuda a manter os testes mais limpos e com menos “histórico morto”.
  • Java 17+ como baseline: se você já está com Spring Boot 3+ ou Quarkus recentinho, provavelmente já está em Java 17, então sem problema — e poderá usar recursos modernos do Java no seu código de teste.
  • Melhor usabilidade: a ordenação determinística ajuda a evitar “flapping” de testes; o modo fail-fast e cancelamento ajudam em testes demorados ou pipelines CI.
  • Integração com Kotlin e corrotinas: se seu time usa Kotlin ou partes do projeto são em Kotlin, agora os testes podem tirar proveito direto.
  • Melhor manipulação de CSV e display names: para testes parametrizados, você terá mais uniformidade e melhores relatórios.
  • Preparação para o futuro: migrar agora para JUnit 6 coloca seu projeto um passo à frente — antigas versões (JUnit 4 ou JUnit 5 sem update) podem vir a ter menos suporte com gems de ecossistema futuros.
  • 3. Como migrar / configurar para usar JUnit 6

    3.1 Dependências no Maven e Gradle

    Para começar com JUnit 6.0.0, veja como configurar:

    Maven (pom.xml):

    XML
    <properties>
    <java.version>17</java.version>
    </properties>
    <dependencies>
    <dependency>
    <groupId>org.junit</groupId>
    <artifactId>junit-bom</artifactId>
    <version>6.0.0</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>
    <build>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0</version> <!-- ou superior -->
    </plugin>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>3.0.0</version>
    </plugin>
    </plugins>
    </build>

    Gradle (build.gradle):

    GROOVY
    plugins {
    id 'java'
    }
    java {
    toolchain {
    languageVersion = JavaLanguageVersion.of(17)
    }
    }
    repositories {
    mavenCentral()
    }
    dependencies {
    testImplementation platform('org.junit:junit-bom:6.0.0')
    testImplementation 'org.junit.jupiter:junit-jupiter'
    }
    test {
    useJUnitPlatform()
    testLogging {
    events "passed", "skipped", "failed"
    }
    }
    Vale lembrar: seu projeto deve compilar sob Java 17 ou superior — se estiver usando Spring Boot 2.x com Java 8 ou 11, será necessário planejar a migração.

    3.2 Considerações antes da migração

  • Verifique se todos os seus testes (e dependências de teste) são compatíveis com Java 17+.
  • Revise o uso de módulos removidos ou descontinuados (ex: junit-platform-runner, junit-jupiter-migrationsupport).
  • Revise arquivos de configuração como junit-platform.properties, @TestMethodOrder, etc., para adequar à nova ordem determinística.
  • Verifique pipelines CI/CD: o plugin Surefire/Failsafe deve suportar a nova versão (versão 3.0.0+).
  • Verifique extensões de teste ou frameworks (ex: Spring Test, Quarkus Test) se oferecem suporte para JUnit 6; na maioria dos casos devem funcionar já que são baseados no JUnit Platform.
  • Se estiver usando Kotlin com testes, aproveite o suporte a suspend, mas precisará kotlin-stdlib, kotlin-reflect, kotlinx-coroutines.
  • 3.3 Exemplo mínimo de projeto

    Estrutura (src/main/java … src/test/java) normal.

    Uma classe de produção simples, e uma classe de teste.

    JAVA
    // src/main/java/com/exemplo/Calculator.java
    package com.exemplo;
    public class Calculator {
    public int add(int a, int b) {
    return a + b;
    }
    public int divide(int a, int b) {
    if (b == 0) {
    throw new IllegalArgumentException("divisor zero");
    }
    return a / b;
    }
    }

    Outro exemplo:

    JAVA
    // src/test/java/com/exemplo/CalculatorTest.java
    package com.exemplo;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.Nested;
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.api.TestMethodOrder;
    import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
    import org.junit.jupiter.api.Order;
    import static org.junit.jupiter.api.Assertions.*;
    @DisplayName("Testes do Calculator")
    @TestMethodOrder(OrderAnnotation.class)
    class CalculatorTest {
    Calculator calculator = new Calculator();
    @Test
    @DisplayName("1 + 1 = 2")
    @Order(1)
    void testAdd() {
    assertEquals(2, calculator.add(1, 1));
    }
    @Nested
    @DisplayName("Divisão")
    class DivisionTests {
    @Test
    @DisplayName("Dividir por número diferente de zero")
    @Order(1)
    void testDivideNormal() {
    assertEquals(2, calculator.divide(4, 2));
    }
    @Test
    @DisplayName("Dividir por zero lança exceção")
    @Order(2)
    void testDivideByZero() {
    IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
    () -> calculator.divide(4, 0));
    assertEquals("divisor zero", ex.getMessage());
    }
    }
    }

    Esse exemplo funciona da mesma forma que em versões anteriores, mas mostra uso de @Nested, @Order, @DisplayName. Na migração para JUnit 6 você poderá inclusive simplificar ou adicionar novos recursos conforme veremos nos próximos exemplos.

    4. Exemplos práticos dos novos recursos do JUnit 6

    Agora vamos nos aprofundar nas funcionalidades mais recentes que você pode aproveitar em seus testes — com exemplos práticos (com base em Java, já que seu perfil é Java/Spring/Quarkus).

    4.1 Uso de @CsvSource e @CsvFileSource com FastCSV

    Em JUnit 6, como mencionado, o parser interno mudou para FastCSV o que significa uma manipulação mais robusta de entradas mal-formadas e melhor desempenho. JUnit

    JAVA
    // src/test/java/com/exemplo/CalculatorParameterizedTest.java
    package com.exemplo;
    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.CsvSource;
    import org.junit.jupiter.params.provider.CsvFileSource;
    import static org.junit.jupiter.api.Assertions.*;
    class CalculatorParameterizedTest {
    Calculator calculator = new Calculator();
    @ParameterizedTest(name = "{index} => a={0}, b={1}, expected={2}")
    @CsvSource({
    "1, 1, 2",
    "2, 3, 5",
    "10, 5, 15"
    })
    void testAddCsv(int a, int b, int expected) {
    assertEquals(expected, calculator.add(a, b));
    }
    @ParameterizedTest(name = "{index} => a={0}, b={1}, expected={2}")
    @CsvFileSource(resources = "/add-cases.csv", numLinesToSkip = 1)
    void testAddCsvFile(int a, int b, int expected) {
    assertEquals(expected, calculator.add(a, b));
    }
    }

    No arquivo src/test/resources/add-cases.csv você poderia ter:

    TEXT
    a,b,expected
    0,0,0
    5,6,11
    100,200,300

    Graças à migração para FastCSV, você ganha:

  • Melhor detecção de inconsistências (por exemplo, aspas não fechadas agora lançam exceção).
  • Atributos como ignoreLeadingAndTrailingWhitespace, nullValues agora aplicam também aos cabeçalhos.
  • lineSeparator removido — agora aceita automaticamente \r, \n ou \r\n.
  • 4.2 Herança de ordenação em @Nested classes

    Uma melhoria importante: se você aplicar @TestMethodOrder em uma classe de teste, as classes aninhadas (@Nested) agora herdarão essa ordenação por padrão. Além disso, há a possibilidade de usar MethodOrderer.Default/ClassOrderer.Default para “resetar” a ordenação padrão.

    Exemplo:

    JAVA
    import org.junit.jupiter.api.*;
    import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
    import static org.junit.jupiter.api.Assertions.*;
    @TestMethodOrder(OrderAnnotation.class)
    class OuterTest {
    @Test
    @Order(1)
    void outerFirst() {
    // ...
    }
    @Test
    @Order(2)
    void outerSecond() {
    // ...
    }
    @Nested
    @TestMethodOrder(OrderAnnotation.class) // pode declarar explicitamente ou herdar
    class InnerTest {
    @Test
    @Order(1)
    void innerFirst() {
    // ...
    }
    @Test
    @Order(2)
    void innerSecond() {
    // ...
    }
    }
    }

    Esse comportamento melhora predictibilidade de execução de testes em classes aninhadas, o que é relevante em projetos com muitos testes estruturados em hierarquia (por exemplo, por feature, por cenário).

    4.3 Suporte a Kotlin + suspend (caso use Kotlin)

    Se em algum ponto você usar Kotlin (mesmo que não seja seu principal foco agora), o JUnit 6 já traz suporte a métodos suspend para teste ou ciclo de vida. Exemplo simples:

    KOTLIN
    import org.junit.jupiter.api.BeforeEach
    import org.junit.jupiter.api.Test
    import kotlinx.coroutines.delay
    import kotlinx.coroutines.runBlocking
    import kotlin.test.assertTrue
    class KotlinCoroutinesDemo {
    @BeforeEach
    suspend fun setup() {
    // preparação com corrotina
    delay(10)
    }
    @Test
    suspend fun testWithCoroutine() {
    val result = suspendFun()
    assertTrue(result)
    }
    private suspend fun suspendFun(): Boolean {
    delay(100)
    return true
    }
    }

    Isso permite, por exemplo, testar serviços assíncronos com corrotinas de Kotlin diretamente.

    4.4 Uso do modo “fail-fast” e cancelamento de execução

    Se você usa linha de comando ou execução em CI com o console launcher (ConsoleLauncher), pode utilizar o parâmetro:

    TEXT
    java -jar junit-platform-console-standalone-6.0.0.jar --fail-fast --scan-classpath …

    Isso faz com que, ao encontrar o primeiro teste em falha, o restante seja cancelado — útil para pipelines onde falhas iniciais devem parar a execução, reduzindo tempo. Internamente, o cancelamento do teste é suportado via API CancellationToken.

    4.5 Exemplo de conjunto de testes com Platform API

    Se você for escrever engenharia de testes ou integração com o Platform (por exemplo, criar um launcher customizado ou plugin), o JUnit 6 oferece APIs melhoradas:

    JAVA
    import org.junit.platform.launcher.Launcher;
    import org.junit.platform.launcher.LauncherDiscoveryRequest;
    import org.junit.platform.launcher.LauncherDiscoveryRequestBuilder;
    import org.junit.platform.engine.discovery.DiscoverySelectors;
    import org.junit.platform.launcher.core.LauncherFactory;
    public class CustomTestLauncher {
    public static void main(String[] args) {
    LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
    .selectors(DiscoverySelectors.selectClasses(MyTestClass1.class, MyTestClass2.class))
    .build();
    Launcher launcher = LauncherFactory.create();
    launcher.execute(request);
    }
    }

    Observe o uso de selectClasses(…), e o builder moderno — melhorias de usabilidade introduzidas em 6.0.0.

    5. Boas práticas e dicas para seu contexto (Spring Boot, Quarkus, microserviços)

    Como você trabalha com desenvolvimento Java, Spring Boot, Quarkus e microservices, aqui vão algumas recomendações específicas ao adotar JUnit 6:

  • Integrar com Spring Boot Test: Se estiver usando Spring Boot (v3+ provavelmente já com Java 17), mantenha a anotação @SpringBootTest ou @WebMvcTest normalmente — o JUnit 6 é compatível via JUnit Platform. Talvez não precise alterar nada além das dependências.
  • Usar Quarkus Test: Se usar Quarkus, o suporte a JUnit 6 virá via extensão quarkus-junit5 (ou futura versão para JUnit6). Verifique versões da extensão para garantir compatibilidade.
  • Microservices e testes de integração: Em ambientes de microserviços, onde testes de integração podem levar tempo, o modo fail-fast e o cancelamento de execução ajudam a controlar execução em CI/CD.
  • Paralelismo de testes: Com baseline Java 17, você pode ativar execução paralela de testes (via configuração junit.jupiter.execution.parallel.enabled = true etc.) como nas versões anteriores — só lembre de garantir que seus testes sejam thread-safe (especialmente em microservices onde banco de dados ou containers podem sofrer concorrência).
  • Ordenação determinística: Em ambientes de equipe, com muitos testes, evita surpresa onde testes “à ordem aleatória” variavam de execução para execução. A herança de ordenação nas classes @Nested ajuda a estruturar melhor.
  • Códigos legados: Se seu projeto ainda tem muitos testes em JUnit 4, você pode usar o módulo Vintage para mantê-los funcionando temporariamente, mas fique atento: no JUnit 6 esse módulo está deprecated e vai sumir em versões futuras.
  • 6. Resumo e recomendação

    A chegada do JUnit 6.0.0 representa um passo importante para manter o ecossistema de testes Java moderno, limpo e alinhado com as versões recentes do Java e Kotlin. Se seu projeto já está rodando com Java 17+, a migração para JUnit 6 vale fortemente a pena — você ganha APIs mais limpas, menor legado morto, melhor integração em pipelines de CI/CD, e novas funcionalidades úteis como cancelamento de execução, melhor parametrização e suporte a Kotlin.

    Minha recomendação:

  • Atualize as dependências para JUnit 6 – vendo se versões dos plugins/módulos suportam.
  • Execute seus testes existentes — verifique se algo quebra (ex: APIs removidas, uso de módulos obsoletos).
  • Aproveite os novos recursos gradualmente — comece por parametrizados ou @Nested bem estruturados.
  • Documente para a equipe as novas práticas (ex: uso de ordenação, características do CSV, etc.).
  • Em pipeline CI, adicione -fail-fast ou monitore execução para falhas mais rápidas.
  • Se por alguma razão seu projeto ainda está em Java 11 ou inferior, ou depende fortemente de testes legados, talvez faça sentido aguardar ou migrar de forma faseada — mas para novos módulos ou microservices, já começaria com JUnit 6.

    Guia de solução de problemas e migração

    Guia de Troubleshooting e Migração do JUnit 5 → JUnit 6

    7. Referência

    junit-user-guide-6.0.0.pdf

    JUnit Release Notes

    What’s new in JUnit 6: Key Changes and Improvements

    JUnit 5 : Step-by-step Tutorial - Mastertheboss

    O que achou deste artigo?

    Apoie este projeto

    Gostou do conteúdo?

    Se este conteúdo te ajudou de alguma forma, considere fazer uma doação. Seu apoio me ajuda a continuar criando conteúdo de qualidade!

    Cada contribuição faz a diferença • Totalmente opcional
    📬Newsletter Exclusiva

    Atualizações na sua caixa de entrada!

    Receba atualizações semanais sobre novos artigos, tutoriais, dicas de programação e descobertas tecnológicas.

    Sem spam • Cancele quando quiser • Conteúdo exclusivo

    Artigos Relacionados

    Nenhum artigo encontrado

    Tente usar palavras-chave diferentes