Install
$ agentstack add skill-hmcts-claude-cpp-test-authoring ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
CPP Test Authoring
Guides contributors through the conventions of the two HMCTS Crime Common Platform test repositories so new tests slot into existing patterns instead of forking them.
Repos covered:
cpp-ui-e2e-serenity— UI end-to-end (Serenity BDD 4.x + Cucumber 6 + Selenium, Java 17, Maven)cpp-apitests— API integration tests (JUnit 5 + REST Assured, Java 17, Maven)
When to Use
- User asks to add or extend a UI E2E test, Cucumber feature, step definition, or page object
- User asks to add or extend an API integration test (
*IT.java) - User asks "how do I add a test for X" while inside either repo
- Reviewing whether a proposed test follows the established pattern (defer the actual PR review to
review-pr)
When NOT to Use
- Authoring unit tests inside a runtime service (
cpp-context-*,cpp-mbd-*) — that's part of the service's own conventions - Writing or modifying Spring Boot service code — see
springboot-service-from-template - Pipeline failures — defer to
pipeline-debug - WCAG audits — defer to
accessibility-check
Prerequisites
Before writing test code:
- Story has acceptance criteria — apply
write-acceptance-criteriaif missing - For UI scenarios, the Gherkin draft exists — apply
generate-bdd-specsif missing - Jira ticket is linked (hard rule from
claude/CLAUDE.md) - No PII, case data, or court reference numbers in any planned fixture, feature, or assertion (hard rule)
Step 1 — Identify the Repo and Test Layer
| Repo | Layer | Marker files | |------|-------|--------------| | cpp-ui-e2e-serenity | UI E2E | serenity.properties, azure-pipelines-dev01_*.yml, src/test/resources/features/ | | cpp-apitests | API integration | apitests-pipeline.yaml, api-integration-test/ module, *IT.java suffixed tests |
If neither marker is present, stop — you're in the wrong repo.
Step 2 — UI E2E: Authoring a Serenity / Cucumber Test
Directory map
cpp-ui-e2e-serenity/
├── src/test/java/com/
│ ├── pageobjects/ # One class per page/section; holds locators + interactions
│ ├── stepdefinitions/ # Cucumber glue; extends the relevant page object
│ └── runner/ # TestRunner.java, RetryTestRunner.java
├── src/test/resources/
│ ├── features// # *.feature files (Gherkin)
│ ├── locators/custom-locators.json
│ └── testdata//
└── serenity.properties
Authoring checklist
- Reuse first — grep
stepdefinitions/andpageobjects/for the journey before creating new classes. Duplicating a step definition is the single most common review reject. - Place the feature file under the correct
features//folder. Match the naming style of neighbours (CPS,In-Sprint, etc.). - Tag scenarios for the pipeline they belong in. The repo has many runner profiles:
azure-pipelines-dev01_regression.yml— main regressionazure-pipelines-dev01_BPO_regression.yml— BPO regressionazure-pipelines-dev01_migration*.yml— migration suites (vanilla / EDT / nows / ts)azure-pipeline-cdci-dlrm.yml— DLRM
Choose tags consistent with the existing features in the same folder.
- Step definitions must
extendsthe page object they exercise. Annotate steps with@Step. Do not hold state in static fields — use the Serenity session. - Page objects own all locator strategy. Register new locators in
src/test/resources/locators/custom-locators.json; do not hard-code selectors in Java. - Wait correctly — use Serenity / WebDriverWait conditions. No
Thread.sleep. - Test data goes under
src/test/resources/testdata//. No real names, NI numbers, URNs, or court refs — use the existing fake data pattern. - Wire glue —
TestRunner.javadeclaresglue = "com.stepdefinitions". If you add a new package, update the runner. - Local run —
mvn clean verify -P. Serenity report lands intarget/site/serenity/index.html.
Common rejects to avoid
- New page object that duplicates locators from an existing one
- Hard-coded XPath in a step definition
Thread.sleep(...)instead of an explicit wait- Feature file in the wrong domain folder so it isn't picked up by the intended pipeline tag
- Real defendant / officer / court data in
testdata/
Step 3 — API: Authoring a *IT.java
Directory map
cpp-apitests/api-integration-test/src/test/
├── java/uk/gov/moj/
│ ├── AbstractTest.java # Root base
│ ├── ApplicationsAbstractTest.java
│ ├── AuditAbstractTest.java
│ ├── AuthorizationAbstractTest.java
│ └── test/ # *IT.java live here
└── resources// # JSON fixtures, payloads
Authoring checklist
- File naming is load-bearing — must end
IT.java. Failsafe only picks up that suffix;*Test.javawill not run in CI. - Extend the closest abstract base:
- General API →
AbstractTest - Audit assertions →
AuditAbstractTest - Authorization flows →
AuthorizationAbstractTest - Applications API →
ApplicationsAbstractTest
The base wires @ExtendWith(TestHook.class) and shared setup. Do not re-declare hooks.
- Reuse helpers and builders before creating new ones — grep for the domain you're testing:
JsonUtil,DbUtil,ApplicationUtil,RestAssuredFileUploadUtil- Domain helpers, e.g.
CpsUnifiedSearchHelper - Builders, e.g.
CpsCaseIngestionData.Builder
- REST Assured pattern — use
given().when().then()with Hamcrest matchers or AssertJ. Avoid rawassertEqualson JSON paths. - Fixtures live under
src/test/resources//. Load viaJsonUtil. No PII / court refs. - Contract alignment — when asserting a response shape, cross-check it against the producing service's RAML / OpenAPI. Apply
api-contract-checkif the response surface is changing. - Local run —
mvn clean verify(Failsafe phase). Single class:mvn verify -Dit.test=MyEndpointIT -pl api-integration-test.
Common rejects to avoid
- File named
*Test.java(Failsafe skips it) - Extending
AbstractTestwhen a more specific base exists - Inline JSON payload strings instead of resource fixtures +
JsonUtil - New helper class that duplicates an existing util
- Hard-coded bearer tokens or URLs — use the configured environment
Step 4 — Pre-Commit Checklist (both repos)
- [ ] No PII / case data / court reference numbers anywhere in the diff
- [ ] Existing page objects / step defs / helpers / builders were reused, not duplicated — apply
simplifyif unsure - [ ] (UI only) Journey passes a11y check — apply
accessibility-check - [ ] (API only) Assertions match the producing service's contract — apply
api-contract-check - [ ] ADR raised for any deviation from the patterns above — apply
adr-template - [ ] Test runs green locally
- [ ] Test runs green on the targeted pipeline profile
Step 5 — When CI Fails
Defer to pipeline-debug. Identify the failing YAML first:
- UI: one of the
azure-pipelines*.ymlvariants incpp-ui-e2e-serenity - API:
apitests-pipeline.yamlorazure-pipelines.yamlincpp-apitests
Step 6 — Raising the PR
When the test is ready:
- Run
review-pragainst the diff first — it has a section for these two repos - If it surfaces blocking issues, fix before raising
- Open the PR; reviewer runs
review-pragain as part of the merge gate
Related Skills
write-acceptance-criteria— derive ACs from the story (run first)generate-bdd-specs— author the Gherkin feature (UI only)accessibility-check— WCAG 2.1 AA on user-facing journeysapi-contract-check— RAML / OpenAPI alignment for*IT.javareview-pr— PR review checklist (includes a test-repo section)pipeline-debug— CI failure diagnosissimplify— reuse and dedupe pass before commitadr-template— record any deviation from the patterns abovesecurity-review— required if touching auth, session, tokens, or PII handling
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: hmcts
- Source: hmcts/claude
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.