Unit and runtime tests
Run the closest regression test before architecture and cross-module discovery checks.
Run a focused test in its owning module first. For example, after changing capability composition:
./gradlew :anvil-capability:capability-common:test
./gradlew verifyArchitecture
./gradlew :anvil-testkit:tests:runtime:testA focused integration test can use temporary files, sockets, isolated protocol workers, or Gradle TestKit without starting Minecraft. Its location follows the owner of the behavior.
Use the relevant module suite
| Owner | Task |
|---|---|
| Global registration, extensions, and scenario lifecycle | :anvil-engine:test |
| Default scoped-service assembly and ownership | :anvil-launcher:test |
| Cache entry access and publication | :anvil-environment:cache:test |
| Artifact acquisition | :anvil-environment:provisioning:provisioning-artifact:test |
| Java provisioning | :anvil-environment:provisioning:provisioning-java:test |
| Workspace policies and snapshots | :anvil-environment:provisioning:provisioning-workspace:test |
| Process lifecycle and restarts | :anvil-environment:execution:execution-managed:test |
| Docker execution settings and image resolution | :anvil-environment:execution:execution-docker:test; containers on a real engine: dockerTest |
| Platform planning and forwarding | :anvil-process:process-common:test |
| Player registration, library selection, and observations | :anvil-player:player-common:test |
| Agent clients, sessions, and observations | :anvil-process:process-protocol:protocol-host:protocol-host-common:test |
| Native agent dispatch and extension loading | :anvil-process:process-protocol:protocol-agent:protocol-agent-common:test |
| Capability discovery and composition | :anvil-capability:capability-common:test |
| MCProtocolLib library, worker contracts and segments | :anvil-player:player-library:library-mcprotocol:mcprotocol-common:test and :anvil-player:player-library:library-mcprotocol:mcprotocol-java:<segment>:check |
| Gradle scenario tooling | :anvil-integration:integration-gradle:gradle-plugin:test |
| Curated plugin composition | :anvil-integration:integration-gradle:gradle-capabilities:test |
| Root build discovery and fixture publication | ./gradlew help |
| Foreground sessions and structured protocol | :anvil-tooling:tooling-runner:test |
| Default tooling entry points and property parsing | :anvil-tooling:tooling-launcher:test |
| IntelliJ build-integration aggregation and launch manifests | :anvil-integration:integration-intellij:intellij-common:test |
| IntelliJ catalog, launches, environments, consoles, actions, editor, and run configurations | :anvil-integration:integration-intellij:intellij-scenario:test |
| IntelliJ accounts, pools, sign-in, and account settings | :anvil-integration:integration-intellij:intellij-account:test |
| IntelliJ native Gradle import | :anvil-integration:integration-intellij:intellij-gradle:test |
| Installed plugin registration and composition | :anvil-integration:integration-intellij:test (also runs every module above) |
| Gradle tooling producer | :anvil-integration:integration-gradle:gradle-tooling:test |
| Build conventions: release data, segments, linkage, legacy Java release, and library layout | :build-logic:check and :build-logic-settings:check, which the root check runs |
Use --tests '*ClassName' to select the regression class when appropriate. Tests should establish an
observable contract or failure outcome, rather than repeat the implementation's steps.
Workspace tests mirror the directory, preparation, and snapshot implementation packages.
Agent client tests exercise host lifetimes and connections; server tests exercise embedded handlers
and endpoints. Cross-process assertions belong in the live suite, with the independently compiled
fixture checking the public client and server API dependencies.
Run the Docker engine tests
Tests that start containers on a real Docker engine live in the module's dockerTest test suite, in
src/dockerTest/java, apart from its test suite. test, and therefore build, never runs them, so neither needs
Docker. Run them with a Docker engine available:
./gradlew dockerTest
./gradlew :anvil-environment:execution:execution-docker:dockerTestThey run in the image anvil.docker.testImage in gradle.properties names, the only place it is named.
It is a copy of eclipse-temurin:21-jdk on the GitHub Container Registry, which the Docker test image workflow
refreshes when dev changes the reference, weekly and on demand. A test pulls the image when the engine does not
have it; the package is public, so that needs no login, and CI pulls it with its GITHUB_TOKEN. To test against
another image for a run, pass -Panvil.docker.testImage=<image>; to change it for everyone, change the property,
and the workflow copies the new image once the change reaches dev.
Check cross-module discovery
anvil-testkit/tests/runtime exercises protocol library selection, platform providers, and capability
composition without Minecraft. It consumes actual runtime dependencies and the separately built external-extension JAR.
./gradlew :anvil-testkit:tests:runtime:test
./gradlew :anvil-testkit:tests:runtime:test --tests '*ExternalProviderDiscoveryIntegrationTest'Use these tests for ranked and explicit protocol library selection, ties between libraries, missing
dependencies, external service discovery, and offline authentication defaults. The runtime suite also
holds JavaVersionTableDocumentationTest, which compares the Java guide's table with the platform
providers' version data. They complement module-level tests
by testing the installed composition rather than manually assembled implementation objects.
Check the IntelliJ package
Tests live with the module that owns the behaviour; intellij-api has no test sources. Each feature
module's tests load its real descriptor fragment through a test-only META-INF/plugin.xml, which adds
the shared services and a stand-in for any contract another module implements, so actions, settings
pages, and extensions are registered exactly as in the plugin. Test fixtures shared by several modules,
such as SwingTestSupport and the controlled tooling process, live in intellij-common/src/testFixtures
and are never packaged in the plugin. The plugin's own tests check how the fragments compose: service
bindings, the settings tree, cross-module action groups, editor extensions, and the tool window.
Run all module tests together:
./gradlew :anvil-integration:integration-intellij:test./gradlew :anvil-integration:integration-intellij:buildPlugin :anvil-integration:integration-intellij:verifyPluginThe verifier checks the declared IDE baselines. To verify against an installed IDE, pass
-Panvil.intellijVerificationPath=/absolute/path/to/idea. IDE tests exercise native model import
and session behavior without starting Minecraft. Project tooling
describes the contract; installation describes
the ZIP workflow.
Validate UI changes against the current IDE as well as the compilation baseline:
./gradlew :anvil-integration:integration-intellij:intellij-scenario:testCurrentIde --tests '*SectionTabsPlatformTest' -Panvil.intellijVerificationPath=/absolute/path/to/ideaThis separate test task keeps baseline compilation intact while using the selected IDE's runtime,
test framework, and sandbox. Omit the path to use the configured current verification version.
The UI sandbox excludes optional Ultimate product hooks, whose obfuscated classes collide under
the test framework's flat class loader; Anvil, Java, Gradle, and the IDE's native themes remain loaded.
Section-switcher tests exercise both standard themes and the current IDE's Islands themes; editor
tab styling can differ from the Services-style JBTabbedPane used for Anvil's sections.
Both declared baselines currently verify as compatible with no deprecated or scheduled-for-removal
API usage. The remaining findings are experimental APIs the Gradle adapter and source discovery rely on
(ExternalSystemBuildEvent and TrustedProjectsListener); recheck them when raising the baseline.
UI tests lay out and paint their screens offscreen on every run. To inspect the renders, add
-Panvil.uiCaptures; the images are written to intellij-scenario/build/reports/ui-captures:
./gradlew :anvil-integration:integration-intellij:intellij-scenario:test -Panvil.uiCapturesFinish with the build
./gradlew buildThe normal build skips the whole real-server test task. For behavior involving Minecraft sessions, packet bindings, forwarding, or platform agents, also run the relevant live coverage. For dependency or publication changes, verify a separate consumer through local publication.