@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.
- package/README.md +351 -0
- package/bin/shiftleft.js +95 -0
- package/package.json +57 -0
- package/src/commands/doctor.js +208 -0
- package/src/commands/init-postman.js +298 -0
- package/src/commands/init-rules.js +78 -0
- package/src/commands/link.js +172 -0
- package/src/commands/protect.js +61 -0
- package/src/commands/run-tests.js +182 -0
- package/src/commands/setup-pipeline.js +209 -0
- package/src/commands/update.js +203 -0
- package/src/index.js +4 -0
- package/src/utils/copy-tree.js +98 -0
- package/src/utils/gitignore.js +26 -0
- package/src/utils/logger.js +9 -0
- package/src/utils/manifest.js +145 -0
- package/src/utils/stack.js +80 -0
- package/src/utils/template.js +135 -0
- package/templates/AGENTS.md +109 -0
- package/templates/CLAUDE.md +3 -0
- package/templates/jenkins/Jenkinsfile-java.groovy +432 -0
- package/templates/jenkins/Jenkinsfile-node.groovy +450 -0
- package/templates/postman/.husky/pre-commit +19 -0
- package/templates/postman/.prettierrc.json +5 -0
- package/templates/postman/README.md.ejs +147 -0
- package/templates/postman/collections/01-core.json.ejs +91 -0
- package/templates/postman/config/local.json.ejs +12 -0
- package/templates/postman/config/staging.json.ejs +26 -0
- package/templates/postman/environments/local.postman_environment.json.ejs +31 -0
- package/templates/postman/environments/staging.postman_environment.json.ejs +31 -0
- package/templates/postman/gitignore +16 -0
- package/templates/postman/npmrc +31 -0
- package/templates/postman/package.json.ejs +66 -0
- package/templates/postman/run-all-shim.sh +16 -0
- package/templates/postman/scripts/auth/generate-jwt.sh +113 -0
- package/templates/postman/scripts/auth/get-issuer-secret.sh +140 -0
- package/templates/postman/scripts/infra/start-mocks.sh +138 -0
- package/templates/postman/scripts/infra/stop-mocks.sh +43 -0
- package/templates/postman/scripts/lib/api_coverage.py +1122 -0
- package/templates/postman/scripts/lib/cleanup-reports.sh +101 -0
- package/templates/postman/scripts/lib/cleanup-stryker.sh +44 -0
- package/templates/postman/scripts/lib/report_combined.py +527 -0
- package/templates/postman/scripts/lib/report_consolidated.py +363 -0
- package/templates/postman/scripts/lib/report_generator.py +121 -0
- package/templates/postman/scripts/lib/report_migration.py +156 -0
- package/templates/postman/scripts/lib/report_mutation.py +110 -0
- package/templates/postman/scripts/lib/report_unit.py +353 -0
- package/templates/postman/scripts/lib/report_utils.py +973 -0
- package/templates/postman/scripts/report-generators/generate-consolidated-report.sh +445 -0
- package/templates/postman/scripts/report-generators/java-api-coverage-matrix.sh +257 -0
- package/templates/postman/scripts/report-generators/mutation-report.sh +672 -0
- package/templates/postman/scripts/report-generators/node-api-coverage-matrix.sh +167 -0
- package/templates/postman/scripts/report-generators/stage-report-artifacts.sh +27 -0
- package/templates/postman/scripts/run-all.sh +452 -0
- package/templates/postman/scripts/runners/run-mutation-tests.sh +113 -0
- package/templates/postman/scripts/runners/run-tests-local.sh +936 -0
- package/templates/postman/scripts/runners/run-tests-staging.sh +741 -0
- package/templates/postman-node/README.md.ejs +26 -0
- package/templates/postman-node/collections/crud/01-bootstrap.json.ejs +34 -0
- package/templates/postman-node/config/local.json.ejs +46 -0
- package/templates/postman-node/config/staging.json.ejs +31 -0
- package/templates/postman-node/local.test.env.ejs +3 -0
- package/templates/postman-node/mocks/external.js +14 -0
- package/templates/postman-node/package.json.ejs +39 -0
- package/templates/postman-node/requirements.txt +1 -0
- package/templates/postman-node/scripts/database/cleanup-mysql.sh +12 -0
- package/templates/postman-node/scripts/database/run-migrations.js +29 -0
- package/templates/postman-node/scripts/database/start-mysql.sh +34 -0
- package/templates/postman-node/scripts/database/wait-for-mysql.sh +36 -0
- package/templates/postman-node/scripts/lib/api_coverage_node.py +1137 -0
- package/templates/postman-node/scripts/lib/fetch-jwt.sh +86 -0
- package/templates/postman-node/scripts/lib/run-newman.sh +104 -0
- package/templates/postman-node/scripts/lib/setup-database.sh +55 -0
- package/templates/postman-node/scripts/lib/start-app.sh +48 -0
- package/templates/postman-node/scripts/lib/utils.sh +114 -0
- package/templates/postman-node/scripts/report-generators/stage-report-artifacts.sh +26 -0
- package/templates/postman-node/scripts/run-all.sh +303 -0
- package/templates/postman-node/scripts/runners/run-tests.sh +123 -0
- package/templates/postman-node/scripts/setup-mocks.js.ejs +29 -0
- package/templates/postman-node/stryker.config.js.ejs +51 -0
- package/templates/rules/local-test-setup.mdc +420 -0
- package/templates/rules/testing-node.mdc +66 -0
- package/templates/rules/testing.mdc +248 -0
- package/templates/skills/_shared/postman-standards.md +380 -0
- package/templates/skills/enhance-test-pipeline/SKILL-java.md +483 -0
- package/templates/skills/enhance-test-pipeline/SKILL-node.md +431 -0
- package/templates/skills/enhance-test-pipeline/SKILL.md +9 -0
- package/templates/skills/review-test-suite/SKILL-java.md +137 -0
- package/templates/skills/review-test-suite/SKILL-node.md +78 -0
- package/templates/skills/review-test-suite/SKILL.md +9 -0
- package/templates/skills/run-test-suite/SKILL-java.md +186 -0
- package/templates/skills/run-test-suite/SKILL-node.md +191 -0
- package/templates/skills/run-test-suite/SKILL.md +9 -0
- package/templates/skills/setup-api-tests/SKILL-java.md +1094 -0
- package/templates/skills/setup-api-tests/SKILL-node.md +141 -0
- package/templates/skills/setup-api-tests/SKILL.md +9 -0
- package/templates/skills/setup-mutation-tests/SKILL-java.md +303 -0
- package/templates/skills/setup-mutation-tests/SKILL-node.md +408 -0
- package/templates/skills/setup-mutation-tests/SKILL.md +9 -0
- package/templates/skills/setup-test-pipeline/SKILL-java.md +454 -0
- package/templates/skills/setup-test-pipeline/SKILL-node.md +318 -0
- package/templates/skills/setup-test-pipeline/SKILL.md +9 -0
- package/templates/skills/write-api-tests/SKILL-java.md +115 -0
- package/templates/skills/write-api-tests/SKILL-node.md +83 -0
- package/templates/skills/write-api-tests/SKILL.md +9 -0
- package/templates/stryker.config.js +50 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
# Setup Test Pipeline — Java Spring Boot
|
|
2
|
+
|
|
3
|
+
Set up a complete test pipeline from scratch (or near-scratch) for a Java/Spring Boot repo. This skill orchestrates the full pipeline: unit tests, JaCoCo coverage, PIT mutation tests, Postman API tests, API coverage matrix, combined quality report, and Jenkins integration.
|
|
4
|
+
|
|
5
|
+
Use this skill when a repo has NOTHING (or only bare unit tests). For repos that already have partial pipeline setup, use `/enhance-test-pipeline` instead.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
Invoke when:
|
|
10
|
+
- "set up the full test pipeline"
|
|
11
|
+
- "add complete test infrastructure to this Java repo"
|
|
12
|
+
- "set up unit tests, mutation tests, and postman tests"
|
|
13
|
+
- "I want everything: unit tests, coverage, mutation, API tests, quality report"
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Reference Implementations
|
|
18
|
+
|
|
19
|
+
Before writing any code, check these canonical repos. They are the ground truth — use them instead of guessing.
|
|
20
|
+
|
|
21
|
+
**Java canonical repos:**
|
|
22
|
+
- `mp-installation` — PIT mutation, JaCoCo, multi-product Postman, API coverage matrix, quality report, Jenkins ShiftLeft
|
|
23
|
+
- `dp-apps` — same stack, original reference
|
|
24
|
+
|
|
25
|
+
**Script source (the `shiftleft-tools` package — pulled at runtime):**
|
|
26
|
+
```bash
|
|
27
|
+
# Stage the latest library scripts from the installed package into postman/scripts/.
|
|
28
|
+
# These are gitignored and refreshed on every run — never copy or commit them by hand.
|
|
29
|
+
shiftleft stage-scripts
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Do not copy scripts from a templates directory or write them from scratch. The
|
|
33
|
+
library scripts (`runners/`, `report-generators/`, `lib/`, `auth/`, `infra/`,
|
|
34
|
+
`database/`) live only in the `shiftleft-tools` package; `shiftleft stage-scripts`
|
|
35
|
+
(and `shiftleft test`, which stages then runs) pulls the current versions in.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Phase 1: Inspect — Audit What Exists
|
|
40
|
+
|
|
41
|
+
Run each check and record the result (present/missing/partial).
|
|
42
|
+
|
|
43
|
+
### 1.1 Unit tests
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
ls src/test/java/
|
|
47
|
+
mvn test -q 2>&1 | tail -5
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
- Present and passing: unit tests exist and pass
|
|
51
|
+
- Present but failing: unit tests exist but have failures (must fix before mutation tests)
|
|
52
|
+
- Missing: no test directory or no test files
|
|
53
|
+
|
|
54
|
+
### 1.2 JaCoCo coverage
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
grep -r "jacoco" pom.xml
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- Present: JaCoCo already configured
|
|
61
|
+
- Missing: needs to be added
|
|
62
|
+
|
|
63
|
+
### 1.3 Postman infrastructure
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
ls postman/ 2>/dev/null
|
|
67
|
+
ls postman/collections/ 2>/dev/null
|
|
68
|
+
ls postman/scripts/ 2>/dev/null
|
|
69
|
+
ls postman/scripts/run-all.sh 2>/dev/null
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- Present: full postman/ directory with collections and scripts
|
|
73
|
+
- Partial: directory exists but scripts or collections missing
|
|
74
|
+
- Missing: no postman/ directory
|
|
75
|
+
|
|
76
|
+
### 1.4 PIT mutation testing
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
grep -r "pitest-maven" pom.xml
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- Present: PIT configured (check if it's in a profile — it should be)
|
|
83
|
+
- Missing: needs to be added
|
|
84
|
+
|
|
85
|
+
### 1.5 API coverage matrix
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
ls postman/scripts/report-generators/java-api-coverage-matrix.sh 2>/dev/null
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 1.6 Quality report
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
ls postman/scripts/run-all.sh 2>/dev/null
|
|
95
|
+
grep "skip-report\|skip-unit\|skip-mutation" postman/scripts/run-all.sh 2>/dev/null | head -5
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
- Present and modern: run-all.sh exists and has --skip-* flags
|
|
99
|
+
- Present but stale: run-all.sh exists but is an old version without flags
|
|
100
|
+
- Missing
|
|
101
|
+
|
|
102
|
+
### 1.7 Jenkinsfile
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
ls Jenkinsfile
|
|
106
|
+
grep -E "Mutation|ShiftLeft|Quality|quality-report" Jenkinsfile 2>/dev/null
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
- Complete: has Unit Tests, Mutation Tests, ShiftLeft stages with quality report generation
|
|
110
|
+
- Partial: has some stages but missing mutation or quality report
|
|
111
|
+
- Missing: no Jenkinsfile
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Phase 2: Report Gaps
|
|
116
|
+
|
|
117
|
+
Present a clear status table to the user:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
Pipeline Audit Results
|
|
121
|
+
======================
|
|
122
|
+
Component Status
|
|
123
|
+
-----------------------------------------------
|
|
124
|
+
Unit Tests [PRESENT / MISSING / FAILING]
|
|
125
|
+
JaCoCo Coverage [PRESENT / MISSING]
|
|
126
|
+
Postman Infrastructure [PRESENT / PARTIAL / MISSING]
|
|
127
|
+
PIT Mutation Tests [PRESENT / MISSING]
|
|
128
|
+
API Coverage Matrix [PRESENT / MISSING]
|
|
129
|
+
run-all.sh (modern) [PRESENT / STALE / MISSING]
|
|
130
|
+
Jenkinsfile [COMPLETE / PARTIAL / MISSING]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Phase 3: Confirm
|
|
136
|
+
|
|
137
|
+
Tell the user exactly what will be set up:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
I will set up the following components in order:
|
|
141
|
+
1. [if missing] Postman infrastructure (collections, scripts, config)
|
|
142
|
+
2. [if missing] JaCoCo coverage plugin in pom.xml
|
|
143
|
+
3. [if missing] PIT mutation testing (profile-gated, discover packages first)
|
|
144
|
+
4. Stage library scripts from the shiftleft-tools package (`shiftleft stage-scripts`):
|
|
145
|
+
postman/scripts/run-all.sh
|
|
146
|
+
postman/scripts/report-generators/mutation-report.sh
|
|
147
|
+
postman/scripts/report-generators/java-api-coverage-matrix.sh
|
|
148
|
+
postman/scripts/report-generators/generate-consolidated-report.sh
|
|
149
|
+
postman/scripts/report-generators/stage-report-artifacts.sh
|
|
150
|
+
postman/scripts/lib/report_generator.py
|
|
151
|
+
postman/scripts/lib/report_utils.py
|
|
152
|
+
postman/scripts/lib/report_consolidated.py
|
|
153
|
+
postman/scripts/lib/report_migration.py
|
|
154
|
+
postman/scripts/lib/report_mutation.py
|
|
155
|
+
postman/scripts/lib/report_unit.py
|
|
156
|
+
postman/scripts/lib/report_combined.py
|
|
157
|
+
postman/scripts/lib/api_coverage.py
|
|
158
|
+
5. [if partial] Update Jenkinsfile with mutation + ShiftLeft + quality report stages
|
|
159
|
+
|
|
160
|
+
This will take approximately 5-10 minutes.
|
|
161
|
+
Proceed? [Y/n]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Wait for confirmation before making any changes.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Phase 4: Execute in Order
|
|
169
|
+
|
|
170
|
+
### Step A: Postman infrastructure (if missing)
|
|
171
|
+
|
|
172
|
+
If no `postman/` directory exists, invoke `/setup-api-tests` skill for the full Postman setup. This skill handles:
|
|
173
|
+
- Directory structure (postman/collections/, scripts/, environments/, config/)
|
|
174
|
+
- Initial test collection scaffolding
|
|
175
|
+
- Local environment configuration
|
|
176
|
+
- WireMock mock setup (if needed)
|
|
177
|
+
|
|
178
|
+
### Step B: JaCoCo coverage (if missing)
|
|
179
|
+
|
|
180
|
+
Add to the main `<build><plugins>` section of pom.xml:
|
|
181
|
+
|
|
182
|
+
```xml
|
|
183
|
+
<plugin>
|
|
184
|
+
<groupId>org.jacoco</groupId>
|
|
185
|
+
<artifactId>jacoco-maven-plugin</artifactId>
|
|
186
|
+
<version>0.8.11</version>
|
|
187
|
+
<executions>
|
|
188
|
+
<execution>
|
|
189
|
+
<goals>
|
|
190
|
+
<goal>prepare-agent</goal>
|
|
191
|
+
</goals>
|
|
192
|
+
</execution>
|
|
193
|
+
<execution>
|
|
194
|
+
<id>report</id>
|
|
195
|
+
<phase>test</phase>
|
|
196
|
+
<goals>
|
|
197
|
+
<goal>report</goal>
|
|
198
|
+
</goals>
|
|
199
|
+
</execution>
|
|
200
|
+
</executions>
|
|
201
|
+
</plugin>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Verify: `mvn test jacoco:report -q` and confirm `target/site/jacoco/index.html` exists.
|
|
205
|
+
|
|
206
|
+
### Step C: PIT mutation testing (if missing)
|
|
207
|
+
|
|
208
|
+
Follow the `setup-mutation-tests` SKILL-java.md skill in full:
|
|
209
|
+
1. Inspect source packages (never use placeholders)
|
|
210
|
+
2. Confirm targetClasses with user
|
|
211
|
+
3. Add `<profile id="mutation-tests">` to pom.xml
|
|
212
|
+
|
|
213
|
+
Key requirements:
|
|
214
|
+
- PIT version 1.15.3 with pitest-junit5-plugin 1.2.1
|
|
215
|
+
- STRONGER mutators
|
|
216
|
+
- `<timestampedReports>false</timestampedReports>` — required for CI
|
|
217
|
+
- XML + HTML output — XML required for quality report script
|
|
218
|
+
- Mutation threshold: 60%, coverage threshold: 70%
|
|
219
|
+
|
|
220
|
+
### Step D: Stage scripts from the shiftleft-tools package
|
|
221
|
+
|
|
222
|
+
**Do not copy or write these by hand.** Run `shiftleft stage-scripts` to pull the
|
|
223
|
+
current library scripts from the installed package into `postman/scripts/` (they
|
|
224
|
+
are gitignored and refreshed on every `shiftleft test` run). If the project has a
|
|
225
|
+
Maven submodule (e.g., `installation/`), adjust the `target/` paths in
|
|
226
|
+
`stage-report-artifacts.sh` to point to `<module>/target/` instead of `target/`.
|
|
227
|
+
|
|
228
|
+
After staging, `postman/scripts/` contains (only `run-all.sh` is committed — a
|
|
229
|
+
thin shim; everything else is the gitignored, staged cache):
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
postman/scripts/
|
|
233
|
+
├── run-all.sh # master pipeline runner
|
|
234
|
+
├── mutation-report.sh # runs PIT, generates HTML
|
|
235
|
+
├── java-api-coverage-matrix.sh # endpoint coverage matrix
|
|
236
|
+
├── generate-consolidated-report.sh # aggregates Newman JSON
|
|
237
|
+
├── stage-report-artifacts.sh # copies JaCoCo/PIT HTML for Jenkins
|
|
238
|
+
├── generate-quality-report.sh # standalone Jenkins quality report
|
|
239
|
+
├── runners/
|
|
240
|
+
│ ├── run-tests-local.sh # Postman against local + WireMock
|
|
241
|
+
│ └── run-tests-staging.sh # Postman against staging (ShiftLeft)
|
|
242
|
+
└── lib/
|
|
243
|
+
├── report_generator.py # CLI entry point
|
|
244
|
+
├── report_utils.py # shared CSS, helpers
|
|
245
|
+
├── report_consolidated.py # consolidated Newman results
|
|
246
|
+
├── report_migration.py # migration comparison
|
|
247
|
+
├── report_mutation.py # PIT mutation report
|
|
248
|
+
├── report_unit.py # Surefire + JaCoCo parsers
|
|
249
|
+
├── report_combined.py # combined quality report (tabs)
|
|
250
|
+
└── api_coverage.py # API coverage matrix generator
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Make all `.sh` files executable:
|
|
254
|
+
```bash
|
|
255
|
+
chmod +x postman/scripts/*.sh postman/scripts/runners/*.sh
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Data flow between scripts:**
|
|
259
|
+
```
|
|
260
|
+
mvn test → target/surefire-reports/*.xml → report_unit.py
|
|
261
|
+
mvn jacoco:report → target/site/jacoco/jacoco.xml → report_unit.py
|
|
262
|
+
mvn pitest → target/pit-reports/mutations.xml → report_mutation.py, report_unit.py
|
|
263
|
+
Newman run → postman/reports/newman/*.json → report_consolidated.py
|
|
264
|
+
coverage matrix → postman/reports/api-coverage.json → api_coverage.py
|
|
265
|
+
stage-artifacts → postman/reports/jacoco/, pit/ → quality report HTML links
|
|
266
|
+
|
|
267
|
+
report_generator.py (CLI entry) dispatches to:
|
|
268
|
+
├─ report_unit.py → postman/reports/unit-test-report-*.html
|
|
269
|
+
├─ report_consolidated.py → postman/reports/consolidated-report-*.html
|
|
270
|
+
├─ report_mutation.py → postman/reports/mutation-report-*.html
|
|
271
|
+
└─ report_combined.py → postman/reports/quality-report-*.html (THE main report)
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**Quality report HTML structure** — `report_combined.py` generates a single-page HTML with:
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
278
|
+
│ [Health Badge: 🟢 Healthy | 🟡 Good | 🔴 Needs Attention] │
|
|
279
|
+
│ Health: all green = Healthy, any warning = Good, any red = Needs Attention │
|
|
280
|
+
├─────────────┬─────────────┬─────────────┬──────────┬─────────┤
|
|
281
|
+
│ Unit Tests │ Line Cov │ Mutation │ API │ API Cov │
|
|
282
|
+
│ N/M passed │ XX.X% │ Score XX.X% │ N passed │ XX.X% │
|
|
283
|
+
│ [green/red] │ [green/warn │ [green/warn │ [grn/red]│[grn/wrn]│
|
|
284
|
+
│ │ /red] │ /red] │ │ /red] │
|
|
285
|
+
└─────────────┴─────────────┴─────────────┴──────────┴─────────┘
|
|
286
|
+
|
|
287
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
288
|
+
│ [Unit Tests tab] | [API Tests tab] ← CSS tab switcher │
|
|
289
|
+
├─────────────────────────────────────────────────────────────┤
|
|
290
|
+
│ Unit Tests tab contains sub-tabs: │
|
|
291
|
+
│ [Test Results] [Coverage] [Mutations] [Survived Mutations]│
|
|
292
|
+
│ │
|
|
293
|
+
│ API Tests tab contains sub-tabs: │
|
|
294
|
+
│ [Summary] [by Collection] [API Coverage Matrix] │
|
|
295
|
+
└─────────────────────────────────────────────────────────────┘
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Card thresholds:
|
|
299
|
+
- Unit Tests: green if 0 failures, red if any failures
|
|
300
|
+
- Line Coverage: green ≥80%, yellow ≥60%, red <60%
|
|
301
|
+
- Mutation Score: green ≥80%, yellow ≥60%, red <60%
|
|
302
|
+
- API Tests: green if 0 failed, red if any failed
|
|
303
|
+
- API Coverage: green ≥80%, yellow ≥60%, red <60%
|
|
304
|
+
|
|
305
|
+
**Survived Mutations tab** — shows up to 15 survived mutations:
|
|
306
|
+
- Class name, method, line number, mutation description
|
|
307
|
+
- Empty state: "No survived mutations. All mutations were killed by tests."
|
|
308
|
+
|
|
309
|
+
### Step E: Update Jenkinsfile (if missing stages)
|
|
310
|
+
|
|
311
|
+
If the Jenkinsfile exists but is missing mutation or quality report stages, update it to match the `templates/jenkins/Jenkinsfile-java.groovy` pattern:
|
|
312
|
+
|
|
313
|
+
Required stages:
|
|
314
|
+
1. `Unit tests` — `mvn clean install`
|
|
315
|
+
2. `Mutation Tests` — calls `runMutationTests()` which runs `./run-all.sh --skip-unit --skip-postman --skip-coverage --skip-report --no-delay`
|
|
316
|
+
3. `Shift Left Integration Test - Isolation` — runs Postman against staging, generates API coverage matrix, generates quality report
|
|
317
|
+
|
|
318
|
+
Key quality report pattern in Jenkins:
|
|
319
|
+
```groovy
|
|
320
|
+
// In ShiftLeft stage, after Postman tests:
|
|
321
|
+
sh "./run-all.sh --skip-unit --skip-mutation --skip-postman --skip-coverage --no-delay"
|
|
322
|
+
publishHTML([
|
|
323
|
+
reportDir: 'postman/reports',
|
|
324
|
+
reportFiles: 'quality-report-*.html',
|
|
325
|
+
includes: '**/*', // REQUIRED — without this, CSS/subdirs won't load
|
|
326
|
+
reportName: 'QualityReport'
|
|
327
|
+
])
|
|
328
|
+
archiveArtifacts artifacts: 'postman/reports/**', allowEmptyArchive: true
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Replace placeholders in the template:
|
|
332
|
+
- `SERVICE_NAME` → your actual service name (e.g. `mp-installation`)
|
|
333
|
+
- `NAMESPACE` → your Kubernetes namespace
|
|
334
|
+
- `ISO_HEADER` → isoforge routing header for this service
|
|
335
|
+
- `ISO_HEADER_VALUE` → the header value (regex or account ID)
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## PIT XML Format Spec
|
|
340
|
+
|
|
341
|
+
When writing or debugging `report_mutation.py` or `report_unit.py`, the PIT XML format is:
|
|
342
|
+
|
|
343
|
+
```xml
|
|
344
|
+
<mutations>
|
|
345
|
+
<mutation detected="true" status="KILLED" numberOfTestsRun="3">
|
|
346
|
+
<sourceFile>MyClass.java</sourceFile>
|
|
347
|
+
<mutatedClass>com.example.service.MyClass</mutatedClass>
|
|
348
|
+
<mutatedMethod>myMethod</mutatedMethod>
|
|
349
|
+
<methodDescription>(Ljava/lang/String;)Z</methodDescription>
|
|
350
|
+
<lineNumber>42</lineNumber>
|
|
351
|
+
<mutator>org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator</mutator>
|
|
352
|
+
<indexes><index>5</index></indexes>
|
|
353
|
+
<blocks><block>2</block></blocks>
|
|
354
|
+
<killingTest>com.example.service.MyClassTest.[engine:junit-jupiter]/...</killingTest>
|
|
355
|
+
<description>negated conditional</description>
|
|
356
|
+
</mutation>
|
|
357
|
+
</mutations>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**Status attribute values** (read from `mutation.get('status')`, NOT from `detected` attribute):
|
|
361
|
+
- `KILLED` — test caught the mutation (good)
|
|
362
|
+
- `SURVIVED` — no test caught it (bad — report these in Survived Mutations tab)
|
|
363
|
+
- `NO_COVERAGE` — no test covers this line at all
|
|
364
|
+
- `TIMED_OUT` — mutation caused an infinite loop (treated as killed)
|
|
365
|
+
- `RUN_ERROR` — mutation caused a runtime error (treated as killed)
|
|
366
|
+
|
|
367
|
+
**Common bug:** Do NOT use `mutation.get('detected')` — use `mutation.get('status')`. The `detected` attribute (`"true"/"false"`) loses the distinction between NO_COVERAGE and SURVIVED.
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Error Handling Rules
|
|
372
|
+
|
|
373
|
+
When any input file is missing, degrade gracefully — never crash the report:
|
|
374
|
+
|
|
375
|
+
| Missing file | Behavior |
|
|
376
|
+
|---|---|
|
|
377
|
+
| `surefire-reports/*.xml` | Show "No unit test data" card, continue |
|
|
378
|
+
| `jacoco.xml` | Show "Coverage data unavailable", skip coverage card |
|
|
379
|
+
| `mutations.xml` | Show "Mutation data unavailable", skip mutation card |
|
|
380
|
+
| `newman/*.json` | Show "No API test results", skip API tabs |
|
|
381
|
+
| `api-coverage.json` | Show "API coverage data unavailable", skip coverage card |
|
|
382
|
+
|
|
383
|
+
Pattern used in `report_unit.py`:
|
|
384
|
+
```python
|
|
385
|
+
try:
|
|
386
|
+
tree = ET.parse(mutations_xml)
|
|
387
|
+
# ... parse
|
|
388
|
+
except Exception as e:
|
|
389
|
+
print(f"Warning: Could not parse mutations.xml: {e}")
|
|
390
|
+
# return empty/default results dict, not None
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Always return a results dict with zero values rather than `None` — callers check keys, not None.
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## Phase 5: Verify
|
|
398
|
+
|
|
399
|
+
Run a two-phase verification:
|
|
400
|
+
|
|
401
|
+
### Verify Phase A: Unit + Mutation + Coverage (no Postman needed)
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
cd postman/scripts
|
|
405
|
+
./run-all.sh --skip-postman --no-delay
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Expected: unit tests pass, PIT mutation tests run, quality report generates.
|
|
409
|
+
|
|
410
|
+
### Verify Phase B: Postman + API Coverage + Quality Report (skip mutation)
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
cd postman/scripts
|
|
414
|
+
./run-all.sh --skip-mutation --no-delay
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
Expected: Postman tests run against local environment, API coverage matrix generates, quality report generates.
|
|
418
|
+
|
|
419
|
+
### Report to user
|
|
420
|
+
|
|
421
|
+
```
|
|
422
|
+
Pipeline setup complete!
|
|
423
|
+
|
|
424
|
+
Verification results:
|
|
425
|
+
Unit Tests: [PASS/FAIL] — N tests, M% line coverage
|
|
426
|
+
Mutation Tests: [PASS/FAIL] — X% mutation score
|
|
427
|
+
Postman Tests: [PASS/FAIL] — N collections, M assertions
|
|
428
|
+
API Coverage: [PASS/FAIL] — X% endpoints covered
|
|
429
|
+
Quality Report: [GENERATED] — postman/reports/quality-report-*.html
|
|
430
|
+
|
|
431
|
+
Next steps:
|
|
432
|
+
- Local run-all: cd postman/scripts && ./run-all.sh
|
|
433
|
+
- Staging run: cd postman/scripts && ./run-all.sh --env staging
|
|
434
|
+
- Jenkins: push a PR and comment "shiftleft" to trigger integration tests
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## Verification Checklist
|
|
440
|
+
|
|
441
|
+
- [ ] `mvn test` passes
|
|
442
|
+
- [ ] `mvn test jacoco:report` generates `target/site/jacoco/index.html` (or `<module>/target/site/jacoco/index.html` if submodule)
|
|
443
|
+
- [ ] `mvn org.pitest:pitest-maven:mutationCoverage -Pmutation-tests` runs without error
|
|
444
|
+
- [ ] `target/pit-reports/mutations.xml` exists with `<mutation>` elements that have a `status` attribute
|
|
445
|
+
- [ ] `./run-all.sh --skip-postman --no-delay` completes successfully
|
|
446
|
+
- [ ] `./run-all.sh --skip-mutation --no-delay` completes successfully
|
|
447
|
+
- [ ] `postman/reports/quality-report-*.html` is generated
|
|
448
|
+
- [ ] Quality report has 5 metric cards (unit tests, line coverage, mutation score, API assertions, API coverage)
|
|
449
|
+
- [ ] Quality report has Unit Tests tab and API Tests tab
|
|
450
|
+
- [ ] Unit Tests tab has Survived Mutations sub-tab
|
|
451
|
+
- [ ] JaCoCo and PIT report links in quality report are not 404 (check `stage-report-artifacts.sh` ran)
|
|
452
|
+
- [ ] All `.sh` files are executable (`chmod +x`)
|
|
453
|
+
- [ ] Jenkinsfile `publishHTML` has `includes: '**/*'` — otherwise CSS won't load
|
|
454
|
+
- [ ] Jenkinsfile has Mutation Tests stage and Quality Report generation
|