Testing / JUnit6 Interview Questions
1. What is JUnit 6 and when was it released?
JUnit 6 is the current major version of the JUnit testing framework for Java and the JVM, released as GA on September 30, 2025 -- eight years after JUnit 5. The latest stable release is 6.1.1 (mid-2026). Unlike the disruptive JUnit 4 to 5 migration (which rewrote the entire annotation model), JUn...
2. What is the JUnit 6 architecture and what are its three main components?
JUnit 6 retains the three-tier architecture introduced in JUnit 5, with one key change: all three components now share a single unified version number instead of having separate version schemes. JUnit 6 three-component architecture Component Artifact prefix Role JUnit Platform junit-platform-* Fo...
3. What are the core annotations in JUnit 6 and what does each do?
The JUnit 6 annotation model is unchanged from JUnit 5 Jupiter -- this is by design, making migration from JUnit 5 to JUnit 6 primarily a version bump rather than an annotation rewrite. Core JUnit 6 annotations Annotation Purpose Notes @Test Marks a method as a test case No parameters; replaces J...
4. What assertions does JUnit 6 provide and how do you use them?
JUnit 6 provides a rich set of assertions in org.junit.jupiter.api.Assertions . All methods are static and can be statically imported. Assertions fail the test immediately when the condition is not met (unlike assumptions, which abort silently). import static org . junit . jupiter . api . Asserti...
5. What are parameterized tests in JUnit 6 and how do you write them?
Parameterized tests run the same test method multiple times with different arguments. In JUnit 6 they are written with @ParameterizedTest and a source annotation that provides the data. import org.junit.jupiter.params.ParameterizedTest ; import org.junit.jupiter.params.provider. * ; class Paramet...
6. What is the CancellationToken API introduced in JUnit 6?
One of the headline new features in JUnit 6 is the CancellationToken API -- a cooperative cancellation mechanism that allows launchers (Gradle, Maven, IntelliJ, GitHub Actions) to signal a running test suite to stop cleanly, without killing the JVM process. The problem it solves: in JUnit 5, ther...
7. What are JSpecify nullability annotations in JUnit 6 and why do they matter?
JUnit 6 adds JSpecify nullability annotations ( @Nullable , @NonNull , @NullMarked ) to its entire public API. This is a significant improvement for static analysis, IDE tooling, and Kotlin interoperability. JSpecify annotations in JUnit 6 Annotation Meaning Where applied @NonNull The annotated e...
8. What is the native Kotlin coroutine support in JUnit 6?
JUnit 6 adds first-class support for Kotlin suspend functions as test and lifecycle methods. In JUnit 5, testing coroutines required wrapping every test in runBlocking { } . JUnit 6 eliminates this boilerplate: the Jupiter engine manages the coroutine context internally. // JUnit 5 (before): runB...
9. What are the Extension Model and extension points in JUnit 6?
JUnit 6 uses a single, composable Extension Model replacing JUnit 4's fragmented @RunWith, @Rule, and @ClassRule system. Extensions implement one or more callback interfaces corresponding to specific points in the test lifecycle. Key extension callback interfaces Interface Callback method When it...
10. What are nested tests in JUnit 6 and what is the @TestClassOrder/@TestMethodOrder inheritance change?
Nested tests (inner classes annotated with @Nested ) allow you to organise tests hierarchically, grouping related tests and sharing setup/teardown context. JUnit 6 introduces a notable change: @TestClassOrder and @TestMethodOrder are now recursively inherited by all @Nested classes, giving determ...
11. What is @ParameterizedClass in JUnit 6 and how does it differ from @ParameterizedTest?
@ParameterizedClass is a JUnit 6 (and late JUnit 5) annotation that parameterises an entire test class rather than a single test method. Instead of repeating @ParameterizedTest on every method, the whole class is instantiated multiple times with different argument sets. // @ParameterizedTest : re...
12. What is the FastCSV migration in JUnit 6 and how does it affect @CsvSource and @CsvFileSource?
JUnit 6 replaced the univocity-parsers library (which had stopped receiving maintenance) with FastCSV for parsing CSV data in @CsvSource and @CsvFileSource . FastCSV is actively maintained, has better performance, and is stricter about malformed input. @CsvSource/@CsvFileSource changes in JUnit 6...
13. What modules were removed in JUnit 6 and what replaced them?
JUnit 6 removed several modules that had been deprecated across JUnit 5.x releases. Understanding what was removed and what replaced it is important for migration. Removed modules in JUnit 6 Removed module What it did Replacement in JUnit 6 junit-platform-runner JUnit 4 @RunWith(JUnitPlatform.cla...
14. How do you migrate from JUnit 5 to JUnit 6?
For teams already on JUnit 5.14 and Java 17+ , the JUnit team describes the JUnit 6 migration as a "routine dependency bump". The annotation model is unchanged; what breaks is removed APIs and stricter CSV parsing.
15. What are assumptions in JUnit 6 and how do they differ from assertions?
Assumptions are conditions checked at the start of a test. If an assumption fails, the test is aborted (skipped) rather than failed. Assumptions are used to skip tests that are not meaningful in a particular environment (e.g. running only on Linux, only with network access, only when a feature fl...
16. What is @TestInstance and how does it change test class lifecycle?
By default, JUnit creates a new instance of the test class for each test method. @TestInstance(Lifecycle.PER_CLASS) changes this so a single instance is shared across all test methods in the class. // Default: PER_METHOD (new instance per test) class DefaultLifecycleTest { int count = 0 ; @Test v...
17. What is the @RegisterExtension annotation and how does it differ from @ExtendWith?
@ExtendWith registers an extension via a class reference (declarative, at compile time). @RegisterExtension registers an extension via a field instance at runtime, allowing the extension to be configured with constructor parameters. // @ExtendWith : declarative, no configuration @ExtendWith (Mock...
18. What is the @TempDir annotation in JUnit 6?
@TempDir is a built-in JUnit 6 extension (from junit-jupiter-api ) that creates a temporary directory for a test and automatically deletes it afterwards. It eliminates the boilerplate of creating, using, and deleting temp directories manually. import org.junit.jupiter.api.io.TempDir ; import java...
19. What are dynamic tests in JUnit 6 and how do you create them with @TestFactory?
Dynamic tests are tests generated at runtime rather than defined at compile time. They are created using @TestFactory methods that return a Stream , Collection , or Iterable of DynamicTest objects. import org.junit.jupiter.api.DynamicTest ; import org.junit.jupiter.api.TestFactory ; import static...
20. How does parallel test execution work in JUnit 6?
JUnit 6 supports running tests in parallel to reduce total test suite execution time. It must be enabled via configuration and provides fine-grained control over which tests run in parallel. # Enable parallel execution in junit-platform.properties # (src/test/resources/junit-platform.properties) ...
21. What is @ParameterizedClass in JUnit 6 and how does it differ from @ParameterizedTest?
@ParameterizedClass (introduced in JUnit 5.13 and fully supported in JUnit 6) parameterises an entire test class rather than a single method. All test methods in the class run for each set of arguments. This is ideal when multiple tests share the same setup conditions that vary per invocation. im...
22. What FastCSV migration happened in JUnit 6 and what are the breaking changes?
JUnit 6 replaced the univocity-parsers library (used for CSV parsing in @CsvSource and @CsvFileSource ) with FastCSV . This was necessary because univocity-parsers became unmaintained. FastCSV is faster and stricter, which causes a few breaking changes for tests with previously tolerated malforme...
23. What is the TestInstance lifecycle in JUnit 6 and what are the two modes?
By default JUnit 6 creates a new test class instance for each test method (PER_METHOD). The @TestInstance annotation lets you change this to PER_CLASS, where one instance is shared across all methods in the class. Test instance lifecycle modes Mode Annotation Behaviour Implication PER_METHOD (def...
24. How does test ordering work in JUnit 6 with @TestMethodOrder?
By default JUnit 6 uses a deterministic but non-obvious method order. @TestMethodOrder lets you explicitly control execution order. In JUnit 6, this annotation is recursively inherited by @Nested classes. Available MethodOrderer implementations Orderer Behaviour MethodOrderer.OrderAnnotation Meth...
25. What modules were removed in JUnit 6 and why?
JUnit 6 removed several modules that had been deprecated in earlier JUnit 5.x releases. Knowing what was removed and its replacement is a common interview topic. Modules removed in JUnit 6 Removed module What it did Replacement junit-platform-runner JUnit 4 @RunWith-based runner that could run JU...
26. How do you migrate from JUnit 5 to JUnit 6?
Migrating from JUnit 5 to JUnit 6 is significantly simpler than the JUnit 4 to 5 migration. Because the Jupiter annotation model is unchanged, most projects require only a version bump plus addressing a handful of breaking changes. JUnit 5 to JUnit 6 migration checklist Step Action 1. Update depe...
27. What are assumptions in JUnit 6 and how do they differ from assertions?
Assumptions abort a test silently (marking it as aborted ) when a condition is not met. Assertions fail the test with a failure when a condition is not met. Use assumptions to skip tests that are irrelevant in the current environment rather than to verify business logic. import static org . junit...
28. What is the @TempDir annotation and how has it changed in JUnit 6?
@TempDir creates a temporary directory for a test and automatically deletes it after the test completes. JUnit 6 adds a cleanup attribute to control when (and whether) the directory is deleted, enabling inspection of files after a failing test. import org.junit.jupiter.api.io.TempDir ; import org...
29. How does parallel test execution work in JUnit 6?
JUnit 6 supports parallel test execution at both the class and method level. It is disabled by default and is configured via junit-platform.properties or programmatic launcher configuration. The implementation uses Java's ForkJoinPool . # junit-platform.properties (in src/test/resources/) # Enabl...
30. What is the difference between @ExtendWith and @RegisterExtension in JUnit 6?
JUnit 6 provides two ways to register extensions. The choice between them depends on whether you need programmatic construction (with constructor arguments) or simple declarative annotation use. @ExtendWith vs @RegisterExtension Aspect @ExtendWith @RegisterExtension Location Annotation on class o...
31. What is the @RepeatedTest annotation in JUnit 6?
@RepeatedTest(n) runs a test method exactly n times. Each repetition is treated as an independent test. It is useful for verifying non-deterministic behaviour, testing concurrency, or stress-testing time-sensitive operations. import org.junit.jupiter.api.RepeatedTest ; import org.junit.jupiter.ap...
32. What is the ExtensionContext and its Store used for in JUnit 6?
The ExtensionContext is the primary object through which extensions interact with the JUnit 6 runtime. It provides access to the current test method, class, display name, tags, and a key-value Store for sharing data between extension callbacks. // ExtensionContext.Store: share data between callba...
33. What are tags and filtering in JUnit 6 and how are they used?
Tags categorise tests. At build time you can include or exclude specific tags, enabling selective test execution (e.g. run only fast tests in a pre-commit hook, all tests in CI). // Annotate tests with @Tag @Tag ( "fast" ) @Tag ( "unit" ) class FastUnitTest { @Test void test1() { ... } } @Tag ( "...
34. What are dynamic tests in JUnit 6 and how does @TestFactory work?
Dynamic tests are generated at runtime rather than being declared statically as annotated methods. The @TestFactory method returns a collection or stream of DynamicTest or DynamicContainer objects, each with its own name and executable. import org.junit.jupiter.api.DynamicTest ; import org.junit....
35. How does JUnit 6 integrate with Maven and Gradle?
JUnit 6 requires updated build tool versions that support the JUnit Platform. Maven needs Surefire 3.x and Gradle needs 8.x .
36. What is the @Suite API in JUnit 6 and how do you group tests into suites?
JUnit 6 provides a @Suite annotation (in junit-platform-suite ) for declaratively grouping tests from multiple classes or packages. This replaces JUnit 4's @RunWith(Suite.class) and JUnit Platform Runner (which was removed in JUnit 6). import org.junit.platform.suite.api. * ; // Basic suite: sele...
37. What is the ParameterResolver extension interface and how do you use it for custom injection?
The ParameterResolver extension interface allows you to inject custom objects into test method parameters, @BeforeEach methods, and constructors. This is the foundation of how MockitoExtension injects @Mock objects and how SpringExtension injects beans. // Custom ParameterResolver: inject a confi...
38. What is conditional test execution in JUnit 6 and what built-in conditions are available?
JUnit 6 provides condition annotations that skip or enable tests based on runtime conditions without writing assumption code inside the test body. These are implemented as extensions using the ExecutionCondition interface. Built-in condition annotations Annotation Skips test when... @EnabledOnOs ...
39. What are test interfaces and default methods in JUnit 6?
JUnit 6 supports placing @Test , @BeforeEach , @AfterEach , and other annotations on interface default methods . Test classes implementing the interface automatically inherit those tests and lifecycle methods. This is useful for contract testing and shared test behaviour. // Define a reusable con...
40. How does JUnit 6 interact with Mockito and Spring Test?
JUnit 6 integrates with major testing frameworks via its Extension Model. Mockito and Spring Test both provide JUnit 6-compatible extensions. // Mockito with JUnit 6 : // Use MockitoExtension (works identically to JUnit 5 ) @ExtendWith (MockitoExtension . class) class OrderServiceTest { @Mock Ord...
41. What is the TestExecutionListener SPI in JUnit 6?
The TestExecutionListener is a Service Provider Interface (SPI) that allows external tools (IDEs, build plugins, reporting frameworks) to observe test execution events without modifying test code. Unlike extensions (which are registered in test code), listeners are registered via ServiceLoader or...
42. What are the key differences between JUnit 4 and JUnit 6?
JUnit 4 and JUnit 6 have fundamentally different architectures, annotation models, and extension mechanisms. This is the most common comparison question in interviews where teams have legacy JUnit 4 code. JUnit 4 vs JUnit 6 comparison Aspect JUnit 4 JUnit 6 Package org.junit org.junit.jupiter.api...
43. What is TestWatcher extension interface in JUnit 6 and when do you use it?
The TestWatcher interface provides callbacks for the four possible test outcomes: succeeded, failed, aborted, and disabled. It is simpler than implementing multiple separate extension interfaces when you just want to react to test results. import org.junit.jupiter.api.extension.TestWatcher ; publ...
44. What is the ConsoleLauncher and how do you run JUnit 6 tests from the command line?
The ConsoleLauncher ( junit-platform-console-standalone ) is a self-contained JAR that can discover and run JUnit 6 tests from the command line without Maven or Gradle. It is useful for CI scripts, Docker containers, and quick local runs. # Download the standalone JAR: # From: https://repo1.maven...
45. What is the @AutoClose extension and how does it simplify resource management in JUnit 6?
The @AutoClose annotation (introduced in JUnit 5.11 and fully supported in JUnit 6) automatically calls close() on fields implementing AutoCloseable at the end of the test lifecycle, eliminating the need for @AfterEach / @AfterAll teardown methods for simple resource cleanup. import org.junit.jup...
46. How does JUnit 6 support for Kotlin differ from JUnit 5?
JUnit 6 significantly improves Kotlin support beyond just suspend function tests. The minimum Kotlin version is 2.2 and several common pain points from JUnit 5 Kotlin usage are addressed. JUnit 6 Kotlin improvements Area JUnit 5 pain point JUnit 6 improvement suspend tests runBlocking required ev...
47. What is the @DisplayNameGeneration annotation in JUnit 6?
@DisplayNameGeneration automatically generates human-readable display names for all test methods in a class without requiring a @DisplayName on each method. It transforms method names (which must follow identifier rules) into more readable strings. import org.junit.jupiter.api.DisplayNameGenerati...
48. What is TestReporter in JUnit 6 and how do you use it?
TestReporter lets test methods publish key-value entries to the test execution report. Unlike System.out.println , reported values are attached to the test result and appear in IDE test reports and XML output -- they are not just lost in console noise. import org.junit.jupiter.api.TestReporter ; ...
49. What are the unified version changes in JUnit 6 and why do they matter for dependency management?
One of the practical improvements in JUnit 6 is the adoption of a single unified version number across all three components. In JUnit 5, the components used different version schemes, causing widespread confusion and dependency conflicts. JUnit version comparison Component JUnit 5 versions JUnit ...
50. What are best practices and anti-patterns in JUnit 6 test design?
Writing maintainable, fast, and reliable tests requires following established principles. Knowing common anti-patterns is as important as knowing the APIs. JUnit 6 best practices and anti-patterns Category Best practice Anti-pattern to avoid Test isolation Each test should set up its own state in...