Skip to content

Running the Tests

Petrus Pradella edited this page Aug 3, 2026 · 5 revisions

Running the Tests

What this page covers: how to run EveryDatabase's test suites — the embedded backends that need nothing, the SQL/Mongo integration suites that need real servers via Docker compose, the -PnoDocker / -PskipStress switches, the throwaway-database plumbing, and the :manager add-on tests.


The 60-second version

export JAVA_HOME=/path/to/jdk-25            # PowerShell: $env:JAVA_HOME = "C:\path\to\jdk-25"

./gradlew :core:test                        # everything (auto-starts the DB containers)

No Docker on the machine? The integration suites self-skip; the embedded ones still run:

./gradlew :core:test -PnoDocker -PskipStress    # embedded only (H2 / LocalFile / InMemory), fast

📌 Note — the build prerequisites (the single JDK 25 toolchain that compiles and runs everything) are on Building from Source. This page is just the test mechanics.


The two tiers of suites

Tier Backends Needs a server?
Embedded H2, Local Files, In-Memory No — always run
Integration MySQL/MariaDB, PostgreSQL, MongoDB Yes — a real server (Docker)

The integration suites guard themselves with a JUnit assumeTrue in each @BeforeAll: when their server is unreachable they self-skip, so the build never fails just because a database is down.


Integration databases via Docker compose

The SQL/Mongo suites need real servers. docker-compose.yml starts all of them on non-default high ports chosen to avoid clashing with any default-port databases already on your host; these ports/credentials match the test defaults, so no configuration is needed. Valkey and Redis back the :manager-jedis cache-sync transport tests.

Service Host port Credentials
MariaDB (MySQL-compatible) 39306 root / root
PostgreSQL 39307 root / root
MongoDB 39308 none — open 1-node replica set (mongodb://localhost:39308/?directConnection=true)
Valkey 39309 none — open
Redis 39310 none — open
docker compose up -d            # start all services in the background
docker compose up -d mariadb    # or just one
docker compose ps               # status / healthcheck of each container
docker compose logs -f          # watch initialization
docker compose down             # stop (keeps volumes — data survives)
docker compose down -v          # stop + wipe volumes (destroys all data)

📌 Note — MariaDB is wire-compatible with MySQL: the mysql-connector-j driver connects to it normally, so the MariaDB container also covers real MySQL. There is no separate MySQL container.

:core:test brings the containers up for you

The Gradle com.avast.gradle.docker-compose plugin is wired so dockerCompose.isRequiredBy(test) — running :core:test starts the containers automatically and stops them when the build finishes. No need to docker compose up first. Useful properties:

./gradlew :core:test -Pdocker.stop        # stop + remove containers after the run
./gradlew :core:test -Pdocker.recreate    # force-recreate the containers
./gradlew :core:test -Pdocker.logs        # surface container logs

⚠️ Gotcha — to run embedded-only without Docker, use -PnoDocker. Do not reach for -x :core:composeUp: under Gradle 9 + docker-compose plugin 0.17.x the test task eagerly queries composeUp's providers, and excluding that task makes the build fail. -PnoDocker skips the wiring itself, which is the supported path.


The switches

./gradlew :core:test                                   # everything
./gradlew :core:test -PskipStress                      # skip the @Tag("stress") 10k-record suites
./gradlew :core:test -PnoDocker                        # no Docker — SQL/Mongo suites self-skip
./gradlew :core:test -PnoDocker -PskipStress           # fastest embedded-only run
./gradlew :core:test --tests "*MariaDbStorageTest"     # one class
./gradlew :core:test --tests "*MariaDbStorageTest.inTransaction_commit_savesAreVisible"   # one method
  • -PskipStress excludes the @Tag("stress") 10k-record suites (one concrete class per backend, e.g. H2StorageStressTest). They run by default; skipping them is much faster.
  • -PnoDocker skips the docker-compose wiring entirely — the SQL/Mongo suites self-skip, the embedded suites still run.

💡 Tip — set verbosity without touching code via the log-level system property: ./gradlew :core:test -Deverydatabase.log.level=info (or debug / trace). See Logging & Diagnostics.


Throwaway databases (and keeping them)

Each SQL/Mongo test method runs against its own freshly-created database, named enc_NNN_<backend>_<methodName>, dropped in @AfterAll — so a failed run never leaves state that poisons the next one. All probe/create/drop plumbing lives in one place, testutil/ThrowawayDatabaseSupport (factories mysql(...), postgres(...), mongo(...)); concrete suites declare a static DBS instance and delegate.

To keep the throwaway databases for inspection after a run:

TEST_KEEP_DATABASES=true ./gradlew :core:test --tests "*PostgreSqlStorageTest"
# PowerShell: $env:TEST_KEEP_DATABASES = "true"; .\gradlew :core:test --tests "*PostgreSqlStorageTest"

Overriding connection coordinates

Resolution order per setting is system property → env var → default (DotEnvTestUtil). Override any backend's host/port/credentials/URL without editing code:

./gradlew :core:test -DMARIADB_PORT=3306 -DMONGO_USER=admin
# or via env vars: MARIADB_HOST, MARIADB_PORT, MONGO_USER, POSTGRES_URL, ...

The :manager add-on tests

The refs/caching module (Caching & References) has its own suite:

./gradlew :manager:test

It runs on the embedded backends (InMemory / H2 / LocalFile), needing no Docker for the bulk of its coverage. The heterogeneous-backend test MultiBackendRefExampleTest resolves one root across all six real backends when Docker is up and self-skips otherwise — an embedded-only variant always runs. Test entities live under the module's testdata (and testdata.multibackend) packages.


How the suites are organized (for when a test fails)

  • A small abstract hierarchy holds the backend-agnostic contract. AbstractStorageTest covers CRUD, codec round-trip, the index/query matrix, and a [base] log: block; AbstractTransactionalStorageTest adds the [tx] transactional/lifecycle/schema suite; AbstractVersionedStorageTest covers optimistic locking. Display names are prefixed [base] / [tx].
  • Each backend extends the right abstract suite, so a cross-backend behavior is exercised on every backend at once. Backend-specific quirks (H2's index-drop enforcement, Mongo's insert race) live in the concrete class.
  • Tests are @Ordered for readability but independent (clean storage per @BeforeEach).

💡 Tip--tests "*AbstractStorageTest*" won't match anything (it's abstract). Target the concrete subclass, e.g. --tests "*H2StorageTest", then narrow to a method with the Class.method form.


See also

Clone this wiki locally