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

Por Rafael (Software Engineer Java) — guia técnico completo
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.
A versão 6.0.0 foi lançada em 30 de setembro de 2025.
Alguns destaques dessa versão:
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.
Vamos entrar em detalhes nas melhorias/chaves e nas mudanças de quebra (breaking changes) que você deve conhecer antes de migrar.
Como engenheiro de software Java (especialmente em ambientes modernos usando Spring Boot, Quarkus, micro-services, etc) você se beneficia de:
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):
GROOVYplugins {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.
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.javapackage 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.javapackage 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.
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).
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.javapackage 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:
TEXTa,b,expected0,0,05,6,11100,200,300
Graças à migração para FastCSV, você ganha:
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:
JAVAimport 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 herdarclass 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).
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:
KOTLINimport org.junit.jupiter.api.BeforeEachimport org.junit.jupiter.api.Testimport kotlinx.coroutines.delayimport kotlinx.coroutines.runBlockingimport kotlin.test.assertTrueclass KotlinCoroutinesDemo {@BeforeEachsuspend fun setup() {// preparação com corrotinadelay(10)}@Testsuspend 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.
Se você usa linha de comando ou execução em CI com o console launcher (ConsoleLauncher), pode utilizar o parâmetro:
TEXTjava -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.
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:
JAVAimport 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.
Como você trabalha com desenvolvimento Java, Spring Boot, Quarkus e microservices, aqui vão algumas recomendações específicas ao adotar JUnit 6:
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:
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 Troubleshooting e Migração do JUnit 5 → JUnit 6
O que achou deste artigo?
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!