Architecture Testing
Purpose and scope
Turn an agreed architectural promise into a test that exercises its actual mechanism and
fails for the intended violation. A green functional test does not establish transaction,
dependency, concurrency or compatibility properties it never observes. This skill owns
test design and implementation, not architecture selection or governance policy.
Before choosing version-sensitive test APIs, inspect compiler release/toolchains, resolved
framework/test-library versions, runner configuration and the JDKs used by tests and deployment.
The structural example uses release 17 source compilation; its recorded run used JDK 25, not
a Java 17 runtime. Match the target project rather than upgrading it to fit an example. New
dependencies, preview features and toolchain upgrades require their own justification and scope.
Workflow
- Name the promise and failure. Obtain the relevant implementation, existing tests,
package/contract or transaction boundary, dependency versions and build command. For data
tests, also obtain engine/version, migrations, isolation and cache settings. For a budget,
identify the operation and what is counted. If the promise or threshold is unknown, propose
a conditional test design and request the missing contract; do not invent the architecture.
- Choose the smallest setup that retains the mechanism. Use the table below. Fakes and
mocks can isolate behavior but do not establish database or network semantics. A full context
is justified when proxying, wiring or cross-layer behavior is the assertion; inspect slow-suite
timing before assuming that a large context is the cause.
- Control the observation. Define fixture state, transaction ownership, caches, execution
scope, cleanup and time bounds. Count selected classes/tests or observed operations where
an empty selection or disabled instrument could produce a false green.
- Prove the test detects the defect. Use a small violating fixture or a temporary mutation:
forbidden dependency, missing transaction, lazy fetch regression or stale write. Observe the
intended assertion fail, then restore the valid state and rerun. A compile/setup error is not
that proof. Keep mutations isolated and preserve unrelated work.
- Report evidence and limits. Name the command, actual tests run and result, plus what
remains untested. A configuration inspection is evidence of intent; a runtime result proves
only the tested state/interleaving/version. For diagnosis, separate the suspected blind spot
from a reproduced defect and name the experiment that would distinguish them.
Match the assertion to the mechanism
| Promise |
Smallest credible test setup |
| Pure business invariant |
Domain test; add persistence coverage if truth depends on durable state |
| Use-case orchestration |
Owned ports with a suitable fake, stub or focused mock |
| Dependency prohibition |
Imported production classes/build graph plus a known violating fixture |
| HTTP binding, validation, error/response shape |
Web slice with actual relevant advice, serialization and security configuration |
| Gateway protocol and error translation |
Real adapter/client against a controlled server, including applicable failure classes |
| Mapping, constraint, migration or isolation |
Isolated production-family engine with representative configuration and production migrations |
| Local use-case atomicity |
Actual transaction entry point, no outer test transaction masking it, durable-state observation |
| Stale version rejection |
Separate committed transactions using stale state; overlap only if the claim requires it |
| Concurrent interleaving/locking |
Independent transactions/connections, controlled schedule and bounded failure/cleanup |
| Query or remote-call budget |
Enabled scoped counters around full result consumption, representative cardinality |
| Consumer compatibility |
Actual consumer interaction and provider verification, or policy-specific schema checks plus runtime conformance |
Read Boundary and contract tests for structural,
web, gateway or compatibility checks. Read
Persistence and concurrency tests for
data, rollback, budget, migration or concurrency checks. Neither reference is required for
a pure domain assertion.
Decision rules
- Choose doubles by the assertion. A fake can model useful state but can also drift; a mock
can verify a meaningful interaction without freezing every call order. Neither proves the
real adapter works. Avoid simulating vendor internals when a controlled boundary is available.
- An alternative in-memory engine can catch some defects; it cannot establish fidelity to the
production engine's dialect, locking or constraints. Testcontainers is one provisioning option,
not a substitute for matching versions/configuration or ensuring isolation.
- Do not replace semantic properties with convenient syntax. A suffix rule tests names, not
aggregate ownership; an annotation-location rule does not prove a transaction executes.
- Test application/framework integration where it is your responsibility: constraints actually
applied to the request, converters preserving precision, and advice mapping errors. Do not
delete these checks merely because a framework implements part of the mechanism.
- Budget tests catch access growth, not acceptable latency or plans. Performance/plan checks may
run in dedicated CI when representative resources exist; hand capacity claims to
load-testing
and diagnosis to architecture-and-performance.
- An overlap test covers a chosen schedule, not all races. A single-threaded sequence using stale
detached state can verify optimistic version checks; it cannot establish concurrent lock behavior.
- Keep accepted exemptions narrow, named and explained. Do not widen imports, disable empty-rule
failures, reset a baseline or weaken an assertion simply to make the build green.
Minimum deliverable
For a review: evidence, defect or coverage gap, consequence, adjustment and validation.
For implementation: the focused test/change, its prerequisites, how the violating case fails,
the passing run and any remaining coverage gap. Scale this to the task; no suite-wide report
is needed for one guard.
Choosing thresholds and consequences belongs to architecture-fitness-functions; transaction
design to enterprise-transactions; contract policy to rpc-and-api-contracts.
Use Validation cases when evaluating this skill or rehearsing
a difficult review. Those cases evaluate agent decisions, not the application under test.
1---2name: architecture-testing3description: Write or review tests for architectural promises: dependency boundaries, transaction atomicity, persistence mappings, stale-write detection, query budgets and API/event compatibility. Use when green tests missed a lost update or N+1, a boundary exists only in documentation, or an integration test may hide the behavior it claims to verify. Does not choose the architecture or governance thresholds (architecture-fitness-functions), replace general unit-test design, or establish production capacity (load-testing).4---56# Architecture Testing78## Purpose and scope910Turn an agreed architectural promise into a test that exercises its actual mechanism and11fails for the intended violation. A green functional test does not establish transaction,12dependency, concurrency or compatibility properties it never observes. This skill owns13test design and implementation, not architecture selection or governance policy.1415Before choosing version-sensitive test APIs, inspect compiler release/toolchains, resolved16framework/test-library versions, runner configuration and the JDKs used by tests and deployment.17The structural example uses release 17 source compilation; its recorded run used JDK 25, not18a Java 17 runtime. Match the target project rather than upgrading it to fit an example. New19dependencies, preview features and toolchain upgrades require their own justification and scope.2021## Workflow22231. **Name the promise and failure.** Obtain the relevant implementation, existing tests,24 package/contract or transaction boundary, dependency versions and build command. For data25 tests, also obtain engine/version, migrations, isolation and cache settings. For a budget,26 identify the operation and what is counted. If the promise or threshold is unknown, propose27 a conditional test design and request the missing contract; do not invent the architecture.282. **Choose the smallest setup that retains the mechanism.** Use the table below. Fakes and29 mocks can isolate behavior but do not establish database or network semantics. A full context30 is justified when proxying, wiring or cross-layer behavior is the assertion; inspect slow-suite31 timing before assuming that a large context is the cause.323. **Control the observation.** Define fixture state, transaction ownership, caches, execution33 scope, cleanup and time bounds. Count selected classes/tests or observed operations where34 an empty selection or disabled instrument could produce a false green.354. **Prove the test detects the defect.** Use a small violating fixture or a temporary mutation:36 forbidden dependency, missing transaction, lazy fetch regression or stale write. Observe the37 intended assertion fail, then restore the valid state and rerun. A compile/setup error is not38 that proof. Keep mutations isolated and preserve unrelated work.395. **Report evidence and limits.** Name the command, actual tests run and result, plus what40 remains untested. A configuration inspection is evidence of intent; a runtime result proves41 only the tested state/interleaving/version. For diagnosis, separate the suspected blind spot42 from a reproduced defect and name the experiment that would distinguish them.4344## Match the assertion to the mechanism4546| Promise | Smallest credible test setup |47| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |48| Pure business invariant | Domain test; add persistence coverage if truth depends on durable state |49| Use-case orchestration | Owned ports with a suitable fake, stub or focused mock |50| Dependency prohibition | Imported production classes/build graph plus a known violating fixture |51| HTTP binding, validation, error/response shape | Web slice with actual relevant advice, serialization and security configuration |52| Gateway protocol and error translation | Real adapter/client against a controlled server, including applicable failure classes |53| Mapping, constraint, migration or isolation | Isolated production-family engine with representative configuration and production migrations |54| Local use-case atomicity | Actual transaction entry point, no outer test transaction masking it, durable-state observation |55| Stale version rejection | Separate committed transactions using stale state; overlap only if the claim requires it |56| Concurrent interleaving/locking | Independent transactions/connections, controlled schedule and bounded failure/cleanup |57| Query or remote-call budget | Enabled scoped counters around full result consumption, representative cardinality |58| Consumer compatibility | Actual consumer interaction and provider verification, or policy-specific schema checks plus runtime conformance |5960Read [Boundary and contract tests](references/boundary-and-contract-tests.md) for structural,61web, gateway or compatibility checks. Read62[Persistence and concurrency tests](references/persistence-and-concurrency-tests.md) for63data, rollback, budget, migration or concurrency checks. Neither reference is required for64a pure domain assertion.6566## Decision rules6768- Choose doubles by the assertion. A fake can model useful state but can also drift; a mock69 can verify a meaningful interaction without freezing every call order. Neither proves the70 real adapter works. Avoid simulating vendor internals when a controlled boundary is available.71- An alternative in-memory engine can catch some defects; it cannot establish fidelity to the72 production engine's dialect, locking or constraints. Testcontainers is one provisioning option,73 not a substitute for matching versions/configuration or ensuring isolation.74- Do not replace semantic properties with convenient syntax. A suffix rule tests names, not75 aggregate ownership; an annotation-location rule does not prove a transaction executes.76- Test application/framework integration where it is your responsibility: constraints actually77 applied to the request, converters preserving precision, and advice mapping errors. Do not78 delete these checks merely because a framework implements part of the mechanism.79- Budget tests catch access growth, not acceptable latency or plans. Performance/plan checks may80 run in dedicated CI when representative resources exist; hand capacity claims to `load-testing`81 and diagnosis to `architecture-and-performance`.82- An overlap test covers a chosen schedule, not all races. A single-threaded sequence using stale83 detached state can verify optimistic version checks; it cannot establish concurrent lock behavior.84- Keep accepted exemptions narrow, named and explained. Do not widen imports, disable empty-rule85 failures, reset a baseline or weaken an assertion simply to make the build green.8687## Minimum deliverable8889For a review: evidence, defect or coverage gap, consequence, adjustment and validation.90For implementation: the focused test/change, its prerequisites, how the violating case fails,91the passing run and any remaining coverage gap. Scale this to the task; no suite-wide report92is needed for one guard.9394Choosing thresholds and consequences belongs to `architecture-fitness-functions`; transaction95design to `enterprise-transactions`; contract policy to `rpc-and-api-contracts`.96Use [Validation cases](references/validation-cases.md) when evaluating this skill or rehearsing97a difficult review. Those cases evaluate agent decisions, not the application under test.