# Dynamic Tests, Ordering and Parallel Execution — JUnit 5 & Mockito

Source: https://www.skillbyai.com/en/java-testing/a-dynamic

> Generate tests at run time, control ordering and run tests in parallel safely.

## More control over execution

**Dynamic tests** are generated at run time by a **`@TestFactory`** method returning a stream or collection of `DynamicTest` (and optionally `DynamicContainer` for grouping). They suit test cases discovered from data, such as one test per JSON fixture file. Unlike parameterised tests, dynamic tests do not get `@BeforeEach` and `@AfterEach` callbacks per dynamic test, only per factory method. **Ordering**: JUnit runs tests in a deterministic but intentionally non-obvious order; well-designed unit tests must not depend on order. When order genuinely matters (for example in a step-by-step integration scenario), use `@TestMethodOrder(MethodOrderer.OrderAnnotation.class)` with `@Order(n)`, but prefer independent tests. **Parallel execution** speeds up large suites: enable it in `junit-platform.properties` with `junit.jupiter.execution.parallel.enabled=true` and choose the default mode (`concurrent` or `same_thread`). Tests that share resources (a file, a static field, a database table) need `@ResourceLock` or `@Execution(SAME_THREAD)`, otherwise parallelism creates flaky failures.

## A test factory and parallel configuration

One dynamic test per fixture file; parallel execution enabled for the suite.

```java
class TaxRulesTest {

    @TestFactory
    Stream<DynamicTest> everyFixtureMatchesExpectedTax() throws IOException {
        Path fixtures = Path.of("src/test/resources/tax-cases");
        return Files.list(fixtures)
            .filter(p -> p.toString().endsWith(".json"))
            .map(p -> DynamicTest.dynamicTest(p.getFileName().toString(), () -> {
                TaxCase c = TaxCase.read(p);
                assertEquals(c.expectedTaxPaise(), TaxRules.taxFor(c.invoice()));
            }));
    }
}

// src/test/resources/junit-platform.properties
// junit.jupiter.execution.parallel.enabled = true
// junit.jupiter.execution.parallel.mode.default = concurrent
// junit.jupiter.execution.parallel.mode.classes.default = concurrent

@ResourceLock("global-clock")             // tests touching the same shared resource run one at a time
class ClockDependentTest { /* ... */ }
```

## Order-dependent tests are a smell

If tests pass only in a certain order, one test is leaking state into another. Find the shared state (a static field, a database row, a file) and isolate it, rather than pinning the order.

**Quiz:** What do you need to make tests that share a resource safe under JUnit parallel execution?

- [ ] Nothing; JUnit detects shared resources
- [ ] Static fields
- [x] Synchronisation such as @ResourceLock or running them in the same thread
- [ ] More assertions

*Answer:* Synchronisation such as @ResourceLock or running them in the same thread. Shared mutable resources must be declared so JUnit serialises access to them.
