Skip to content

Testing and Verification

tien.nguyen edited this page Jul 31, 2026 · 3 revisions

Testing & Verification Strategy

The Emporia Trading Platform uses a layered verification strategy: automated unit tests, integration tests with real databases, deterministic concurrency schedulers, model checking, static analysis, frontend checks, and end-to-end smoke tests.


Verification Matrix

Layer Tools & Frameworks Target & Purpose Verification Command
Unit & Mock Testing JUnit 5, Mockito, AssertJ Individual business logic, records, state machines mvn test
Code Coverage JaCoCo (0.8.15) Enforcement of 91.95%+ instruction & branch coverage mvn verify
Static Code Quality PMD (7.26.0), custom ruleset Code correctness, resource management, exception handling mvn verify or mvn pmd:check
Database Concurrency Testcontainers, PostgreSQL Optimistic-lock and idempotency behavior under parallel transactions mvn -Ppostgres-it ... test
Controlled Concurrency Fray Scheduler (0.9.0) Controlled JVM thread interleavings for cancel/fill races mvn -Pfray -pl order-management-service -am test
Model Checking TLA+ / TLC Proposed order lifecycle invariants and race semantics java -jar tla2tools.jar ...
Browser & System Smoke Playwright, Vite, OIDC, Kafka Browser routes, dev-server proxy boundaries, API calls, and live event flow npm run test:e2e, scripts/oidc-smoke-test.mjs

Full Verification Runbook

Run the commands from the directory that contains the emporia/ checkout. If you are already inside the repository root, remove the leading emporia/ from paths.

Compile, test, and run PMD for every service, then verify the frontend:

mvn -f emporia/pom.xml verify
mvn -f emporia/authorisation-service/pom.xml verify
mvn -f emporia/gateway/pom.xml verify
npm --prefix emporia/frontend run lint
npm --prefix emporia/frontend run build
npm --prefix emporia/frontend run test:e2e

The Maven verify phase runs PMD 7.26.0 through Maven PMD Plugin 3.28.0 and fails on violations or PMD processing errors. The shared static-analysis/ruleset.xml concentrates on correctness, resource ownership, exception integrity, concurrency, and unambiguous performance problems; it intentionally excludes formatting and subjective style checks. Generated sources and test sources are excluded.

To generate browsable PMD reports without running the full build:

mvn -f emporia/pom.xml -DskipTests pmd:pmd
mvn -f emporia/authorisation-service/pom.xml -DskipTests pmd:pmd
mvn -f emporia/gateway/pom.xml -DskipTests pmd:pmd

Each module writes XML to target/pmd.xml and HTML to target/reports/pmd.html.


Focused Backend Checks

Run only the jqwik order invariants:

mvn -f emporia/pom.xml -pl order-management-service -am \
  -Dtest=TradingOrderPropertyTest \
  -Dsurefire.failIfNoSpecifiedTests=false test

The generated properties cover positive and increment-aligned quantities, positive tick-aligned limit prices, partial-fill quantity accounting, modifications bounded by traded quantity, two-fill weighted averages, randomized command and venue-event sequences, pending cancellation, cancel-versus-fill races in both arrival orders, late fills after venue acknowledgement, and idempotent command redelivery.

Run the real PostgreSQL optimistic-lock race with Testcontainers:

mvn -f emporia/pom.xml -Ppostgres-it -pl order-management-service -am test

This opt-in test applies Flyway migrations to PostgreSQL 16 and races two independent transactions that loaded the same entity version. See the order-management service documentation for the OrbStack command and assertions.

Run the portfolio receipt idempotency and concurrency tests with PostgreSQL:

mvn -f emporia/pom.xml -Ppostgres-it -pl portfolio-service -am test

Run the controlled cancel-versus-full-fill concurrency pilot with Fray:

mvn -f emporia/pom.xml -Pfray -pl order-management-service -am test

The profile adds the isolated Fray source set, runs only its pilot test, and leaves ordinary mvn test unchanged. See the order-management service documentation for its scope and limitations.


Model Checking

Model-check the proposed fill/cancel state machine with TLC:

cd emporia/verification/order-lifecycle
java -XX:+UseParallelGC -jar /path/to/tla2tools.jar \
  -config OrderLifecycle.cfg \
  -metadir target/tlc \
  OrderLifecycle.tla

See the order lifecycle TLA+ model for the checked invariants, race semantics, and model boundaries.

Java aggregate validation and Flyway migrations V2 and V4 enforce the corresponding persisted-state and pending-cancellation invariants. See the order-management invariant documentation for the constraint matrix, migration behavior, and focused test commands.


Frontend Playwright Verification

Run the complete browser regression suite from the frontend package:

npm --prefix emporia/frontend run test:e2e

When the frontend is already running locally, point Playwright at that server instead of letting it start another Vite instance:

PLAYWRIGHT_BASE_URL=http://localhost:3001 \
npm --prefix emporia/frontend run test:e2e

To verify only the local dev-server routing guard for Chrome DevTools well-known probes:

PLAYWRIGHT_BASE_URL=http://localhost:3001 \
npm --prefix emporia/frontend run test:e2e -- tests/e2e/dev-server-routing.spec.ts

This focused test requests /.well-known/appspecific/com.chrome.devtools.json?continue through the Vite development server and verifies that the response is the React SPA shell, not a proxied Spring Boot Whitelabel 404 page. It protects the OIDC proxy boundary by ensuring local Vite only forwards the required authorization metadata paths, such as /.well-known/openid-configuration.


Browser and System Smoke Tests

With the application running, execute the full OIDC and Kafka smoke test:

EMPORIA_ORIGIN=http://localhost:3001 \
EMPORIA_USERNAME=admin \
EMPORIA_PASSWORD=admin123 \
node emporia/scripts/oidc-smoke-test.mjs

The check signs in with Authorization Code + PKCE, verifies instruments, watchlist, quotes, and the order blotter, then exercises a DMA cancel/fill race, depth-aware SMART, scheduled VWAP, materialized history, and order-command-service cancel-all through the live Kafka flow.

Clone this wiki locally