You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(test-driver): add non-unit test design principles
Section 8 covers how universal test design principles shift for
integration, contract, security, e2e, and UI tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: plugins/test-driver/skills/test-design/SKILL.md
+34Lines changed: 34 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -174,3 +174,37 @@ assert len(users) == 3
174
174
expected_user_count =3# admin + two test users created in arrange
175
175
assertlen(users) == expected_user_count
176
176
```
177
+
178
+
## 8. Non-Unit Test Design
179
+
180
+
Sections 1-7 apply universally, but some principles shift weight when writing non-unit tests.
181
+
182
+
### Integration Tests
183
+
184
+
Relax isolation (Section 1): the point of integration tests is verifying that components work together. Use real dependencies where feasible (test database, actual HTTP client, real service wiring). Keep test independence (each test sets up its own state), but don't mock the interactions you're trying to test.
185
+
186
+
Assert on observable outcomes across boundaries: data persisted correctly, response includes data assembled from multiple components, side effects propagated through the real dependency chain. Avoid asserting on internal state of intermediate components.
187
+
188
+
### Contract Tests
189
+
190
+
Test the shape, not the content. Assert on response structure (required fields present, correct types, proper status codes, expected content-type headers, error response format). Use schema validation (jsonschema, pydantic model parsing) rather than value equality.
191
+
192
+
Contract tests should pass regardless of what data is in the system. If a contract test breaks when test data changes, it's testing values, not shape.
193
+
194
+
### Security Tests
195
+
196
+
Each test represents one attack vector. Write the test as an attacker would attempt the attack: SQL injection in a user input field, manipulated auth tokens, requests without credentials, accessing another user's resources via ID enumeration.
197
+
198
+
Assert that the attack fails gracefully: proper HTTP error code (401/403, not 500), no sensitive data leaked in error messages or response bodies, no state corruption from the malicious input.
199
+
200
+
### E2E Tests
201
+
202
+
Test user-facing workflows from entry point to final result. Minimize mocking: the value of E2E tests is proving the full stack works together. Accept slower execution as the cost of this confidence.
203
+
204
+
Focus on critical paths (authenticate, perform primary action, verify result) rather than exhaustive feature coverage. A few high-quality E2E tests covering the main workflows are worth more than dozens covering edge cases.
205
+
206
+
### UI Tests
207
+
208
+
Test what the user sees and does, not implementation details. Click buttons, fill forms, navigate between screens, verify visible outcomes (text content, element visibility, enabled/disabled state).
209
+
210
+
Use accessibility identifiers or object names for element lookup, not CSS selectors or internal widget hierarchy. If a test breaks because the widget tree changed but the user experience didn't, the test is too tightly coupled to implementation.
0 commit comments