Subsystem · testing

Testing

Curie runs JUnit 5 tests via the official platform console runner. No Surefire, no Failsafe, no maven-surefire-plugin XML — declare a test dependency and put a test file where Curie can find it.

How tests are run

On curie test (or as part of curie build), Curie resolves org.junit.platform:junit-platform-console-standalone from Maven Central, places it on the classpath alongside your test classes and dependencies, and shells out to java -jar junit-platform-console-standalone.jar with the test classpath wired up.

The console runner discovers JUnit Jupiter, JUnit Vintage, and JUnit Platform Suite tests in one pass — anything that registers a TestEngine just works.

Source discovery

Curie collects test sources from two layouts simultaneously:

Maven-style projects keep using src/test/java/.

Declaring test dependencies

Curie.toml
[test-dependencies]
"org.junit.jupiter:junit-jupiter"        = "5.11.0"
"org.junit.jupiter:junit-jupiter-engine" = "5.11.0"
"org.assertj:assertj-core"               = "3.26.3"

[test-bom-imports]
"org.junit:junit-bom" = "5.11.0"

[test-bom-imports] pins versions for a whole family of artifacts at once. Combined with empty version strings (""), it lets you declare just the artifact name and inherit the version from the BOM — matching how Spring Boot starters keep their version graph consistent.

Filtering

Pass a substring to curie test to run only matching tests:

$ curie test reverse
Testing string-utils-flat v0.1.0
  Tests           ✔ 3 tests successful  (matched "reverse")

Configuring the JUnit Platform version

By default Curie pins the console-runner version it knows it has tested against. If you need to track a newer (or older) JUnit Platform release, set it in [test]:

Curie.toml
[test]
junitPlatformVersion = "6.0.3"

The same key in a workspace root Curie.toml applies to every member that doesn't override it.

Workspace fan-out

curie test at the workspace root iterates over members in topological order. Upstream members' target/classes directories (not their JARs) are placed on downstream test classpaths, so test runs don't have to wait for upstream JAR packaging.

$ curie test # workspace
Workspace . test (3 members)

[1/3] utils
  Tests           ✔ 8 tests successful
[2/3] core
  Tests           ✔ 12 tests successful
[3/3] app
  Tests           ✔ 7 tests successful

Spock framework

Spock 2.x specs (Groovy-based BDD tests) run through the same JUnit Platform launcher with zero extra configuration beyond adding [spock] to Curie.toml:

Curie.toml
[groovy]
version = "5.0.6"

[spock]
version = "2.4-groovy-5.0"

Curie resolves spock-core from Maven Central, adds it to the test compilation and runtime classpath, and sets a compatible JUnit Platform standalone launcher version (Spock 2.x targets Platform 1.x). Spec files ending in *Spec.groovy, *Test.groovy, or *Tests.groovy are discovered and compiled automatically alongside any Java/Kotlin test sources.

See Groovy & Spock for the full Groovy/Spock reference.

Java agents (Mockito)

Mockito 5 uses the inline mock maker by default, which requires attaching mockito-core as a JVM agent on JDK 21+. Without it the JVM prints a warning and future releases may refuse self-attachment entirely.

Mark any dependency with javaAgent = true in its detailed inline-table form to have Curie pass it as -javaagent:<jar> automatically:

Curie.toml
[test-dependencies]
"org.springframework.boot:spring-boot-starter-test" = ""
"org.mockito:mockito-core" = { version = "", javaAgent = true }

The flag works on [dependencies] too, for agents that must be active at application runtime (curie run / curie dev).

Incremental test runs

Curie stamps the test classes directory + the dep JARs + the test resources, and skips the JVM round-trip when none of those have changed since the last green run. A pure curie test on an unchanged tree exits in milliseconds with Tests up to date.