qa-skills 3.0.0
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 +168 -0
- package/bin/cli.js +42 -0
- package/dist/agents/registry.d.ts +5 -0
- package/dist/agents/registry.d.ts.map +1 -0
- package/dist/agents/registry.js +101 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/types.d.ts +9 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/dependencies.d.ts +21 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +125 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/installer.d.ts +25 -0
- package/dist/installer.d.ts.map +1 -0
- package/dist/installer.js +437 -0
- package/dist/installer.js.map +1 -0
- package/dist/scaffold.d.ts +27 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +182 -0
- package/dist/scaffold.js.map +1 -0
- package/package.json +40 -0
- package/skills/qa-accessibility-test-writer/SKILL.md +127 -0
- package/skills/qa-accessibility-test-writer/references/axe-core-patterns.md +349 -0
- package/skills/qa-accessibility-test-writer/references/best-practices.md +184 -0
- package/skills/qa-accessibility-test-writer/references/wcag-tests.md +331 -0
- package/skills/qa-api-contract-curator/SKILL.md +104 -0
- package/skills/qa-api-contract-curator/references/breaking-changes.md +363 -0
- package/skills/qa-api-contract-curator/references/openapi-structure.md +404 -0
- package/skills/qa-browser-data-collector/SKILL.md +132 -0
- package/skills/qa-browser-data-collector/references/data-collection-checklist.md +91 -0
- package/skills/qa-browser-data-collector/references/playwright-mcp-patterns.md +113 -0
- package/skills/qa-bug-ticket-creator/SKILL.md +148 -0
- package/skills/qa-bug-ticket-creator/references/bug-report-format.md +149 -0
- package/skills/qa-bug-ticket-creator/references/severity-guide.md +81 -0
- package/skills/qa-bug-ticket-creator/templates/bug-ticket-template.md +39 -0
- package/skills/qa-changelog-analyzer/SKILL.md +134 -0
- package/skills/qa-changelog-analyzer/references/git-analysis-patterns.md +138 -0
- package/skills/qa-changelog-analyzer/references/impact-mapping.md +120 -0
- package/skills/qa-clickup-integration/SKILL.md +166 -0
- package/skills/qa-clickup-integration/references/api-patterns.md +102 -0
- package/skills/qa-clickup-integration/references/field-mapping.md +71 -0
- package/skills/qa-codeceptjs-writer/SKILL.md +136 -0
- package/skills/qa-codeceptjs-writer/references/best-practices.md +207 -0
- package/skills/qa-codeceptjs-writer/references/config.md +255 -0
- package/skills/qa-codeceptjs-writer/references/patterns.md +285 -0
- package/skills/qa-coverage-analyzer/SKILL.md +166 -0
- package/skills/qa-coverage-analyzer/references/best-practices.md +142 -0
- package/skills/qa-coverage-analyzer/references/coverage-dimensions.md +155 -0
- package/skills/qa-coverage-analyzer/references/tools.md +204 -0
- package/skills/qa-cypress-writer/SKILL.md +134 -0
- package/skills/qa-cypress-writer/references/assertions.md +121 -0
- package/skills/qa-cypress-writer/references/best-practices.md +82 -0
- package/skills/qa-cypress-writer/references/config.md +121 -0
- package/skills/qa-cypress-writer/references/patterns.md +170 -0
- package/skills/qa-data-factory/SKILL.md +126 -0
- package/skills/qa-data-factory/references/factory-patterns.md +164 -0
- package/skills/qa-data-factory/references/faker-guide.md +131 -0
- package/skills/qa-diagram-generator/SKILL.md +125 -0
- package/skills/qa-diagram-generator/references/c4-model.md +53 -0
- package/skills/qa-diagram-generator/references/charts.md +58 -0
- package/skills/qa-diagram-generator/references/class-diagram.md +85 -0
- package/skills/qa-diagram-generator/references/er-diagram.md +69 -0
- package/skills/qa-diagram-generator/references/flowchart.md +92 -0
- package/skills/qa-diagram-generator/references/from-screenshot.md +45 -0
- package/skills/qa-diagram-generator/references/gantt.md +49 -0
- package/skills/qa-diagram-generator/references/journey.md +50 -0
- package/skills/qa-diagram-generator/references/mindmap.md +75 -0
- package/skills/qa-diagram-generator/references/sequence.md +69 -0
- package/skills/qa-diagram-generator/references/state-diagram.md +56 -0
- package/skills/qa-discovery-interview/SKILL.md +182 -0
- package/skills/qa-discovery-interview/references/completeness-checklist.md +53 -0
- package/skills/qa-discovery-interview/references/conflict-patterns.md +101 -0
- package/skills/qa-discovery-interview/references/qa-categories.md +147 -0
- package/skills/qa-discovery-interview/templates/qa-brief-template.md +168 -0
- package/skills/qa-environment-checker/SKILL.md +142 -0
- package/skills/qa-environment-checker/references/dependency-matrix.md +101 -0
- package/skills/qa-environment-checker/references/health-checks.md +209 -0
- package/skills/qa-environment-checker/templates/env-readiness-template.md +64 -0
- package/skills/qa-flaky-detector/SKILL.md +153 -0
- package/skills/qa-flaky-detector/references/ci-analysis.md +140 -0
- package/skills/qa-flaky-detector/references/flaky-patterns.md +247 -0
- package/skills/qa-github-issues-enhanced/SKILL.md +175 -0
- package/skills/qa-github-issues-enhanced/references/issue-templates.md +425 -0
- package/skills/qa-github-issues-enhanced/references/label-taxonomy.md +130 -0
- package/skills/qa-github-issues-enhanced/references/workflow-patterns.md +188 -0
- package/skills/qa-httpx-writer/SKILL.md +138 -0
- package/skills/qa-httpx-writer/references/assertions.md +195 -0
- package/skills/qa-httpx-writer/references/best-practices.md +140 -0
- package/skills/qa-httpx-writer/references/config.md +212 -0
- package/skills/qa-httpx-writer/references/patterns.md +262 -0
- package/skills/qa-jest-writer/SKILL.md +131 -0
- package/skills/qa-jest-writer/references/assertions.md +125 -0
- package/skills/qa-jest-writer/references/best-practices.md +136 -0
- package/skills/qa-jest-writer/references/config.md +134 -0
- package/skills/qa-jest-writer/references/patterns.md +172 -0
- package/skills/qa-jira-integration/SKILL.md +135 -0
- package/skills/qa-jira-integration/references/api-patterns.md +143 -0
- package/skills/qa-jira-integration/references/field-mapping.md +79 -0
- package/skills/qa-jira-integration/references/xray-integration.md +85 -0
- package/skills/qa-jmeter-writer/SKILL.md +171 -0
- package/skills/qa-jmeter-writer/references/best-practices.md +157 -0
- package/skills/qa-jmeter-writer/references/config.md +204 -0
- package/skills/qa-jmeter-writer/references/patterns.md +242 -0
- package/skills/qa-junit5-writer/SKILL.md +157 -0
- package/skills/qa-junit5-writer/references/assertions.md +118 -0
- package/skills/qa-junit5-writer/references/config.md +97 -0
- package/skills/qa-junit5-writer/references/patterns.md +162 -0
- package/skills/qa-k6-writer/SKILL.md +155 -0
- package/skills/qa-k6-writer/references/best-practices.md +236 -0
- package/skills/qa-k6-writer/references/config.md +219 -0
- package/skills/qa-k6-writer/references/patterns.md +304 -0
- package/skills/qa-linear-integration/SKILL.md +137 -0
- package/skills/qa-linear-integration/references/api-patterns.md +249 -0
- package/skills/qa-linear-integration/references/field-mapping.md +121 -0
- package/skills/qa-locust-writer/SKILL.md +151 -0
- package/skills/qa-locust-writer/references/best-practices.md +126 -0
- package/skills/qa-locust-writer/references/config.md +170 -0
- package/skills/qa-locust-writer/references/patterns.md +235 -0
- package/skills/qa-manual-test-designer/SKILL.md +145 -0
- package/skills/qa-manual-test-designer/references/exploratory-charters.md +138 -0
- package/skills/qa-manual-test-designer/references/personas.md +146 -0
- package/skills/qa-manual-test-designer/templates/exploratory-charter-template.md +47 -0
- package/skills/qa-manual-test-designer/templates/test-case-template.md +31 -0
- package/skills/qa-mobile-test-writer/SKILL.md +144 -0
- package/skills/qa-mobile-test-writer/references/best-practices.md +214 -0
- package/skills/qa-mobile-test-writer/references/config.md +309 -0
- package/skills/qa-mobile-test-writer/references/patterns.md +304 -0
- package/skills/qa-nfr-analyst/SKILL.md +177 -0
- package/skills/qa-nfr-analyst/references/iso-25010-model.md +159 -0
- package/skills/qa-nfr-analyst/references/owasp-wstg-baseline.md +202 -0
- package/skills/qa-nfr-analyst/references/wcag-checklist.md +184 -0
- package/skills/qa-nfr-analyst/templates/owasp-checklist-template.md +89 -0
- package/skills/qa-nfr-analyst/templates/wcag-checklist-template.md +48 -0
- package/skills/qa-orchestrator/SKILL.md +132 -0
- package/skills/qa-orchestrator/references/handoff-chains.md +105 -0
- package/skills/qa-orchestrator/references/pipeline-modes.md +115 -0
- package/skills/qa-orchestrator/references/scheduler-rules.md +84 -0
- package/skills/qa-pact-writer/SKILL.md +133 -0
- package/skills/qa-pact-writer/references/best-practices.md +100 -0
- package/skills/qa-pact-writer/references/config.md +135 -0
- package/skills/qa-pact-writer/references/patterns.md +161 -0
- package/skills/qa-plan-creator/SKILL.md +139 -0
- package/skills/qa-plan-creator/references/introduction-plan.md +43 -0
- package/skills/qa-plan-creator/references/migration-plan.md +44 -0
- package/skills/qa-plan-creator/references/onboarding-plan.md +46 -0
- package/skills/qa-plan-creator/references/performance-plan.md +44 -0
- package/skills/qa-plan-creator/references/regression-plan.md +45 -0
- package/skills/qa-plan-creator/references/release-plan.md +45 -0
- package/skills/qa-plan-creator/references/sprint-plan.md +44 -0
- package/skills/qa-plan-creator/references/test-plan.md +59 -0
- package/skills/qa-plan-creator/references/uat-plan.md +43 -0
- package/skills/qa-plan-creator/templates/checklist-template.md +36 -0
- package/skills/qa-plan-creator/templates/regression-checklist-template.md +49 -0
- package/skills/qa-plan-creator/templates/release-checklist-template.md +46 -0
- package/skills/qa-plan-creator/templates/test-plan-template.md +74 -0
- package/skills/qa-playwright-py-writer/SKILL.md +156 -0
- package/skills/qa-playwright-py-writer/references/best-practices.md +194 -0
- package/skills/qa-playwright-py-writer/references/config.md +195 -0
- package/skills/qa-playwright-py-writer/references/patterns.md +212 -0
- package/skills/qa-playwright-ts-writer/SKILL.md +151 -0
- package/skills/qa-playwright-ts-writer/references/assertions.md +109 -0
- package/skills/qa-playwright-ts-writer/references/best-practices.md +191 -0
- package/skills/qa-playwright-ts-writer/references/config.md +144 -0
- package/skills/qa-playwright-ts-writer/references/patterns.md +171 -0
- package/skills/qa-pytest-writer/SKILL.md +145 -0
- package/skills/qa-pytest-writer/references/assertions.md +149 -0
- package/skills/qa-pytest-writer/references/best-practices.md +97 -0
- package/skills/qa-pytest-writer/references/config.md +176 -0
- package/skills/qa-pytest-writer/references/patterns.md +251 -0
- package/skills/qa-qase-integration/SKILL.md +149 -0
- package/skills/qa-qase-integration/references/api-reference.md +354 -0
- package/skills/qa-qase-integration/references/ci-integration.md +196 -0
- package/skills/qa-qase-integration/references/field-mapping.md +157 -0
- package/skills/qa-requirements-generator/SKILL.md +152 -0
- package/skills/qa-requirements-generator/references/iso-29148-structure.md +153 -0
- package/skills/qa-requirements-generator/references/requirement-patterns.md +278 -0
- package/skills/qa-rest-assured-writer/SKILL.md +137 -0
- package/skills/qa-rest-assured-writer/references/best-practices.md +50 -0
- package/skills/qa-rest-assured-writer/references/config.md +124 -0
- package/skills/qa-rest-assured-writer/references/patterns.md +192 -0
- package/skills/qa-risk-analyzer/SKILL.md +158 -0
- package/skills/qa-risk-analyzer/references/impact-analysis.md +133 -0
- package/skills/qa-risk-analyzer/references/risk-factors.md +123 -0
- package/skills/qa-robot-framework-writer/SKILL.md +147 -0
- package/skills/qa-robot-framework-writer/references/best-practices.md +249 -0
- package/skills/qa-robot-framework-writer/references/config.md +204 -0
- package/skills/qa-robot-framework-writer/references/libraries.md +273 -0
- package/skills/qa-robot-framework-writer/references/patterns.md +216 -0
- package/skills/qa-security-test-writer/SKILL.md +123 -0
- package/skills/qa-security-test-writer/references/best-practices.md +155 -0
- package/skills/qa-security-test-writer/references/owasp-top10.md +331 -0
- package/skills/qa-security-test-writer/references/zap-config.md +258 -0
- package/skills/qa-selenium-java-writer/SKILL.md +143 -0
- package/skills/qa-selenium-java-writer/references/best-practices.md +59 -0
- package/skills/qa-selenium-java-writer/references/config.md +143 -0
- package/skills/qa-selenium-java-writer/references/patterns.md +170 -0
- package/skills/qa-selenium-py-writer/SKILL.md +150 -0
- package/skills/qa-selenium-py-writer/references/best-practices.md +175 -0
- package/skills/qa-selenium-py-writer/references/config.md +224 -0
- package/skills/qa-selenium-py-writer/references/patterns.md +255 -0
- package/skills/qa-shortcut-integration/SKILL.md +143 -0
- package/skills/qa-shortcut-integration/references/api-patterns.md +126 -0
- package/skills/qa-shortcut-integration/references/field-mapping.md +66 -0
- package/skills/qa-spec-auditor/SKILL.md +162 -0
- package/skills/qa-spec-auditor/references/audit-checklist.md +144 -0
- package/skills/qa-spec-auditor/references/drift-patterns.md +207 -0
- package/skills/qa-spec-writer/SKILL.md +143 -0
- package/skills/qa-spec-writer/references/gherkin-guide.md +253 -0
- package/skills/qa-spec-writer/references/specification-patterns.md +274 -0
- package/skills/qa-spring-test-writer/SKILL.md +170 -0
- package/skills/qa-spring-test-writer/references/best-practices.md +57 -0
- package/skills/qa-spring-test-writer/references/config.md +179 -0
- package/skills/qa-spring-test-writer/references/patterns.md +235 -0
- package/skills/qa-supertest-writer/SKILL.md +150 -0
- package/skills/qa-supertest-writer/references/assertions.md +192 -0
- package/skills/qa-supertest-writer/references/best-practices.md +102 -0
- package/skills/qa-supertest-writer/references/config.md +166 -0
- package/skills/qa-supertest-writer/references/patterns.md +242 -0
- package/skills/qa-task-creator/SKILL.md +142 -0
- package/skills/qa-task-creator/references/linking-patterns.md +127 -0
- package/skills/qa-task-creator/references/task-types.md +169 -0
- package/skills/qa-task-creator/templates/task-template.md +24 -0
- package/skills/qa-test-doc-compiler/SKILL.md +114 -0
- package/skills/qa-test-doc-compiler/references/agile-tailoring.md +220 -0
- package/skills/qa-test-doc-compiler/references/iso-29119-3-documents.md +302 -0
- package/skills/qa-test-healer/SKILL.md +101 -0
- package/skills/qa-test-healer/references/diagnosis-patterns.md +142 -0
- package/skills/qa-test-healer/references/fix-strategies.md +177 -0
- package/skills/qa-test-reporter/SKILL.md +130 -0
- package/skills/qa-test-reporter/references/best-practices.md +162 -0
- package/skills/qa-test-reporter/references/iso-29119-reports.md +236 -0
- package/skills/qa-test-reporter/references/report-formats.md +287 -0
- package/skills/qa-test-reviewer/SKILL.md +142 -0
- package/skills/qa-test-reviewer/references/anti-patterns.md +268 -0
- package/skills/qa-test-reviewer/references/review-checklist.md +93 -0
- package/skills/qa-test-strategy/SKILL.md +133 -0
- package/skills/qa-test-strategy/references/entry-exit-criteria.md +176 -0
- package/skills/qa-test-strategy/references/risk-matrix.md +102 -0
- package/skills/qa-test-strategy/references/testing-types.md +143 -0
- package/skills/qa-testcase-from-docs/SKILL.md +161 -0
- package/skills/qa-testcase-from-docs/references/test-case-format.md +196 -0
- package/skills/qa-testcase-from-docs/references/test-design-techniques.md +126 -0
- package/skills/qa-testcase-from-docs/templates/test-case-template.md +31 -0
- package/skills/qa-testcase-from-ui/SKILL.md +109 -0
- package/skills/qa-testcase-from-ui/references/ui-element-patterns.md +126 -0
- package/skills/qa-testcase-from-ui/references/visual-analysis-guide.md +146 -0
- package/skills/qa-testcase-from-ui/templates/test-case-template.md +31 -0
- package/skills/qa-visual-regression-writer/SKILL.md +175 -0
- package/skills/qa-visual-regression-writer/references/best-practices.md +154 -0
- package/skills/qa-visual-regression-writer/references/config.md +220 -0
- package/skills/qa-visual-regression-writer/references/patterns.md +213 -0
- package/skills/qa-vitest-writer/SKILL.md +141 -0
- package/skills/qa-vitest-writer/references/assertions.md +105 -0
- package/skills/qa-vitest-writer/references/best-practices.md +62 -0
- package/skills/qa-vitest-writer/references/config.md +127 -0
- package/skills/qa-vitest-writer/references/patterns.md +141 -0
- package/skills/qa-webdriverio-writer/SKILL.md +145 -0
- package/skills/qa-webdriverio-writer/references/best-practices.md +176 -0
- package/skills/qa-webdriverio-writer/references/config.md +240 -0
- package/skills/qa-webdriverio-writer/references/patterns.md +269 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-junit5-writer
|
|
3
|
+
description: Generate JUnit 5 unit and integration tests for Java with parameterized tests, nested classes, extensions, Mockito mocking, and AssertJ assertions.
|
|
4
|
+
output_dir: tests/unit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# QA JUnit 5 Writer
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Write JUnit 5 unit and integration tests from test case specifications. Transform structured test cases into executable JUnit 5 test classes with parameterized tests, nested classes for organization, extensions, Mockito mocking, and AssertJ assertions.
|
|
12
|
+
|
|
13
|
+
## Trigger Phrases
|
|
14
|
+
|
|
15
|
+
- "Write JUnit 5 tests for [class/feature]"
|
|
16
|
+
- "Generate unit tests with JUnit 5"
|
|
17
|
+
- "Create parameterized tests for [method]"
|
|
18
|
+
- "Add JUnit 5 tests with Mockito"
|
|
19
|
+
- "JUnit 5 tests with AssertJ assertions"
|
|
20
|
+
- "Nested test classes for [feature]"
|
|
21
|
+
- "JUnit 5 @ParameterizedTest for [scenarios]"
|
|
22
|
+
- "Mockito mocks in JUnit 5 tests"
|
|
23
|
+
- "Heal my failing JUnit 5 tests"
|
|
24
|
+
|
|
25
|
+
## Key Features
|
|
26
|
+
|
|
27
|
+
| Feature | Description |
|
|
28
|
+
| ------- | ----------- |
|
|
29
|
+
| **@Test** | Standard test methods |
|
|
30
|
+
| **@ParameterizedTest** | Data-driven tests with @CsvSource, @MethodSource, @EnumSource |
|
|
31
|
+
| **@Nested** | Logical grouping; inner classes with @BeforeEach per level |
|
|
32
|
+
| **@ExtendWith** | Extensions (MockitoExtension, custom) |
|
|
33
|
+
| **Mockito** | @Mock, @InjectMocks, when().thenReturn(), verify() |
|
|
34
|
+
| **AssertJ** | Fluent assertions: assertThat().isEqualTo(), containsExactly() |
|
|
35
|
+
| **@TestInstance** | PER_CLASS for shared setup; PER_METHOD default |
|
|
36
|
+
| **@Tag** | Categorization for selective execution |
|
|
37
|
+
| **@DisplayName** | Human-readable test names |
|
|
38
|
+
|
|
39
|
+
## Workflow
|
|
40
|
+
|
|
41
|
+
1. **Read test cases** — From specs, requirements, or manual test designs
|
|
42
|
+
2. **Analyze Java code** — Inspect classes, methods, dependencies
|
|
43
|
+
3. **Generate test classes** — Produce `{Class}Test.java` with appropriate structure
|
|
44
|
+
4. **Add mocks/fixtures** — Use Mockito for dependencies; fixtures for test data
|
|
45
|
+
5. **Run** — User runs `mvn test` or `./gradlew test`
|
|
46
|
+
|
|
47
|
+
## Key Patterns
|
|
48
|
+
|
|
49
|
+
| Pattern | Usage |
|
|
50
|
+
| ------- | ----- |
|
|
51
|
+
| `@Test` | JUnit 5 test method |
|
|
52
|
+
| `@ParameterizedTest` | Data-driven test |
|
|
53
|
+
| `@CsvSource({"a,1", "b,2"})` | Inline CSV data |
|
|
54
|
+
| `@MethodSource("provideData")` | Method-provided data |
|
|
55
|
+
| `@Nested` | Group related tests |
|
|
56
|
+
| `@ExtendWith(MockitoExtension.class)` | Enable Mockito |
|
|
57
|
+
| `@Mock` | Mock dependency |
|
|
58
|
+
| `@InjectMocks` | Inject mocks into SUT |
|
|
59
|
+
| `when(mock.method()).thenReturn(value)` | Stub mock |
|
|
60
|
+
| `verify(mock, times(1)).method()` | Verify interaction |
|
|
61
|
+
| `assertThat(actual).isEqualTo(expected)` | AssertJ assertion |
|
|
62
|
+
|
|
63
|
+
## Parameterized Tests
|
|
64
|
+
|
|
65
|
+
```java
|
|
66
|
+
@ParameterizedTest
|
|
67
|
+
@CsvSource({"admin, true", "user, false"})
|
|
68
|
+
void shouldCheckAccess(String role, boolean expected) {
|
|
69
|
+
assertThat(service.hasAccess(role)).isEqualTo(expected);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@ParameterizedTest
|
|
73
|
+
@MethodSource("provideInvalidInputs")
|
|
74
|
+
void shouldRejectInvalidInput(String input) {
|
|
75
|
+
assertThatThrownBy(() -> validator.validate(input))
|
|
76
|
+
.isInstanceOf(ValidationException.class);
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Nested Classes
|
|
81
|
+
|
|
82
|
+
Use @Nested for logical grouping; each nested class gets its own @BeforeEach:
|
|
83
|
+
|
|
84
|
+
```java
|
|
85
|
+
@DisplayName("UserService")
|
|
86
|
+
class UserServiceTest {
|
|
87
|
+
@Nested
|
|
88
|
+
@DisplayName("when user exists")
|
|
89
|
+
class WhenUserExists {
|
|
90
|
+
@Test
|
|
91
|
+
void shouldReturnUser() { ... }
|
|
92
|
+
}
|
|
93
|
+
@Nested
|
|
94
|
+
@DisplayName("when user not found")
|
|
95
|
+
class WhenUserNotFound {
|
|
96
|
+
@Test
|
|
97
|
+
void shouldThrowException() { ... }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## File Naming
|
|
103
|
+
|
|
104
|
+
- `{Class}Test.java` — Test classes (e.g., `UserServiceTest.java`, `OrderValidatorTest.java`)
|
|
105
|
+
- Place in `src/test/java` mirroring production package structure
|
|
106
|
+
|
|
107
|
+
## Scope
|
|
108
|
+
|
|
109
|
+
**Can do (autonomous):**
|
|
110
|
+
- Generate JUnit 5 unit and integration tests from test case specs
|
|
111
|
+
- Use @ParameterizedTest for data-driven scenarios
|
|
112
|
+
- Apply @Nested for logical grouping
|
|
113
|
+
- Use Mockito for mocking dependencies
|
|
114
|
+
- Use AssertJ for fluent assertions
|
|
115
|
+
- Add @Tag, @DisplayName for organization
|
|
116
|
+
- Configure @TestInstance when shared setup needed
|
|
117
|
+
- Use Context7 MCP for JUnit 5/Mockito docs
|
|
118
|
+
- Delegate to qa-test-healer when tests fail (Heal Mode)
|
|
119
|
+
|
|
120
|
+
**Cannot do (requires confirmation):**
|
|
121
|
+
- Change production code structure
|
|
122
|
+
- Add dependencies not in pom.xml/build.gradle
|
|
123
|
+
- Override project JUnit/Mockito config without approval
|
|
124
|
+
|
|
125
|
+
**Will not do (out of scope):**
|
|
126
|
+
- Execute tests (user runs `mvn test`)
|
|
127
|
+
- Write Spring integration tests (use qa-spring-test-writer)
|
|
128
|
+
- Modify CI/CD pipelines
|
|
129
|
+
|
|
130
|
+
## References
|
|
131
|
+
|
|
132
|
+
- `references/patterns.md` — Parameterized, nested, extensions, lifecycle
|
|
133
|
+
- `references/assertions.md` — AssertJ assertion reference
|
|
134
|
+
- `references/config.md` — Maven/Gradle JUnit 5 config, Surefire plugin
|
|
135
|
+
|
|
136
|
+
## Quality Checklist
|
|
137
|
+
|
|
138
|
+
- [ ] @DisplayName used for readability
|
|
139
|
+
- [ ] @ParameterizedTest for multiple inputs; avoid duplicate test methods
|
|
140
|
+
- [ ] @Nested for logical grouping where beneficial
|
|
141
|
+
- [ ] Mockito used for external dependencies; avoid over-mocking
|
|
142
|
+
- [ ] AssertJ used for assertions
|
|
143
|
+
- [ ] Tests independent (no shared mutable state)
|
|
144
|
+
- [ ] One assertion focus per test where practical
|
|
145
|
+
- [ ] Traceability to test case IDs where applicable
|
|
146
|
+
- [ ] File naming follows `{Class}Test.java` convention
|
|
147
|
+
|
|
148
|
+
## Troubleshooting
|
|
149
|
+
|
|
150
|
+
| Symptom | Likely Cause | Fix |
|
|
151
|
+
| ------- | ------------ | --- |
|
|
152
|
+
| Mock not injected | Wrong extension or order | Use @ExtendWith(MockitoExtension.class); @InjectMocks before @Mock |
|
|
153
|
+
| ParameterizedTest fails | Invalid CSV/method source | Check @CsvSource format; ensure @MethodSource returns Stream |
|
|
154
|
+
| Nested @BeforeEach runs twice | Misunderstanding lifecycle | Each @Nested level has own lifecycle; @BeforeEach runs per test in that level |
|
|
155
|
+
| AssertJ import error | Wrong static import | Use `import static org.assertj.core.api.Assertions.assertThat` |
|
|
156
|
+
| Test order dependent | Shared state | Ensure test isolation; use @TestInstance(PER_METHOD) or fresh fixtures |
|
|
157
|
+
| Surefire skips tests | JUnit 4 engine conflict | Exclude junit-vintage; use junit-platform-surefire-provider |
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# AssertJ Assertion Reference
|
|
2
|
+
|
|
3
|
+
## Basic Assertions
|
|
4
|
+
|
|
5
|
+
```java
|
|
6
|
+
import static org.assertj.core.api.Assertions.*;
|
|
7
|
+
|
|
8
|
+
// Equality
|
|
9
|
+
assertThat(actual).isEqualTo(expected);
|
|
10
|
+
assertThat(actual).isNotEqualTo(unexpected);
|
|
11
|
+
|
|
12
|
+
// Null
|
|
13
|
+
assertThat(value).isNull();
|
|
14
|
+
assertThat(value).isNotNull();
|
|
15
|
+
|
|
16
|
+
// Boolean
|
|
17
|
+
assertThat(condition).isTrue();
|
|
18
|
+
assertThat(condition).isFalse();
|
|
19
|
+
|
|
20
|
+
// Same instance
|
|
21
|
+
assertThat(actual).isSameAs(expected);
|
|
22
|
+
assertThat(actual).isNotSameAs(other);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## String Assertions
|
|
26
|
+
|
|
27
|
+
```java
|
|
28
|
+
assertThat(str).isEqualTo("expected");
|
|
29
|
+
assertThat(str).contains("substring");
|
|
30
|
+
assertThat(str).startsWith("prefix");
|
|
31
|
+
assertThat(str).endsWith("suffix");
|
|
32
|
+
assertThat(str).matches("regex.*");
|
|
33
|
+
assertThat(str).isBlank();
|
|
34
|
+
assertThat(str).isNotEmpty();
|
|
35
|
+
assertThat(str).hasSize(10);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Collection Assertions
|
|
39
|
+
|
|
40
|
+
```java
|
|
41
|
+
assertThat(list).isEmpty();
|
|
42
|
+
assertThat(list).isNotEmpty();
|
|
43
|
+
assertThat(list).hasSize(3);
|
|
44
|
+
assertThat(list).contains("a", "b");
|
|
45
|
+
assertThat(list).containsExactly("a", "b", "c");
|
|
46
|
+
assertThat(list).containsExactlyInAnyOrder("c", "a", "b");
|
|
47
|
+
assertThat(list).containsAnyOf("a", "x");
|
|
48
|
+
assertThat(list).doesNotContain("x");
|
|
49
|
+
assertThat(list).startsWith("a", "b");
|
|
50
|
+
assertThat(list).endsWith("b", "c");
|
|
51
|
+
assertThat(list).allMatch(e -> e.length() > 0);
|
|
52
|
+
assertThat(list).anyMatch(e -> e.equals("target"));
|
|
53
|
+
assertThat(list).noneMatch(e -> e.isBlank());
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Map Assertions
|
|
57
|
+
|
|
58
|
+
```java
|
|
59
|
+
assertThat(map).isEmpty();
|
|
60
|
+
assertThat(map).containsKey("key");
|
|
61
|
+
assertThat(map).containsValue("value");
|
|
62
|
+
assertThat(map).containsEntry("key", "value");
|
|
63
|
+
assertThat(map).hasSize(3);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Number Assertions
|
|
67
|
+
|
|
68
|
+
```java
|
|
69
|
+
assertThat(number).isEqualTo(42);
|
|
70
|
+
assertThat(number).isGreaterThan(10);
|
|
71
|
+
assertThat(number).isGreaterThanOrEqualTo(10);
|
|
72
|
+
assertThat(number).isLessThan(100);
|
|
73
|
+
assertThat(number).isBetween(1, 100);
|
|
74
|
+
assertThat(number).isPositive();
|
|
75
|
+
assertThat(number).isNegative();
|
|
76
|
+
assertThat(number).isZero();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Exception Assertions
|
|
80
|
+
|
|
81
|
+
```java
|
|
82
|
+
assertThatThrownBy(() -> service.doSomething())
|
|
83
|
+
.isInstanceOf(ValidationException.class)
|
|
84
|
+
.hasMessage("Invalid input")
|
|
85
|
+
.hasMessageContaining("input")
|
|
86
|
+
.hasCauseInstanceOf(IOException.class);
|
|
87
|
+
|
|
88
|
+
assertThatCode(() -> service.validCall()).doesNotThrowAnyException();
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Optional Assertions
|
|
92
|
+
|
|
93
|
+
```java
|
|
94
|
+
assertThat(optional).isPresent();
|
|
95
|
+
assertThat(optional).isEmpty();
|
|
96
|
+
assertThat(optional).hasValue("expected");
|
|
97
|
+
assertThat(optional).contains("expected");
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Object Assertions
|
|
101
|
+
|
|
102
|
+
```java
|
|
103
|
+
assertThat(obj).hasFieldOrProperty("name");
|
|
104
|
+
assertThat(obj).hasFieldOrPropertyWithValue("name", "value");
|
|
105
|
+
assertThat(obj).extracting("name").isEqualTo("value");
|
|
106
|
+
assertThat(obj).extracting("name", "age").containsExactly("John", 30);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Soft Assertions
|
|
110
|
+
|
|
111
|
+
Collect multiple failures:
|
|
112
|
+
```java
|
|
113
|
+
assertSoftly(softly -> {
|
|
114
|
+
softly.assertThat(a).isEqualTo(1);
|
|
115
|
+
softly.assertThat(b).isEqualTo(2);
|
|
116
|
+
softly.assertThat(c).isEqualTo(3);
|
|
117
|
+
});
|
|
118
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# JUnit 5 Configuration
|
|
2
|
+
|
|
3
|
+
## Maven Dependencies
|
|
4
|
+
|
|
5
|
+
```xml
|
|
6
|
+
<dependencies>
|
|
7
|
+
<dependency>
|
|
8
|
+
<groupId>org.junit.jupiter</groupId>
|
|
9
|
+
<artifactId>junit-jupiter</artifactId>
|
|
10
|
+
<version>5.10.2</version>
|
|
11
|
+
<scope>test</scope>
|
|
12
|
+
</dependency>
|
|
13
|
+
<dependency>
|
|
14
|
+
<groupId>org.mockito</groupId>
|
|
15
|
+
<artifactId>mockito-junit-jupiter</artifactId>
|
|
16
|
+
<version>5.11.0</version>
|
|
17
|
+
<scope>test</scope>
|
|
18
|
+
</dependency>
|
|
19
|
+
<dependency>
|
|
20
|
+
<groupId>org.assertj</groupId>
|
|
21
|
+
<artifactId>assertj-core</artifactId>
|
|
22
|
+
<version>3.25.3</version>
|
|
23
|
+
<scope>test</scope>
|
|
24
|
+
</dependency>
|
|
25
|
+
</dependencies>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Surefire Plugin
|
|
29
|
+
|
|
30
|
+
```xml
|
|
31
|
+
<plugin>
|
|
32
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
33
|
+
<artifactId>maven-surefire-plugin</artifactId>
|
|
34
|
+
<version>3.2.5</version>
|
|
35
|
+
<configuration>
|
|
36
|
+
<includes>
|
|
37
|
+
<include>**/*Test.java</include>
|
|
38
|
+
<include>**/*Tests.java</include>
|
|
39
|
+
</includes>
|
|
40
|
+
<excludes>
|
|
41
|
+
<exclude>**/*IntegrationTest.java</exclude>
|
|
42
|
+
</excludes>
|
|
43
|
+
<properties>
|
|
44
|
+
<includeTags>unit</includeTags>
|
|
45
|
+
<excludeTags>slow,integration</excludeTags>
|
|
46
|
+
</properties>
|
|
47
|
+
<parallel>methods</parallel>
|
|
48
|
+
<threadCount>4</threadCount>
|
|
49
|
+
</configuration>
|
|
50
|
+
</plugin>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Gradle
|
|
54
|
+
|
|
55
|
+
```groovy
|
|
56
|
+
dependencies {
|
|
57
|
+
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
|
|
58
|
+
testImplementation 'org.mockito:mockito-junit-jupiter:5.11.0'
|
|
59
|
+
testImplementation 'org.assertj:assertj-core:3.25.3'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
test {
|
|
63
|
+
useJUnitPlatform()
|
|
64
|
+
testLogging {
|
|
65
|
+
events "passed", "skipped", "failed"
|
|
66
|
+
}
|
|
67
|
+
systemProperty 'junit.jupiter.execution.parallel.enabled', 'true'
|
|
68
|
+
systemProperty 'junit.jupiter.execution.parallel.config.strategy', 'dynamic'
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Excluding JUnit 4
|
|
73
|
+
|
|
74
|
+
If JUnit 4 is on classpath, exclude vintage engine:
|
|
75
|
+
```xml
|
|
76
|
+
<dependency>
|
|
77
|
+
<groupId>org.junit.jupiter</groupId>
|
|
78
|
+
<artifactId>junit-jupiter</artifactId>
|
|
79
|
+
<version>5.10.2</version>
|
|
80
|
+
<scope>test</scope>
|
|
81
|
+
<exclusions>
|
|
82
|
+
<exclusion>
|
|
83
|
+
<groupId>org.junit.vintage</groupId>
|
|
84
|
+
<artifactId>junit-vintage-engine</artifactId>
|
|
85
|
+
</exclusion>
|
|
86
|
+
</exclusions>
|
|
87
|
+
</dependency>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## junit-platform.properties
|
|
91
|
+
|
|
92
|
+
Place in `src/test/resources/junit-platform.properties`:
|
|
93
|
+
```properties
|
|
94
|
+
junit.jupiter.execution.parallel.enabled=true
|
|
95
|
+
junit.jupiter.execution.parallel.config.strategy=dynamic
|
|
96
|
+
junit.jupiter.execution.parallel.config.dynamic.factor=1
|
|
97
|
+
```
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# JUnit 5 Patterns
|
|
2
|
+
|
|
3
|
+
## Parameterized Tests
|
|
4
|
+
|
|
5
|
+
### @CsvSource
|
|
6
|
+
Inline CSV data for simple cases:
|
|
7
|
+
```java
|
|
8
|
+
@ParameterizedTest
|
|
9
|
+
@CsvSource({"1, one", "2, two", "3, three"})
|
|
10
|
+
void mapNumberToWord(int num, String word) {
|
|
11
|
+
assertThat(converter.toWord(num)).isEqualTo(word);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@ParameterizedTest
|
|
15
|
+
@CsvSource(value = {"null;null", "'';empty"}, delimiter = ';')
|
|
16
|
+
void handleEdgeCases(String input, String expected) {
|
|
17
|
+
assertThat(processor.process(input)).isEqualTo(expected);
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### @MethodSource
|
|
22
|
+
Method or factory provides data:
|
|
23
|
+
```java
|
|
24
|
+
static Stream<Arguments> provideValidEmails() {
|
|
25
|
+
return Stream.of(
|
|
26
|
+
Arguments.of("user@example.com", true),
|
|
27
|
+
Arguments.of("admin@company.org", true)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@ParameterizedTest
|
|
32
|
+
@MethodSource("provideValidEmails")
|
|
33
|
+
void validateEmail(String email, boolean expected) {
|
|
34
|
+
assertThat(validator.isValid(email)).isEqualTo(expected);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### @EnumSource
|
|
39
|
+
Iterate over enum values:
|
|
40
|
+
```java
|
|
41
|
+
@ParameterizedTest
|
|
42
|
+
@EnumSource(Status.class)
|
|
43
|
+
void eachStatusHasCode(Status status) {
|
|
44
|
+
assertThat(status.getCode()).isNotNull();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@ParameterizedTest
|
|
48
|
+
@EnumSource(value = Status.class, names = {"ACTIVE", "PENDING"})
|
|
49
|
+
void activeStatuses(Status status) {
|
|
50
|
+
assertThat(status.isProcessable()).isTrue();
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### @ValueSource
|
|
55
|
+
Single-value primitives and strings:
|
|
56
|
+
```java
|
|
57
|
+
@ParameterizedTest
|
|
58
|
+
@ValueSource(ints = {1, 2, 3, 5, 8})
|
|
59
|
+
void fibonacciNumbers(int n) {
|
|
60
|
+
assertThat(fib(n)).isPositive();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@ParameterizedTest
|
|
64
|
+
@NullAndEmptySource
|
|
65
|
+
@ValueSource(strings = {" ", "\t"})
|
|
66
|
+
void blankStrings(String input) {
|
|
67
|
+
assertThat(StringUtils.isBlank(input)).isTrue();
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Nested Classes
|
|
72
|
+
|
|
73
|
+
Logical grouping with independent lifecycle:
|
|
74
|
+
```java
|
|
75
|
+
@DisplayName("OrderService")
|
|
76
|
+
class OrderServiceTest {
|
|
77
|
+
@InjectMocks OrderService orderService;
|
|
78
|
+
@Mock OrderRepository repository;
|
|
79
|
+
|
|
80
|
+
@Nested
|
|
81
|
+
@DisplayName("createOrder")
|
|
82
|
+
class CreateOrder {
|
|
83
|
+
@Test
|
|
84
|
+
void shouldCreateValidOrder() { ... }
|
|
85
|
+
@Test
|
|
86
|
+
void shouldRejectInvalidItems() { ... }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@Nested
|
|
90
|
+
@DisplayName("cancelOrder")
|
|
91
|
+
class CancelOrder {
|
|
92
|
+
@BeforeEach
|
|
93
|
+
void setupExistingOrder() {
|
|
94
|
+
when(repository.findById(1L)).thenReturn(Optional.of(existingOrder));
|
|
95
|
+
}
|
|
96
|
+
@Test
|
|
97
|
+
void shouldCancelWhenAllowed() { ... }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Extensions
|
|
103
|
+
|
|
104
|
+
### MockitoExtension
|
|
105
|
+
```java
|
|
106
|
+
@ExtendWith(MockitoExtension.class)
|
|
107
|
+
class ServiceTest {
|
|
108
|
+
@Mock Dependency dependency;
|
|
109
|
+
@InjectMocks ServiceUnderTest service;
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Custom Extension
|
|
114
|
+
```java
|
|
115
|
+
@ExtendWith(DatabaseExtension.class)
|
|
116
|
+
class RepositoryTest {
|
|
117
|
+
// Extension provides @Container, cleanup
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Lifecycle
|
|
122
|
+
|
|
123
|
+
### @TestInstance(PER_CLASS)
|
|
124
|
+
Share instance state across tests (e.g., expensive setup):
|
|
125
|
+
```java
|
|
126
|
+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
|
127
|
+
class ExpensiveSetupTest {
|
|
128
|
+
private HeavyResource resource;
|
|
129
|
+
@BeforeAll
|
|
130
|
+
void init() {
|
|
131
|
+
resource = new HeavyResource(); // Once for all tests
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### @BeforeEach / @AfterEach
|
|
137
|
+
Per-test setup and teardown:
|
|
138
|
+
```java
|
|
139
|
+
@BeforeEach
|
|
140
|
+
void setUp() {
|
|
141
|
+
driver = new ChromeDriver();
|
|
142
|
+
}
|
|
143
|
+
@AfterEach
|
|
144
|
+
void tearDown() {
|
|
145
|
+
if (driver != null) driver.quit();
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Tags and Filtering
|
|
150
|
+
|
|
151
|
+
```java
|
|
152
|
+
@Tag("slow")
|
|
153
|
+
@Test
|
|
154
|
+
void longRunningTest() { ... }
|
|
155
|
+
|
|
156
|
+
@Tag("integration")
|
|
157
|
+
@Tag("database")
|
|
158
|
+
@Test
|
|
159
|
+
void databaseIntegrationTest() { ... }
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Run with: `mvn test -Dgroups=integration` or `-DexcludedGroups=slow`
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-k6-writer
|
|
3
|
+
description: Generate k6 performance tests in JavaScript for load, stress, soak, and spike testing with thresholds, scenarios, checks, and CI-friendly output.
|
|
4
|
+
output_dir: tests/performance
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# QA k6 Writer
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Write k6 performance tests from test case specifications and performance plans. Transform structured performance requirements (from qa-nfr-analyst, qa-plan-creator performance plans) into executable k6 scripts with scenarios, thresholds, checks, and CI-friendly output.
|
|
12
|
+
|
|
13
|
+
## Trigger Phrases
|
|
14
|
+
|
|
15
|
+
- "Write k6 tests for [API/endpoint]"
|
|
16
|
+
- "Generate k6 load tests from performance plan"
|
|
17
|
+
- "Create k6 stress tests for [service]"
|
|
18
|
+
- "Add k6 soak tests with thresholds"
|
|
19
|
+
- "k6 spike test for [endpoint]"
|
|
20
|
+
- "Performance tests with k6 scenarios"
|
|
21
|
+
- "k6 smoke test for [API]"
|
|
22
|
+
- "Breakpoint testing with k6"
|
|
23
|
+
- "k6 tests with custom metrics"
|
|
24
|
+
- "k6 CI integration for GitHub Actions"
|
|
25
|
+
|
|
26
|
+
## Test Types
|
|
27
|
+
|
|
28
|
+
| Type | Purpose | Key Characteristics |
|
|
29
|
+
|------|---------|---------------------|
|
|
30
|
+
| **Load testing** | Validate behavior under expected load | Steady VUs, target throughput |
|
|
31
|
+
| **Stress testing** | Find breaking point | Ramp up until failure |
|
|
32
|
+
| **Soak testing** | Detect memory leaks, degradation | Sustained load over hours |
|
|
33
|
+
| **Spike testing** | Sudden traffic surge | Sharp ramp up/down |
|
|
34
|
+
| **Smoke testing** | Quick sanity check | 1–5 VUs, minimal duration |
|
|
35
|
+
| **Breakpoint testing** | Find capacity limit | Incremental load until threshold fails |
|
|
36
|
+
|
|
37
|
+
## Key Features
|
|
38
|
+
|
|
39
|
+
| Feature | Description |
|
|
40
|
+
|---------|-------------|
|
|
41
|
+
| **JavaScript ES6** | Standard JS syntax; no transpilation required |
|
|
42
|
+
| **Scenarios** | Multiple executors: shared-iterations, per-vu-iterations, constant-arrival-rate, ramping-arrival-rate, externally-controlled |
|
|
43
|
+
| **Thresholds** | Pass/fail criteria: `http_req_duration`, `http_req_failed`, custom metrics |
|
|
44
|
+
| **Checks** | Assertions: `check(res, { 'status is 200': (r) => r.status === 200 })` |
|
|
45
|
+
| **Stages** | Ramp-up, steady, ramp-down for realistic load profiles |
|
|
46
|
+
| **Custom metrics** | Trend, Rate, Counter, Gauge for business metrics |
|
|
47
|
+
| **Protocols** | HTTP, WebSocket, gRPC |
|
|
48
|
+
|
|
49
|
+
## Workflow
|
|
50
|
+
|
|
51
|
+
1. **Read performance test plan** — From qa-plan-creator (performance plan) or qa-nfr-analyst (NFR specs)
|
|
52
|
+
2. **Define scenarios** — Map load profiles to k6 scenarios with appropriate executors
|
|
53
|
+
3. **Set thresholds** — Translate SLAs (p95, error rate) into threshold expressions
|
|
54
|
+
4. **Generate k6 script** — Produce `.js` file with `export default function`, HTTP calls, checks, groups
|
|
55
|
+
5. **Configure output** — JSON, CSV, InfluxDB, Prometheus, or CI-friendly summary
|
|
56
|
+
|
|
57
|
+
## Context7 MCP
|
|
58
|
+
|
|
59
|
+
Use **Context7 MCP** for k6 documentation when:
|
|
60
|
+
- Scenario executor options or syntax are uncertain
|
|
61
|
+
- Threshold expressions or custom metrics need verification
|
|
62
|
+
- WebSocket, gRPC, or advanced options require clarification
|
|
63
|
+
- Output format or CI integration details are needed
|
|
64
|
+
|
|
65
|
+
## Key Patterns
|
|
66
|
+
|
|
67
|
+
| Pattern | Usage |
|
|
68
|
+
|---------|-------|
|
|
69
|
+
| `export default function(options)` | Main entry; receives `options` (env, etc.) |
|
|
70
|
+
| `http.get(url)` / `http.post(url, body)` | HTTP requests; returns response |
|
|
71
|
+
| `check(res, assertions)` | Assertions; returns boolean; does not fail test |
|
|
72
|
+
| `sleep(duration)` | Think time between actions |
|
|
73
|
+
| `group(name, fn)` | Logical grouping; metrics tagged by group |
|
|
74
|
+
| `Trend`, `Rate`, `Counter`, `Gauge` | Custom metrics |
|
|
75
|
+
| `scenarios` in options | Define executor-based scenarios |
|
|
76
|
+
|
|
77
|
+
### Threshold Examples
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
thresholds: {
|
|
81
|
+
'http_req_duration': ['p(95)<200', 'p(99)<500'],
|
|
82
|
+
'http_req_failed': ['rate<0.01'],
|
|
83
|
+
'http_reqs': ['count>1000'],
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Scenario Executors
|
|
88
|
+
|
|
89
|
+
| Executor | Use Case |
|
|
90
|
+
|----------|----------|
|
|
91
|
+
| `shared-iterations` | Fixed total iterations across all VUs |
|
|
92
|
+
| `per-vu-iterations` | Each VU runs N iterations |
|
|
93
|
+
| `constant-arrival-rate` | Fixed request rate (RPS) |
|
|
94
|
+
| `ramping-arrival-rate` | Ramping RPS (stress/spike) |
|
|
95
|
+
| `externally-controlled` | Control VUs from external source |
|
|
96
|
+
|
|
97
|
+
See `references/patterns.md` for load profiles, scenario executors, thresholds, custom metrics, groups.
|
|
98
|
+
|
|
99
|
+
## Output
|
|
100
|
+
|
|
101
|
+
- **k6 scripts** — `.js` files in `tests/` or `performance/` per project convention
|
|
102
|
+
- **CI config** — GitHub Actions workflow for `k6 run`, threshold pass/fail
|
|
103
|
+
|
|
104
|
+
## Scope
|
|
105
|
+
|
|
106
|
+
**Can do (autonomous):**
|
|
107
|
+
- Generate k6 scripts from performance plans and NFR specs
|
|
108
|
+
- Define scenarios with appropriate executors (load, stress, soak, spike)
|
|
109
|
+
- Set thresholds from SLAs (p95, p99, error rate)
|
|
110
|
+
- Add checks for status codes and response validation
|
|
111
|
+
- Use stages for ramping; custom metrics (Trend, Rate, Counter, Gauge)
|
|
112
|
+
- Support HTTP, WebSocket, gRPC
|
|
113
|
+
- Generate GitHub Actions CI workflow for k6
|
|
114
|
+
- Use Context7 MCP for k6 docs
|
|
115
|
+
|
|
116
|
+
**Cannot do (requires confirmation):**
|
|
117
|
+
- Change production service configuration
|
|
118
|
+
- Add dependencies not in package.json
|
|
119
|
+
- Override project k6 config without approval
|
|
120
|
+
- Target production without explicit consent
|
|
121
|
+
|
|
122
|
+
**Will not do (out of scope):**
|
|
123
|
+
- Execute tests (user runs `k6 run script.js`)
|
|
124
|
+
- Write E2E functional tests (use qa-playwright-ts-writer)
|
|
125
|
+
- Modify CI/CD pipelines beyond k6 integration
|
|
126
|
+
- Provision load infrastructure (k6 Cloud, etc.)
|
|
127
|
+
|
|
128
|
+
## References
|
|
129
|
+
|
|
130
|
+
- `references/patterns.md` — Load profiles, scenario executors, thresholds, custom metrics, groups
|
|
131
|
+
- `references/config.md` — options, scenarios, stages, thresholds, output formats
|
|
132
|
+
- `references/best-practices.md` — Realistic load, correlation, parameterization, CI integration
|
|
133
|
+
|
|
134
|
+
## Quality Checklist
|
|
135
|
+
|
|
136
|
+
- [ ] Scenarios match performance plan load profiles
|
|
137
|
+
- [ ] Thresholds reflect SLAs (p95, p99, error rate)
|
|
138
|
+
- [ ] Checks validate critical responses; use `threshold` for pass/fail
|
|
139
|
+
- [ ] Think time (sleep) between requests where realistic
|
|
140
|
+
- [ ] No hardcoded secrets; use `__ENV` or options
|
|
141
|
+
- [ ] Groups used for logical metric segmentation
|
|
142
|
+
- [ ] Output format suitable for CI (JSON summary or exit code)
|
|
143
|
+
- [ ] Stages/ramping match test type (stress = ramp up, soak = steady)
|
|
144
|
+
|
|
145
|
+
## Troubleshooting
|
|
146
|
+
|
|
147
|
+
| Symptom | Likely Cause | Fix |
|
|
148
|
+
|---------|--------------|-----|
|
|
149
|
+
| Thresholds fail in CI | Different baseline or env | Align thresholds with target env; use env-specific config |
|
|
150
|
+
| High `http_req_failed` | Timeouts, 5xx, or wrong assertions | Increase timeout; fix check logic; verify endpoint |
|
|
151
|
+
| VUs not ramping as expected | Wrong executor or stage config | Use `ramping-vus` or `ramping-arrival-rate` for stress |
|
|
152
|
+
| Metrics not tagged | Missing groups | Wrap logic in `group('name', () => { ... })` |
|
|
153
|
+
| Script fails to run | ES module or import error | Use `export default`; ensure k6-compatible imports |
|
|
154
|
+
| WebSocket/gRPC errors | Protocol-specific setup | Use `k6/experimental/grpc` or `k6/ws`; check Context7 docs |
|
|
155
|
+
| CI exit code 0 despite failures | Thresholds not enforced | Ensure `--threshold` or options.thresholds set; k6 exits non-zero on threshold fail |
|