@freshworks/shiftleft-tools 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +351 -0
  2. package/bin/shiftleft.js +95 -0
  3. package/package.json +57 -0
  4. package/src/commands/doctor.js +208 -0
  5. package/src/commands/init-postman.js +298 -0
  6. package/src/commands/init-rules.js +78 -0
  7. package/src/commands/link.js +172 -0
  8. package/src/commands/protect.js +61 -0
  9. package/src/commands/run-tests.js +182 -0
  10. package/src/commands/setup-pipeline.js +209 -0
  11. package/src/commands/update.js +203 -0
  12. package/src/index.js +4 -0
  13. package/src/utils/copy-tree.js +98 -0
  14. package/src/utils/gitignore.js +26 -0
  15. package/src/utils/logger.js +9 -0
  16. package/src/utils/manifest.js +145 -0
  17. package/src/utils/stack.js +80 -0
  18. package/src/utils/template.js +135 -0
  19. package/templates/AGENTS.md +109 -0
  20. package/templates/CLAUDE.md +3 -0
  21. package/templates/jenkins/Jenkinsfile-java.groovy +432 -0
  22. package/templates/jenkins/Jenkinsfile-node.groovy +450 -0
  23. package/templates/postman/.husky/pre-commit +19 -0
  24. package/templates/postman/.prettierrc.json +5 -0
  25. package/templates/postman/README.md.ejs +147 -0
  26. package/templates/postman/collections/01-core.json.ejs +91 -0
  27. package/templates/postman/config/local.json.ejs +12 -0
  28. package/templates/postman/config/staging.json.ejs +26 -0
  29. package/templates/postman/environments/local.postman_environment.json.ejs +31 -0
  30. package/templates/postman/environments/staging.postman_environment.json.ejs +31 -0
  31. package/templates/postman/gitignore +16 -0
  32. package/templates/postman/npmrc +31 -0
  33. package/templates/postman/package.json.ejs +66 -0
  34. package/templates/postman/run-all-shim.sh +16 -0
  35. package/templates/postman/scripts/auth/generate-jwt.sh +113 -0
  36. package/templates/postman/scripts/auth/get-issuer-secret.sh +140 -0
  37. package/templates/postman/scripts/infra/start-mocks.sh +138 -0
  38. package/templates/postman/scripts/infra/stop-mocks.sh +43 -0
  39. package/templates/postman/scripts/lib/api_coverage.py +1122 -0
  40. package/templates/postman/scripts/lib/cleanup-reports.sh +101 -0
  41. package/templates/postman/scripts/lib/cleanup-stryker.sh +44 -0
  42. package/templates/postman/scripts/lib/report_combined.py +527 -0
  43. package/templates/postman/scripts/lib/report_consolidated.py +363 -0
  44. package/templates/postman/scripts/lib/report_generator.py +121 -0
  45. package/templates/postman/scripts/lib/report_migration.py +156 -0
  46. package/templates/postman/scripts/lib/report_mutation.py +110 -0
  47. package/templates/postman/scripts/lib/report_unit.py +353 -0
  48. package/templates/postman/scripts/lib/report_utils.py +973 -0
  49. package/templates/postman/scripts/report-generators/generate-consolidated-report.sh +445 -0
  50. package/templates/postman/scripts/report-generators/java-api-coverage-matrix.sh +257 -0
  51. package/templates/postman/scripts/report-generators/mutation-report.sh +672 -0
  52. package/templates/postman/scripts/report-generators/node-api-coverage-matrix.sh +167 -0
  53. package/templates/postman/scripts/report-generators/stage-report-artifacts.sh +27 -0
  54. package/templates/postman/scripts/run-all.sh +452 -0
  55. package/templates/postman/scripts/runners/run-mutation-tests.sh +113 -0
  56. package/templates/postman/scripts/runners/run-tests-local.sh +936 -0
  57. package/templates/postman/scripts/runners/run-tests-staging.sh +741 -0
  58. package/templates/postman-node/README.md.ejs +26 -0
  59. package/templates/postman-node/collections/crud/01-bootstrap.json.ejs +34 -0
  60. package/templates/postman-node/config/local.json.ejs +46 -0
  61. package/templates/postman-node/config/staging.json.ejs +31 -0
  62. package/templates/postman-node/local.test.env.ejs +3 -0
  63. package/templates/postman-node/mocks/external.js +14 -0
  64. package/templates/postman-node/package.json.ejs +39 -0
  65. package/templates/postman-node/requirements.txt +1 -0
  66. package/templates/postman-node/scripts/database/cleanup-mysql.sh +12 -0
  67. package/templates/postman-node/scripts/database/run-migrations.js +29 -0
  68. package/templates/postman-node/scripts/database/start-mysql.sh +34 -0
  69. package/templates/postman-node/scripts/database/wait-for-mysql.sh +36 -0
  70. package/templates/postman-node/scripts/lib/api_coverage_node.py +1137 -0
  71. package/templates/postman-node/scripts/lib/fetch-jwt.sh +86 -0
  72. package/templates/postman-node/scripts/lib/run-newman.sh +104 -0
  73. package/templates/postman-node/scripts/lib/setup-database.sh +55 -0
  74. package/templates/postman-node/scripts/lib/start-app.sh +48 -0
  75. package/templates/postman-node/scripts/lib/utils.sh +114 -0
  76. package/templates/postman-node/scripts/report-generators/stage-report-artifacts.sh +26 -0
  77. package/templates/postman-node/scripts/run-all.sh +303 -0
  78. package/templates/postman-node/scripts/runners/run-tests.sh +123 -0
  79. package/templates/postman-node/scripts/setup-mocks.js.ejs +29 -0
  80. package/templates/postman-node/stryker.config.js.ejs +51 -0
  81. package/templates/rules/local-test-setup.mdc +420 -0
  82. package/templates/rules/testing-node.mdc +66 -0
  83. package/templates/rules/testing.mdc +248 -0
  84. package/templates/skills/_shared/postman-standards.md +380 -0
  85. package/templates/skills/enhance-test-pipeline/SKILL-java.md +483 -0
  86. package/templates/skills/enhance-test-pipeline/SKILL-node.md +431 -0
  87. package/templates/skills/enhance-test-pipeline/SKILL.md +9 -0
  88. package/templates/skills/review-test-suite/SKILL-java.md +137 -0
  89. package/templates/skills/review-test-suite/SKILL-node.md +78 -0
  90. package/templates/skills/review-test-suite/SKILL.md +9 -0
  91. package/templates/skills/run-test-suite/SKILL-java.md +186 -0
  92. package/templates/skills/run-test-suite/SKILL-node.md +191 -0
  93. package/templates/skills/run-test-suite/SKILL.md +9 -0
  94. package/templates/skills/setup-api-tests/SKILL-java.md +1094 -0
  95. package/templates/skills/setup-api-tests/SKILL-node.md +141 -0
  96. package/templates/skills/setup-api-tests/SKILL.md +9 -0
  97. package/templates/skills/setup-mutation-tests/SKILL-java.md +303 -0
  98. package/templates/skills/setup-mutation-tests/SKILL-node.md +408 -0
  99. package/templates/skills/setup-mutation-tests/SKILL.md +9 -0
  100. package/templates/skills/setup-test-pipeline/SKILL-java.md +454 -0
  101. package/templates/skills/setup-test-pipeline/SKILL-node.md +318 -0
  102. package/templates/skills/setup-test-pipeline/SKILL.md +9 -0
  103. package/templates/skills/write-api-tests/SKILL-java.md +115 -0
  104. package/templates/skills/write-api-tests/SKILL-node.md +83 -0
  105. package/templates/skills/write-api-tests/SKILL.md +9 -0
  106. package/templates/stryker.config.js +50 -0
@@ -0,0 +1,141 @@
1
+ # Setup API Tests Skill — Node.js / Express
2
+
3
+ Set up Postman/Newman integration test infrastructure for a Node.js/Express service.
4
+
5
+ Reference implementation: `freshapps_api_node`
6
+
7
+ ## When to Use
8
+
9
+ - "setup postman", "add newman", "setup integration tests"
10
+ - Project has `package.json` but no `postman/` directory (or incomplete setup)
11
+
12
+ If `postman/` is missing, run `shiftleft init-postman --stack node` first, then customize with this skill.
13
+
14
+ ---
15
+
16
+ ## Phase 1: Explore (REQUIRED)
17
+
18
+ Never assume conventions. Read actual source files first.
19
+
20
+ ```bash
21
+ # Route structure
22
+ ls src/controllers/ src/routes/ 2>/dev/null
23
+ head -50 src/controllers/index.js 2>/dev/null || head -50 src/routes/index.js
24
+
25
+ # App entry (for mock wiring)
26
+ ls src/index.js src/app.js 2>/dev/null
27
+
28
+ # Existing tests
29
+ cat package.json | grep -E '"test"|"unit-tests"|"start"'
30
+ ls test/ postman/ 2>/dev/null
31
+ ```
32
+
33
+ Record:
34
+ - **ROUTES_DIR** — usually `src/controllers` (Express router files)
35
+ - **APP_PORT** — from config or `local.env` (default 4013 in templates)
36
+ - **AUTH** — JWT middleware location (`src/middlewares/auth.js` or similar)
37
+ - **EXTERNAL_DEPS** — helpers that call HTTP (aws, freshid, chargebee, etc.) → need nock mocks
38
+
39
+ ---
40
+
41
+ ## Phase 2: Scaffold (if missing)
42
+
43
+ ```bash
44
+ shiftleft init-postman --stack node --name <service-name> --with-staging
45
+ cd postman && npm ci --ignore-scripts
46
+ ```
47
+
48
+ Verify structure:
49
+ ```
50
+ postman/
51
+ ├── config/local.json # setup.database, setup.app, auth.jwt.users
52
+ ├── collections/crud/ # numbered collections
53
+ ├── scripts/runners/run-tests.sh
54
+ ├── scripts/setup-mocks.js
55
+ ├── mocks/ # nock stubs per external service
56
+ └── local.test.env
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Phase 3: Configure local.json
62
+
63
+ Edit `postman/config/local.json`:
64
+
65
+ | Field | What to set |
66
+ |-------|-------------|
67
+ | `api_url` | `http://localhost:<port>` matching your app |
68
+ | `setup.app.port` | Same port |
69
+ | `setup.app.start_command` | `yarn start` or `node src/index.js` |
70
+ | `setup.database.enabled` | `true` if service needs MySQL locally (Podman) |
71
+ | `auth.jwt.users` | One entry per role your API tests need |
72
+
73
+ ---
74
+
75
+ ## Phase 4: Wire nock mocks
76
+
77
+ 1. List external HTTP dependencies:
78
+ ```bash
79
+ grep -r "https://" src/helpers/ src/clients/ 2>/dev/null | head -20
80
+ ```
81
+
82
+ 2. Create `postman/mocks/<service>.js` with nock stubs (see `mocks/external.js` template)
83
+
84
+ 3. Register in `postman/scripts/setup-mocks.js`
85
+
86
+ 4. Load mocks from app entry when `NODE_ENV=integration-tests`:
87
+ ```javascript
88
+ if (process.env.NODE_ENV === 'integration-tests') {
89
+ require('../postman/scripts/setup-mocks').setupMocks();
90
+ }
91
+ ```
92
+
93
+ **Do NOT use WireMock for Node** — use in-process nock (reference: `freshapps_api_node`).
94
+
95
+ ---
96
+
97
+ ## Phase 5: Collections
98
+
99
+ Follow lifecycle pattern from `freshapps_api_node`:
100
+
101
+ | Order | Collection | Purpose |
102
+ |-------|------------|---------|
103
+ | `01-*` | Bootstrap | Health check, set shared env vars |
104
+ | `02-NN` | Domain CRUD | One file per resource area |
105
+ | `99-*` | Cleanup | Remove test data |
106
+
107
+ Add collections to `postman/collections/crud/`. Newman runs all `*.json` in filename order via `run-newman.sh`.
108
+
109
+ ---
110
+
111
+ ## Phase 6: Root package.json scripts
112
+
113
+ Add to project root `package.json`:
114
+
115
+ ```json
116
+ "mutation-tests": "bash postman/scripts/runners/run-mutation-tests.sh",
117
+ "mutation-tests:full": "MUTATION_MODE=full bash postman/scripts/runners/run-mutation-tests.sh",
118
+ "test:all": "cd postman/scripts && ./run-all.sh"
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Phase 7: Verify
124
+
125
+ ```bash
126
+ cd postman/scripts && ./runners/run-tests.sh local
127
+ ./report-generators/node-api-coverage-matrix.sh ../../src/controllers ..
128
+ ./run-all.sh --skip-mutation
129
+ ```
130
+
131
+ Fix failures before declaring setup complete.
132
+
133
+ ---
134
+
135
+ ## Staging
136
+
137
+ 1. Update `postman/config/staging.json` with real `api_url` and AWS secret name
138
+ 2. Run: `./runners/run-tests.sh staging`
139
+ 3. JWT: `scripts/auth/generate-jwt.sh` + `get-issuer-secret.sh` (secrets unset before Newman)
140
+
141
+ See `../_shared/postman-standards.md` for assertion rules.
@@ -0,0 +1,9 @@
1
+ # Setup API Tests Skill
2
+
3
+ ## Detect Project Type First
4
+
5
+ Before doing anything, detect the stack:
6
+
7
+ 1. `pom.xml` in project root → **Java Spring Boot** → read `SKILL-java.md` in this folder and follow it completely
8
+ 2. `package.json` (no `pom.xml`) → **Node.js** → read `SKILL-node.md` in this folder and follow it completely
9
+ 3. If unsure → ask the user: "Is this a Java or Node.js project?"
@@ -0,0 +1,303 @@
1
+ # Setup Mutation Tests — Java Spring Boot
2
+
3
+ Add PIT mutation testing to a Java Spring Boot project using an inspect-first approach. Never copy-paste placeholders — always discover the actual package structure before writing any config.
4
+
5
+ ## When to Use
6
+
7
+ Invoke when the user says:
8
+ - "setup mutation tests", "add mutation testing", "add PIT", "setup pitest"
9
+ - "measure test quality", "check unit test quality"
10
+ - "my unit tests pass but I want to know if they're strong"
11
+
12
+ ---
13
+
14
+ ## What is Mutation Testing?
15
+
16
+ PIT makes small automated changes (mutations) to your source code — flipping `>` to `>=`, removing return values, negating conditions — then runs your JUnit unit tests against each mutation.
17
+
18
+ - **Mutant killed** — your tests caught the change (good)
19
+ - **Mutant survived** — your tests didn't catch it (weak assertion)
20
+
21
+ Target score: 60%+ mutation, 70%+ coverage. Mutation tests run on every Jenkins build but NOT on every `mvn install` (profile-gated).
22
+
23
+ ---
24
+
25
+ ## Phase 1: Inspect
26
+
27
+ ### 1.1 Check if PIT already exists
28
+
29
+ ```bash
30
+ grep -r "pitest-maven" pom.xml
31
+ ```
32
+
33
+ - Found → check the existing configuration, skip to Phase 4 (Verify)
34
+ - Not found → continue
35
+
36
+ ### 1.2 Discover the actual package structure
37
+
38
+ ```bash
39
+ find src/main/java -type d | sort
40
+ ```
41
+
42
+ Map what you find to these categories:
43
+
44
+ | Category | Typical folder names | Include in PIT? |
45
+ |---|---|---|
46
+ | Business logic | `service`, `services`, `usecase`, `domain` | YES |
47
+ | Data mapping | `mapper`, `mappers`, `converter`, `converters`, `transformer` | YES |
48
+ | Utilities | `util`, `utils`, `helper`, `helpers` | YES |
49
+ | Validation | `validator`, `validators`, `validation` | YES |
50
+ | Filters/interceptors | `filter`, `filters`, `interceptor` | YES |
51
+ | Controllers | `controller`, `controllers`, `api` | NO — integration, not unit |
52
+ | Config | `config`, `configuration` | NO — no branching logic |
53
+ | DTOs | `dto`, `model`, `request`, `response` | NO — data classes |
54
+ | Entities | `entity`, `entities`, `domain/entity` | NO — JPA data classes |
55
+ | Generated | any `MapperImpl` files | NO — MapStruct generated |
56
+ | Main class | `Application.java` | NO |
57
+
58
+ ### 1.3 Find the base package
59
+
60
+ ```bash
61
+ find src/main/java -name "*.java" | head -5 | xargs grep -l "^package" | head -1 | xargs grep "^package"
62
+ ```
63
+
64
+ Example result: `package com.freshworks.myservice.installation;` → base package is `com.freshworks.myservice.installation`
65
+
66
+ ### 1.4 Check for existing test failures
67
+
68
+ ```bash
69
+ mvn test -q 2>&1 | grep -E "FAILED|ERROR|Tests run" | tail -20
70
+ ```
71
+
72
+ Note any failing test classes — these must be excluded from PIT's test scan so PIT doesn't fail on pre-existing issues.
73
+
74
+ ### 1.5 Check if this is a multi-module Maven project
75
+
76
+ ```bash
77
+ ls */pom.xml 2>/dev/null | head -5
78
+ grep "<modules>" pom.xml
79
+ ```
80
+
81
+ Multi-module: the PIT plugin goes in the ROOT pom.xml, and you run `mvn -pl <module-name> org.pitest:pitest-maven:mutationCoverage -Pmutation-tests`.
82
+
83
+ ---
84
+
85
+ ## Phase 2: Reason
86
+
87
+ Based on what you found, determine:
88
+
89
+ **targetClasses** — list each business logic package explicitly:
90
+ - `BASE_PACKAGE.service.*` (if `service/` exists)
91
+ - `BASE_PACKAGE.mapper.*` (if `mapper/` exists)
92
+ - etc.
93
+
94
+ **targetTests** — mirror the source packages:
95
+ - `BASE_PACKAGE.service.*Test` for service tests
96
+ - `BASE_PACKAGE.mapper.*Test` for mapper tests
97
+ - etc.
98
+
99
+ **excludedClasses** — always exclude:
100
+ - `*DTO`, `*Dto`, `*Request`, `*Response` — data transfer objects
101
+ - `*Entity` — JPA entities
102
+ - `*Config`, `*Configuration` — Spring config
103
+ - `*Exception` — exception classes
104
+ - `*Application` — main class
105
+ - `*MapperImpl` — MapStruct generated implementations
106
+ - `*Constants` — constant-only classes
107
+
108
+ **excludedTestClasses** — any test classes that are currently failing (from 1.4)
109
+
110
+ **Profile approach** — NEVER put pitest in the main build. Wrap in `<profile id="mutation-tests">` with `<activeByDefault>false</activeByDefault>`. This means `mvn install` never runs mutation tests — only `mvn ... -Pmutation-tests`.
111
+
112
+ ---
113
+
114
+ ## Phase 3: Confirm
115
+
116
+ Show the user a summary before writing anything:
117
+
118
+ ```
119
+ I found the following packages in src/main/java/:
120
+ BASE_PACKAGE.service (3 classes)
121
+ BASE_PACKAGE.mapper (2 classes)
122
+ BASE_PACKAGE.util (4 classes)
123
+
124
+ I will configure PIT to:
125
+ Target classes: BASE_PACKAGE.service.*, BASE_PACKAGE.mapper.*, BASE_PACKAGE.util.*
126
+ Target tests: BASE_PACKAGE.service.*Test, BASE_PACKAGE.mapper.*Test, BASE_PACKAGE.util.*Test
127
+ Exclude: *DTO, *Entity, *Config, *MapperImpl, ...
128
+ Thresholds: mutation 60%, coverage 70%
129
+ Profile: mutation-tests (not run on mvn install)
130
+
131
+ Proceed? [Y/n]
132
+ ```
133
+
134
+ Wait for confirmation before writing to pom.xml.
135
+
136
+ ---
137
+
138
+ ## Phase 4: Execute
139
+
140
+ Add this profile to pom.xml (inside `<project>`, after `</build>`):
141
+
142
+ ```xml
143
+ <profiles>
144
+ <profile>
145
+ <id>mutation-tests</id>
146
+ <activation>
147
+ <activeByDefault>false</activeByDefault>
148
+ </activation>
149
+ <build>
150
+ <plugins>
151
+ <plugin>
152
+ <groupId>org.pitest</groupId>
153
+ <artifactId>pitest-maven</artifactId>
154
+ <version>1.15.3</version>
155
+ <dependencies>
156
+ <dependency>
157
+ <groupId>org.pitest</groupId>
158
+ <artifactId>pitest-junit5-plugin</artifactId>
159
+ <version>1.2.1</version>
160
+ </dependency>
161
+ </dependencies>
162
+ <configuration>
163
+ <targetClasses>
164
+ <!-- REPLACE with actual packages found in Phase 1 -->
165
+ <param>BASE_PACKAGE.service.*</param>
166
+ <param>BASE_PACKAGE.mapper.*</param>
167
+ <param>BASE_PACKAGE.util.*</param>
168
+ </targetClasses>
169
+ <targetTests>
170
+ <!-- REPLACE with actual test packages found in Phase 1 -->
171
+ <param>BASE_PACKAGE.service.*Test</param>
172
+ <param>BASE_PACKAGE.mapper.*Test</param>
173
+ <param>BASE_PACKAGE.util.*Test</param>
174
+ </targetTests>
175
+ <!-- Add any currently-failing test classes here to prevent PIT failure -->
176
+ <!-- <excludedTestClasses><param>BASE_PACKAGE.SomeFailingTest</param></excludedTestClasses> -->
177
+ <excludedClasses>
178
+ <param>*DTO</param>
179
+ <param>*Dto</param>
180
+ <param>*Entity</param>
181
+ <param>*Config</param>
182
+ <param>*Configuration</param>
183
+ <param>*Exception</param>
184
+ <param>*Application</param>
185
+ <param>*MapperImpl</param>
186
+ <param>*Constants</param>
187
+ <param>*Request</param>
188
+ <param>*Response</param>
189
+ </excludedClasses>
190
+ <excludedMethods>
191
+ <param>hashCode</param>
192
+ <param>equals</param>
193
+ <param>toString</param>
194
+ </excludedMethods>
195
+ <mutators>
196
+ <mutator>STRONGER</mutator>
197
+ </mutators>
198
+ <outputFormats>
199
+ <outputFormat>HTML</outputFormat>
200
+ <outputFormat>XML</outputFormat> <!-- XML required by quality report script -->
201
+ </outputFormats>
202
+ <timestampedReports>false</timestampedReports> <!-- Required for CI report linking -->
203
+ <threads>4</threads>
204
+ <timeoutConstant>8000</timeoutConstant>
205
+ <mutationThreshold>60</mutationThreshold>
206
+ <coverageThreshold>70</coverageThreshold>
207
+ </configuration>
208
+ </plugin>
209
+ </plugins>
210
+ </build>
211
+ </profile>
212
+ </profiles>
213
+ ```
214
+
215
+ **For multi-module projects**: add the profile to the ROOT `pom.xml`, not the module pom. Use `-pl <module-name>` when running.
216
+
217
+ Also ensure JaCoCo is present for coverage reporting. Add to the main `<build><plugins>` if missing:
218
+
219
+ ```xml
220
+ <plugin>
221
+ <groupId>org.jacoco</groupId>
222
+ <artifactId>jacoco-maven-plugin</artifactId>
223
+ <version>0.8.11</version>
224
+ <executions>
225
+ <execution>
226
+ <goals>
227
+ <goal>prepare-agent</goal>
228
+ </goals>
229
+ </execution>
230
+ <execution>
231
+ <id>report</id>
232
+ <phase>test</phase>
233
+ <goals>
234
+ <goal>report</goal>
235
+ </goals>
236
+ </execution>
237
+ </executions>
238
+ </plugin>
239
+ ```
240
+
241
+ Also ensure Surefire is configured to exclude integration tests:
242
+
243
+ ```xml
244
+ <plugin>
245
+ <groupId>org.apache.maven.plugins</groupId>
246
+ <artifactId>maven-surefire-plugin</artifactId>
247
+ <configuration>
248
+ <excludes>
249
+ <exclude>**/*IT.java</exclude>
250
+ <exclude>**/*IntegrationTest.java</exclude>
251
+ </excludes>
252
+ </configuration>
253
+ </plugin>
254
+ ```
255
+
256
+ ---
257
+
258
+ ## Phase 5: Verify
259
+
260
+ Run mutation tests to confirm the setup works:
261
+
262
+ ```bash
263
+ # Single-module project:
264
+ mvn test-compile org.pitest:pitest-maven:mutationCoverage -Pmutation-tests
265
+
266
+ # Multi-module project (replace 'installation' with your module name):
267
+ mvn -pl installation org.pitest:pitest-maven:mutationCoverage -Pmutation-tests
268
+ ```
269
+
270
+ Or use the script if postman/scripts/ already exists:
271
+
272
+ ```bash
273
+ ./postman/scripts/report-generators/mutation-report.sh
274
+ ```
275
+
276
+ Report is generated at `target/pit-reports/index.html`.
277
+
278
+ ### Report results to the user
279
+
280
+ After the run completes:
281
+ 1. Report the mutation score — e.g. "72% of mutants killed (target: 60%+)"
282
+ 2. Identify surviving mutants — list which classes have weak coverage
283
+ 3. Suggest fixes for the top surviving mutants:
284
+
285
+ | Surviving Mutant Type | Likely Cause | Fix |
286
+ |---|---|---|
287
+ | Negated condition | Assertion doesn't test boundary | Add test for the false branch |
288
+ | Removed method call | `verify()` missing or no assertion on side effect | Add `ArgumentCaptor` or assert on saved entity |
289
+ | Changed return value | Return value not asserted | Assert on the actual return value |
290
+ | Removed null check | No test for null input | Add test with null argument |
291
+
292
+ ---
293
+
294
+ ## Verification Checklist
295
+
296
+ - [ ] PIT plugin added inside a `<profile id="mutation-tests">` (NOT in main build)
297
+ - [ ] `targetClasses` matches actual project packages (not placeholder)
298
+ - [ ] `targetTests` matches actual test class names
299
+ - [ ] `<timestampedReports>false</timestampedReports>` is set (required for CI)
300
+ - [ ] XML output format is enabled (required for quality report)
301
+ - [ ] Mutation run completes without errors
302
+ - [ ] Score reported to user
303
+ - [ ] Surviving mutants identified and fixes suggested