ace-test 0.6.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.
- checksums.yaml +7 -0
- data/.ace-defaults/nav/protocols/agent-sources/ace-test.yml +19 -0
- data/.ace-defaults/nav/protocols/guide-sources/ace-test.yml +19 -0
- data/.ace-defaults/nav/protocols/tmpl-sources/ace-test.yml +11 -0
- data/.ace-defaults/nav/protocols/wfi-sources/ace-test.yml +19 -0
- data/CHANGELOG.md +169 -0
- data/LICENSE +21 -0
- data/README.md +40 -0
- data/Rakefile +12 -0
- data/handbook/agents/mock.ag.md +164 -0
- data/handbook/agents/profile-tests.ag.md +132 -0
- data/handbook/agents/test.ag.md +99 -0
- data/handbook/guides/SUMMARY.md +95 -0
- data/handbook/guides/embedded-testing-guide.g.md +261 -0
- data/handbook/guides/mocking-patterns.g.md +464 -0
- data/handbook/guides/quick-reference.g.md +46 -0
- data/handbook/guides/test-driven-development-cycle/meta-documentation.md +26 -0
- data/handbook/guides/test-driven-development-cycle/ruby-application.md +18 -0
- data/handbook/guides/test-driven-development-cycle/ruby-gem.md +19 -0
- data/handbook/guides/test-driven-development-cycle/rust-cli.md +18 -0
- data/handbook/guides/test-driven-development-cycle/rust-wasm-zed.md +19 -0
- data/handbook/guides/test-driven-development-cycle/typescript-nuxt.md +18 -0
- data/handbook/guides/test-driven-development-cycle/typescript-vue.md +19 -0
- data/handbook/guides/test-layer-decision.g.md +261 -0
- data/handbook/guides/test-mocking-patterns.g.md +414 -0
- data/handbook/guides/test-organization.g.md +140 -0
- data/handbook/guides/test-performance.g.md +353 -0
- data/handbook/guides/test-responsibility-map.g.md +220 -0
- data/handbook/guides/test-review-checklist.g.md +231 -0
- data/handbook/guides/test-suite-health.g.md +337 -0
- data/handbook/guides/testable-code-patterns.g.md +315 -0
- data/handbook/guides/testing/ruby-rspec-config-examples.md +120 -0
- data/handbook/guides/testing/ruby-rspec.md +87 -0
- data/handbook/guides/testing/rust.md +52 -0
- data/handbook/guides/testing/test-maintenance.md +364 -0
- data/handbook/guides/testing/typescript-bun.md +47 -0
- data/handbook/guides/testing/vue-firebase-auth.md +546 -0
- data/handbook/guides/testing/vue-vitest.md +236 -0
- data/handbook/guides/testing-philosophy.g.md +82 -0
- data/handbook/guides/testing-strategy.g.md +151 -0
- data/handbook/guides/testing-tdd-cycle.g.md +146 -0
- data/handbook/guides/testing.g.md +170 -0
- data/handbook/skills/as-test-create-cases/SKILL.md +24 -0
- data/handbook/skills/as-test-fix/SKILL.md +26 -0
- data/handbook/skills/as-test-improve-coverage/SKILL.md +22 -0
- data/handbook/skills/as-test-optimize/SKILL.md +34 -0
- data/handbook/skills/as-test-performance-audit/SKILL.md +34 -0
- data/handbook/skills/as-test-plan/SKILL.md +34 -0
- data/handbook/skills/as-test-review/SKILL.md +34 -0
- data/handbook/skills/as-test-verify-suite/SKILL.md +45 -0
- data/handbook/templates/e2e-sandbox-checklist.template.md +289 -0
- data/handbook/templates/test-case.template.md +56 -0
- data/handbook/templates/test-performance-audit.template.md +132 -0
- data/handbook/templates/test-responsibility-map.template.md +92 -0
- data/handbook/templates/test-review-checklist.template.md +163 -0
- data/handbook/workflow-instructions/test/analyze-failures.wf.md +120 -0
- data/handbook/workflow-instructions/test/create-cases.wf.md +675 -0
- data/handbook/workflow-instructions/test/fix.wf.md +120 -0
- data/handbook/workflow-instructions/test/improve-coverage.wf.md +370 -0
- data/handbook/workflow-instructions/test/optimize.wf.md +368 -0
- data/handbook/workflow-instructions/test/performance-audit.wf.md +17 -0
- data/handbook/workflow-instructions/test/plan.wf.md +323 -0
- data/handbook/workflow-instructions/test/review.wf.md +16 -0
- data/handbook/workflow-instructions/test/verify-suite.wf.md +343 -0
- data/lib/ace/test/version.rb +7 -0
- data/lib/ace/test.rb +10 -0
- metadata +152 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc-type: guide
|
|
3
|
+
title: Test Review Checklist Guide
|
|
4
|
+
purpose: Test PR review checklist
|
|
5
|
+
ace-docs:
|
|
6
|
+
last-updated: 2026-02-19
|
|
7
|
+
last-checked: 2026-03-21
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Test Review Checklist Guide
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
|
|
14
|
+
Quick checklist for reviewing PRs that add or modify tests. Ensures tests are:
|
|
15
|
+
- At the correct layer
|
|
16
|
+
- Properly stubbed
|
|
17
|
+
- Testing behavior (not implementation)
|
|
18
|
+
- Fast enough
|
|
19
|
+
- Actually catching bugs
|
|
20
|
+
|
|
21
|
+
## The Quick Check (30 seconds)
|
|
22
|
+
|
|
23
|
+
Before deep review, check:
|
|
24
|
+
|
|
25
|
+
1. **Layer**: Is test in correct directory? (atoms/molecules/organisms/e2e)
|
|
26
|
+
2. **Speed**: Run `ace-test <package> --profile 5` - any >100ms?
|
|
27
|
+
3. **I/O**: Search for `Open3`, `system(`, `File.` in new test code
|
|
28
|
+
|
|
29
|
+
If any fail → detailed review needed.
|
|
30
|
+
|
|
31
|
+
## Detailed Checklist
|
|
32
|
+
|
|
33
|
+
### 1. Layer Appropriateness
|
|
34
|
+
|
|
35
|
+
| Check | Pass | Fail |
|
|
36
|
+
|-------|------|------|
|
|
37
|
+
| Unit tests have NO real I/O | ✓ | Subprocess, network, or filesystem calls |
|
|
38
|
+
| Integration tests stub external deps | ✓ | Real API or subprocess calls |
|
|
39
|
+
| E2E tests are in `test/e2e/TS-*/` | ✓ | E2E behavior in unit test file |
|
|
40
|
+
| No flag permutations in E2E | ✓ | Multiple E2E tests for CLI flags |
|
|
41
|
+
| Max ONE CLI parity test per integration file | ✓ | Multiple subprocess tests |
|
|
42
|
+
|
|
43
|
+
**Red Flag**: Test name says "unit" but takes >100ms
|
|
44
|
+
|
|
45
|
+
### 2. Stubbing Quality
|
|
46
|
+
|
|
47
|
+
| Check | Pass | Fail |
|
|
48
|
+
|-------|------|------|
|
|
49
|
+
| Boundary methods stubbed | ✓ `available?` stubbed | Only `run` stubbed |
|
|
50
|
+
| No zombie mocks | ✓ Stub targets exist | Stub target renamed/removed |
|
|
51
|
+
| Mock data is realistic | ✓ From snapshot/schema | Invented data |
|
|
52
|
+
| Composite helpers used | ✓ Single helper | >3 levels of nesting |
|
|
53
|
+
|
|
54
|
+
**Red Flag**: Deep nesting without composite helper
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
# BAD: 5 levels of nesting
|
|
58
|
+
mock_a do
|
|
59
|
+
mock_b do
|
|
60
|
+
mock_c do
|
|
61
|
+
mock_d do
|
|
62
|
+
test_code
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# GOOD: Composite helper
|
|
69
|
+
with_mock_context(a: x, b: y) do
|
|
70
|
+
test_code
|
|
71
|
+
end
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 3. Behavior vs Implementation
|
|
75
|
+
|
|
76
|
+
| Check | Pass | Fail |
|
|
77
|
+
|-------|------|------|
|
|
78
|
+
| Tests assert on OUTPUT | ✓ `assert_equal expected, result` | Only `mock.verify` |
|
|
79
|
+
| Tests survive refactoring | ✓ Tests behavior | Tests method names |
|
|
80
|
+
| Mock expectations only for side-effects | ✓ `Git.commit` | `Parser.parse` |
|
|
81
|
+
|
|
82
|
+
**Red Flag**: Test only has `mock.verify` without output assertions
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
# BAD: Only verifies mock was called
|
|
86
|
+
mock.expect(:process, true, [data])
|
|
87
|
+
subject.call(data)
|
|
88
|
+
mock.verify # What was the result?
|
|
89
|
+
|
|
90
|
+
# GOOD: Verifies actual behavior
|
|
91
|
+
result = subject.call(data)
|
|
92
|
+
assert_equal expected_output, result.output
|
|
93
|
+
assert result.success?
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 4. Performance
|
|
97
|
+
|
|
98
|
+
| Check | Pass | Fail |
|
|
99
|
+
|-------|------|------|
|
|
100
|
+
| Unit tests <100ms | ✓ All fast | Any >100ms |
|
|
101
|
+
| No unstubbed `sleep` | ✓ `Kernel.stub :sleep` | Real sleep in retry tests |
|
|
102
|
+
| No real subprocess | ✓ Stubbed | `Open3.capture3` without stub |
|
|
103
|
+
| Cache pre-warming if needed | ✓ In test_helper | Cache miss on every test |
|
|
104
|
+
|
|
105
|
+
**Quick Check**:
|
|
106
|
+
```bash
|
|
107
|
+
ace-test <package> --profile 10
|
|
108
|
+
# All unit tests should be <100ms
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 5. Coverage Quality
|
|
112
|
+
|
|
113
|
+
| Check | Pass | Fail |
|
|
114
|
+
|-------|------|------|
|
|
115
|
+
| Happy path tested | ✓ | Missing |
|
|
116
|
+
| Error cases tested | ✓ At least one | None |
|
|
117
|
+
| Edge cases tested | ✓ nil, empty, boundaries | Only happy path |
|
|
118
|
+
| Test actually fails when broken | ✓ Try breaking it | Always passes |
|
|
119
|
+
|
|
120
|
+
**Verification**: Temporarily break the code, test should fail.
|
|
121
|
+
|
|
122
|
+
### 6. Test Base Class Check
|
|
123
|
+
|
|
124
|
+
- [ ] All tests in `test/molecules/` inherit from `<Package>Test` base class
|
|
125
|
+
- [ ] NOT directly from `Minitest::Test`
|
|
126
|
+
|
|
127
|
+
**Red Flag**: Test using `Minitest::Test` without access to package helpers
|
|
128
|
+
|
|
129
|
+
```ruby
|
|
130
|
+
# BAD: Missing package helpers (stub_prompt_path, shared temp dir, etc.)
|
|
131
|
+
class FeedbackExtractorTest < Minitest::Test
|
|
132
|
+
# No access to stub_prompt_path, must manually stub
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# GOOD: Has access to all package test helpers
|
|
136
|
+
class FeedbackExtractorTest < AceReviewTest
|
|
137
|
+
# Can use stub_prompt_path(@extractor), shared temp dir, etc.
|
|
138
|
+
end
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 7. E2E Specific
|
|
142
|
+
|
|
143
|
+
For tests in `test/e2e/TS-*/`:
|
|
144
|
+
|
|
145
|
+
| Check | Pass | Fail |
|
|
146
|
+
|-------|------|------|
|
|
147
|
+
| Explicit PASS/FAIL assertions | ✓ `&& echo PASS \|\| echo FAIL` | Implicit success |
|
|
148
|
+
| Paths discovered at runtime | ✓ `find`, `ls` | Hardcoded paths |
|
|
149
|
+
| Error test cases included | ✓ Wrong args, missing files | Only happy path |
|
|
150
|
+
| Exit codes verified | ✓ `[ $? -eq 1 ]` | Exit code ignored |
|
|
151
|
+
| Cleanup documented | ✓ Cleanup section | No cleanup |
|
|
152
|
+
|
|
153
|
+
## Common Review Comments
|
|
154
|
+
|
|
155
|
+
### Performance Issues
|
|
156
|
+
|
|
157
|
+
> "This test takes 150ms. Please stub the availability check:
|
|
158
|
+
> ```ruby
|
|
159
|
+
> Runner.stub(:available?, true) do
|
|
160
|
+
> # existing test code
|
|
161
|
+
> end
|
|
162
|
+
> ```"
|
|
163
|
+
|
|
164
|
+
### Wrong Layer
|
|
165
|
+
|
|
166
|
+
> "This test uses real subprocess calls but is in `test/atoms/`. Either:
|
|
167
|
+
> - Stub the subprocess and keep in atoms
|
|
168
|
+
> - Move to `test/e2e/` as an E2E test"
|
|
169
|
+
|
|
170
|
+
### Implementation Testing
|
|
171
|
+
|
|
172
|
+
> "This test only verifies the mock was called. Please add assertion on the actual result:
|
|
173
|
+
> ```ruby
|
|
174
|
+
> result = subject.call(input)
|
|
175
|
+
> assert_equal expected_output, result.value
|
|
176
|
+
> ```"
|
|
177
|
+
|
|
178
|
+
### Missing Error Cases
|
|
179
|
+
|
|
180
|
+
> "Please add at least one error case test. For example:
|
|
181
|
+
> ```ruby
|
|
182
|
+
> def test_raises_on_invalid_input
|
|
183
|
+
> assert_raises(ValidationError) { subject.call(nil) }
|
|
184
|
+
> end
|
|
185
|
+
> ```"
|
|
186
|
+
|
|
187
|
+
## Quick Reference Card
|
|
188
|
+
|
|
189
|
+
### Performance Thresholds
|
|
190
|
+
|
|
191
|
+
| Layer | Target | Warning | Critical |
|
|
192
|
+
|-------|--------|---------|----------|
|
|
193
|
+
| Unit (atoms) | <10ms | >50ms | >100ms |
|
|
194
|
+
| Unit (molecules) | <50ms | >100ms | >200ms |
|
|
195
|
+
| Integration | <500ms | >1s | >2s |
|
|
196
|
+
|
|
197
|
+
### Stub the Boundary
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
# Always stub availability if stubbing execution
|
|
201
|
+
Runner.stub(:available?, true) do
|
|
202
|
+
Runner.stub(:run, result) do
|
|
203
|
+
subject.process
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Behavior Assertion Pattern
|
|
209
|
+
|
|
210
|
+
```ruby
|
|
211
|
+
# Arrange
|
|
212
|
+
input = build_test_input
|
|
213
|
+
|
|
214
|
+
# Act
|
|
215
|
+
result = subject.call(input)
|
|
216
|
+
|
|
217
|
+
# Assert (behavior, not implementation)
|
|
218
|
+
assert result.success?
|
|
219
|
+
assert_equal expected_output, result.value
|
|
220
|
+
assert_nil result.error
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Template
|
|
224
|
+
|
|
225
|
+
Use `templates/test-review-checklist.template.md` for formal PR reviews.
|
|
226
|
+
|
|
227
|
+
## See Also
|
|
228
|
+
|
|
229
|
+
- [Test Layer Decision](guide://test-layer-decision)
|
|
230
|
+
- [Test Mocking Patterns](guide://test-mocking-patterns)
|
|
231
|
+
- [Test Performance](guide://test-performance)
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc-type: guide
|
|
3
|
+
title: Test Suite Health Guide
|
|
4
|
+
purpose: Maintain healthy test suites through measurement and continuous improvement
|
|
5
|
+
ace-docs:
|
|
6
|
+
last-updated: 2026-02-22
|
|
7
|
+
last-checked: 2026-03-21
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Test Suite Health Guide
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
|
|
14
|
+
Maintain test suites that are:
|
|
15
|
+
- **Fast**: Quick feedback loop for developers
|
|
16
|
+
- **Reliable**: No flaky tests, deterministic results
|
|
17
|
+
- **Effective**: Actually catch bugs before production
|
|
18
|
+
- **Maintainable**: Easy to update as code evolves
|
|
19
|
+
|
|
20
|
+
## Health Metrics
|
|
21
|
+
|
|
22
|
+
### Performance Metrics
|
|
23
|
+
|
|
24
|
+
| Metric | Target | Warning | Critical |
|
|
25
|
+
|--------|--------|---------|----------|
|
|
26
|
+
| Unit test (atoms) | <10ms | >50ms | >100ms |
|
|
27
|
+
| Unit test (molecules) | <50ms | >100ms | >200ms |
|
|
28
|
+
| Integration test | <500ms | >1s | >2s |
|
|
29
|
+
| Full package suite | <30s | >60s | >120s |
|
|
30
|
+
| Full monorepo suite | <5min | >10min | >20min |
|
|
31
|
+
|
|
32
|
+
**Measurement**: `ace-test --profile 20`
|
|
33
|
+
|
|
34
|
+
### Reliability Metrics
|
|
35
|
+
|
|
36
|
+
| Metric | Target | Warning | Critical |
|
|
37
|
+
|--------|--------|---------|----------|
|
|
38
|
+
| Flake rate | <1% | >2% | >5% |
|
|
39
|
+
| Test determinism | 100% | <99% | <95% |
|
|
40
|
+
| CI pass rate | >98% | <95% | <90% |
|
|
41
|
+
|
|
42
|
+
**Measurement**: Track CI runs over time, re-run suspicious tests
|
|
43
|
+
|
|
44
|
+
### Effectiveness Metrics
|
|
45
|
+
|
|
46
|
+
| Metric | Target | Interpretation |
|
|
47
|
+
|--------|--------|----------------|
|
|
48
|
+
| Defect Removal Efficiency | >85% | `bugs_caught / (bugs_caught + escaped_bugs)` |
|
|
49
|
+
| Code coverage (critical paths) | >80% | Focus on business logic, not getters |
|
|
50
|
+
| Escaped defects | Trending down | Bugs found in production |
|
|
51
|
+
| Mean Time to Detect | <1 day | Time from bug introduction to test failure |
|
|
52
|
+
|
|
53
|
+
**Measurement**: Track bugs in issue tracker, label with "escaped-defect"
|
|
54
|
+
|
|
55
|
+
## Periodic Audit Schedule
|
|
56
|
+
|
|
57
|
+
### Weekly: Changed Package Review
|
|
58
|
+
|
|
59
|
+
**When**: After significant changes to a package
|
|
60
|
+
|
|
61
|
+
**Actions**:
|
|
62
|
+
1. Run `ace-test <package> --profile 10`
|
|
63
|
+
2. Check for new tests exceeding thresholds
|
|
64
|
+
3. Verify no zombie mocks introduced
|
|
65
|
+
|
|
66
|
+
**Trigger**: PR changes >100 lines in test files
|
|
67
|
+
|
|
68
|
+
### Monthly: Full Suite Audit
|
|
69
|
+
|
|
70
|
+
**When**: First week of each month
|
|
71
|
+
|
|
72
|
+
**Actions**:
|
|
73
|
+
1. Run `ace-test-suite` with profiling
|
|
74
|
+
2. Generate health report
|
|
75
|
+
3. Create tasks for issues found
|
|
76
|
+
4. Compare metrics to previous month
|
|
77
|
+
|
|
78
|
+
**Checklist**:
|
|
79
|
+
- [ ] All packages under 30s
|
|
80
|
+
- [ ] No unit test >100ms
|
|
81
|
+
- [ ] No flaky tests (run 3x)
|
|
82
|
+
- [ ] Coverage not decreased
|
|
83
|
+
|
|
84
|
+
### Quarterly: Deep Review
|
|
85
|
+
|
|
86
|
+
**When**: End of each quarter
|
|
87
|
+
|
|
88
|
+
**Actions**:
|
|
89
|
+
1. Review all E2E tests for relevance
|
|
90
|
+
2. Check mock data for API drift
|
|
91
|
+
3. Analyze escaped defects pattern
|
|
92
|
+
4. Update testing guides if needed
|
|
93
|
+
|
|
94
|
+
**Checklist**:
|
|
95
|
+
- [ ] E2E tests still match user workflows
|
|
96
|
+
- [ ] Mock snapshots updated from real APIs
|
|
97
|
+
- [ ] Escaped defects analyzed, regression tests added
|
|
98
|
+
- [ ] Guides reflect current practices
|
|
99
|
+
|
|
100
|
+
## CI Integration
|
|
101
|
+
|
|
102
|
+
### Performance Gates
|
|
103
|
+
|
|
104
|
+
Add to `.github/workflows/test.yml`:
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
- name: Run tests with profiling
|
|
108
|
+
run: |
|
|
109
|
+
ace-test --profile 20 2>&1 | tee test-profile.txt
|
|
110
|
+
|
|
111
|
+
- name: Check performance thresholds
|
|
112
|
+
run: |
|
|
113
|
+
# Extract slowest tests
|
|
114
|
+
slow_tests=$(grep -E "^\s+[0-9]+\.\s+" test-profile.txt | \
|
|
115
|
+
awk '$NF ~ /[0-9]+\.[1-9][0-9][0-9]s/ {print}')
|
|
116
|
+
|
|
117
|
+
if [ -n "$slow_tests" ]; then
|
|
118
|
+
echo "::warning::Tests exceeding 100ms threshold:"
|
|
119
|
+
echo "$slow_tests"
|
|
120
|
+
|
|
121
|
+
# Count critical violations (>200ms)
|
|
122
|
+
critical=$(echo "$slow_tests" | awk '$NF ~ /[0-9]+\.[2-9][0-9][0-9]s|[1-9]\.[0-9]+s/ {count++} END {print count+0}')
|
|
123
|
+
|
|
124
|
+
if [ "$critical" -gt 0 ]; then
|
|
125
|
+
echo "::error::$critical tests exceed 200ms critical threshold"
|
|
126
|
+
exit 1
|
|
127
|
+
fi
|
|
128
|
+
fi
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Flakiness Detection
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
- name: Run tests multiple times for flakiness
|
|
135
|
+
run: |
|
|
136
|
+
for i in 1 2 3; do
|
|
137
|
+
echo "=== Run $i ==="
|
|
138
|
+
ace-test-suite --quiet || echo "FAILED_RUN_$i"
|
|
139
|
+
done | tee runs.txt
|
|
140
|
+
|
|
141
|
+
failures=$(grep -c "FAILED_RUN" runs.txt || true)
|
|
142
|
+
if [ "$failures" -gt 0 ] && [ "$failures" -lt 3 ]; then
|
|
143
|
+
echo "::error::Flaky tests detected ($failures/3 runs failed)"
|
|
144
|
+
exit 1
|
|
145
|
+
fi
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Coverage Tracking
|
|
149
|
+
|
|
150
|
+
```yaml
|
|
151
|
+
- name: Generate coverage report
|
|
152
|
+
run: |
|
|
153
|
+
COVERAGE=true ace-test-suite
|
|
154
|
+
|
|
155
|
+
- name: Check coverage threshold
|
|
156
|
+
run: |
|
|
157
|
+
coverage=$(cat coverage/coverage.json | jq '.metrics.covered_percent')
|
|
158
|
+
if (( $(echo "$coverage < 80" | bc -l) )); then
|
|
159
|
+
echo "::error::Coverage $coverage% below 80% threshold"
|
|
160
|
+
exit 1
|
|
161
|
+
fi
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Pre-commit Hook
|
|
165
|
+
|
|
166
|
+
Add to `.git/hooks/pre-commit`:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
#!/bin/bash
|
|
170
|
+
|
|
171
|
+
# Get changed packages
|
|
172
|
+
changed_packages=$(git diff --cached --name-only | \
|
|
173
|
+
grep "^ace-" | cut -d/ -f1 | sort -u)
|
|
174
|
+
|
|
175
|
+
if [ -z "$changed_packages" ]; then
|
|
176
|
+
exit 0
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
echo "Running tests for changed packages..."
|
|
180
|
+
|
|
181
|
+
for pkg in $changed_packages; do
|
|
182
|
+
echo "Testing $pkg..."
|
|
183
|
+
|
|
184
|
+
# Run with profile, fail on slow tests
|
|
185
|
+
output=$(ace-test "$pkg" --profile 5 2>&1)
|
|
186
|
+
status=$?
|
|
187
|
+
|
|
188
|
+
if [ $status -ne 0 ]; then
|
|
189
|
+
echo "Tests failed in $pkg"
|
|
190
|
+
echo "$output"
|
|
191
|
+
exit 1
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
# Check for slow tests
|
|
195
|
+
slow=$(echo "$output" | grep -E "[0-9]+\.[1-9][0-9][0-9]s" | head -3)
|
|
196
|
+
if [ -n "$slow" ]; then
|
|
197
|
+
echo "Warning: Slow tests in $pkg:"
|
|
198
|
+
echo "$slow"
|
|
199
|
+
fi
|
|
200
|
+
done
|
|
201
|
+
|
|
202
|
+
echo "All tests passed!"
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Troubleshooting Common Issues
|
|
206
|
+
|
|
207
|
+
### Issue: Random Test Failures
|
|
208
|
+
|
|
209
|
+
**Symptoms**: Different tests fail on different runs
|
|
210
|
+
|
|
211
|
+
**Diagnosis**:
|
|
212
|
+
1. Run tests 5x, note which fail
|
|
213
|
+
2. Check for shared mutable state
|
|
214
|
+
3. Look for test order dependencies
|
|
215
|
+
|
|
216
|
+
**Common Causes**:
|
|
217
|
+
- Cache invalidation between tests
|
|
218
|
+
- Global state not reset
|
|
219
|
+
- Time-dependent assertions
|
|
220
|
+
|
|
221
|
+
**Fix**:
|
|
222
|
+
- Pre-warm caches at test startup
|
|
223
|
+
- Reset state in setup, not teardown
|
|
224
|
+
- Use time stubs
|
|
225
|
+
|
|
226
|
+
### Issue: Sudden Slowdown
|
|
227
|
+
|
|
228
|
+
**Symptoms**: Test suite time increased significantly
|
|
229
|
+
|
|
230
|
+
**Diagnosis**:
|
|
231
|
+
1. `ace-test --profile 20` before and after
|
|
232
|
+
2. Compare slow test lists
|
|
233
|
+
3. Check for removed stubs
|
|
234
|
+
|
|
235
|
+
**Common Causes**:
|
|
236
|
+
- Zombie mocks (stub no longer matches code)
|
|
237
|
+
- New tests without proper stubbing
|
|
238
|
+
- Dependency upgrade with slower behavior
|
|
239
|
+
|
|
240
|
+
**Fix**:
|
|
241
|
+
- Update stubs to match new code paths
|
|
242
|
+
- Add missing stubs
|
|
243
|
+
- Profile dependency to identify bottleneck
|
|
244
|
+
|
|
245
|
+
### Issue: Tests Pass Locally, Fail in CI
|
|
246
|
+
|
|
247
|
+
**Symptoms**: Green locally, red in CI
|
|
248
|
+
|
|
249
|
+
**Diagnosis**:
|
|
250
|
+
1. Check CI environment differences
|
|
251
|
+
2. Look for timing-sensitive tests
|
|
252
|
+
3. Check for missing test dependencies
|
|
253
|
+
|
|
254
|
+
**Common Causes**:
|
|
255
|
+
- Different tool versions
|
|
256
|
+
- Network/filesystem differences
|
|
257
|
+
- Race conditions more visible on CI
|
|
258
|
+
|
|
259
|
+
**Fix**:
|
|
260
|
+
- Pin tool versions in CI
|
|
261
|
+
- Add explicit waits or retries
|
|
262
|
+
- Use mocks for environment-dependent behavior
|
|
263
|
+
|
|
264
|
+
### Issue: High Escaped Defect Rate
|
|
265
|
+
|
|
266
|
+
**Symptoms**: Bugs reaching production despite tests
|
|
267
|
+
|
|
268
|
+
**Diagnosis**:
|
|
269
|
+
1. Analyze escaped defects by category
|
|
270
|
+
2. Check if tests exist for those paths
|
|
271
|
+
3. Review test assertions
|
|
272
|
+
|
|
273
|
+
**Common Causes**:
|
|
274
|
+
- Missing edge case coverage
|
|
275
|
+
- Tests check implementation, not behavior
|
|
276
|
+
- Integration gaps (unit tests pass, system fails)
|
|
277
|
+
|
|
278
|
+
**Fix**:
|
|
279
|
+
- Add regression tests for each escaped defect
|
|
280
|
+
- Review test assertions for completeness
|
|
281
|
+
- Add integration/E2E tests for critical paths
|
|
282
|
+
|
|
283
|
+
## Health Report Template
|
|
284
|
+
|
|
285
|
+
Generate monthly with `/ace-test-verify-suite`:
|
|
286
|
+
|
|
287
|
+
```markdown
|
|
288
|
+
# Test Suite Health Report
|
|
289
|
+
|
|
290
|
+
**Date**: YYYY-MM-DD
|
|
291
|
+
**Packages**: N packages analyzed
|
|
292
|
+
**Total Tests**: N tests
|
|
293
|
+
|
|
294
|
+
## Performance Summary
|
|
295
|
+
|
|
296
|
+
| Package | Tests | Time | Slowest Test |
|
|
297
|
+
|---------|-------|------|--------------|
|
|
298
|
+
| ace-lint | 45 | 1.2s | test_complex_validation (89ms) |
|
|
299
|
+
| ace-git | 78 | 2.1s | test_diff_generation (156ms) |
|
|
300
|
+
|
|
301
|
+
### Threshold Violations
|
|
302
|
+
- [ ] ace-git: 2 tests >100ms (warning)
|
|
303
|
+
- [x] ace-lint: All tests <100ms
|
|
304
|
+
|
|
305
|
+
## Reliability Summary
|
|
306
|
+
|
|
307
|
+
| Metric | Value | Status |
|
|
308
|
+
|--------|-------|--------|
|
|
309
|
+
| Flake rate | 0.5% | OK |
|
|
310
|
+
| CI pass rate | 99.2% | OK |
|
|
311
|
+
|
|
312
|
+
### Flaky Tests Identified
|
|
313
|
+
- None this month
|
|
314
|
+
|
|
315
|
+
## Effectiveness Summary
|
|
316
|
+
|
|
317
|
+
| Metric | Value | Trend |
|
|
318
|
+
|--------|-------|-------|
|
|
319
|
+
| Escaped defects | 2 | Down from 4 |
|
|
320
|
+
| DRE | 87% | Up from 83% |
|
|
321
|
+
|
|
322
|
+
### Escaped Defects This Month
|
|
323
|
+
1. #456 - Config parsing edge case
|
|
324
|
+
2. #461 - CLI exit code mismatch
|
|
325
|
+
|
|
326
|
+
## Action Items
|
|
327
|
+
|
|
328
|
+
1. [ ] Add regression test for #456
|
|
329
|
+
2. [ ] Investigate slow test in ace-git
|
|
330
|
+
3. [ ] Update mock data for GitHub API
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## See Also
|
|
334
|
+
|
|
335
|
+
- [Test Layer Decision](guide://test-layer-decision) - Where to test
|
|
336
|
+
- [Test Mocking Patterns](guide://test-mocking-patterns) - How to mock
|
|
337
|
+
- [Test Performance](guide://test-performance) - Optimization techniques
|