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
refactor(workflow): relax tests/unit/ Hypothesis mandate to guidance
Replace the hard rule that tests/unit/ must use @given with guidance:
use Hypothesis for properties spanning many inputs, plain pytest for
specific behaviors or single edge cases. @pytest.mark.slow remains
mandatory on all @given-decorated tests.
Affected files: AGENTS.md, tdd/SKILL.md, implementation/SKILL.md, verify/SKILL.md
Copy file name to clipboardExpand all lines: .opencode/skills/implementation/SKILL.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -309,7 +309,7 @@ If during implementation you discover a behavior not covered by existing accepta
309
309
- Note the gap in TODO.md under `## Next`
310
310
- The PO will decide whether to add a new Example to the `.feature` file
311
311
312
-
Extra tests in `tests/unit/` are allowed freely (coverage, edge cases, etc.) — these do not need `@id` traceability. **Every test in `tests/unit/` must be a Hypothesis property test: `@given` is required, `@pytest.mark.slow` is mandatory, plain `assert` tests without `@given` are forbidden.**
312
+
Extra tests in `tests/unit/` are allowed freely (coverage, edge cases, etc.) — these do not need `@id` traceability. Use Hypothesis (`@given`) for properties that hold across many inputs; use plain pytest for specific behaviors or single edge cases. `@pytest.mark.slow` is mandatory on every `@given`-decorated test.
Copy file name to clipboardExpand all lines: .opencode/skills/tdd/SKILL.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -105,21 +105,21 @@ The correct test asserts on the return value. The wrong test breaks if you renam
105
105
106
106
Tests in `tests/features/` are generated from `@id` criteria — use plain pytest there.
107
107
108
-
Tests in `tests/unit/` cover gaps not represented by any acceptance criterion. **Every test in `tests/unit/` must be a Hypothesis property test.** No plain `assert` tests without `@given` are permitted in `tests/unit/`.
108
+
Tests in `tests/unit/` cover gaps not represented by any acceptance criterion. Any test style is valid — plain `assert` or Hypothesis `@given`. Use Hypothesis when the test covers a **property** that holds across many inputs (mathematical invariants, parsing contracts, value object constraints). Use plain pytest for specific behaviors or single edge cases discovered during refactoring.
109
109
110
110
| Situation | Location | Tool |
111
111
|---|---|---|
112
112
| Deterministic scenario from a `.feature``@id`|`tests/features/`| Plain pytest (generated) |
113
-
| Pure function needing many input combinations |`tests/unit/`| Hypothesis `@given`|
113
+
| Property holding across many input values |`tests/unit/`| Hypothesis `@given`|
114
+
| Specific behavior or single edge case |`tests/unit/`| Plain pytest |
114
115
| Stateful system with sequences of operations |`tests/unit/`| Hypothesis stateful testing |
115
116
116
117
**Never use Hypothesis for**: I/O, side effects, network calls, database writes.
117
118
118
119
### `tests/unit/` Rules
119
120
120
-
-`@given(...)` is **required** on every test — no exceptions
121
-
-`@pytest.mark.slow` is **mandatory** on every Hypothesis test
122
-
-`@example(...)` is optional but encouraged for known corner cases
121
+
-`@pytest.mark.slow` is **mandatory** on every `@given`-decorated test (Hypothesis is genuinely slow)
122
+
-`@example(...)` is optional but encouraged when using `@given` to document known corner cases
123
123
-`@pytest.mark.unit` or `@pytest.mark.integration` still required (one each)
124
124
125
125
## Markers (4 total)
@@ -147,11 +147,11 @@ When in doubt, start with `unit`. Upgrade to `integration` if the implementation
147
147
148
148
## Hypothesis Tests
149
149
150
-
Required decorator order for every `tests/unit/` test:
150
+
When using `@given` in `tests/unit/`, the required decorator order is:
151
151
152
152
```python
153
153
@pytest.mark.unit# required: exactly one of unit or integration
154
-
@pytest.mark.slow# required: mandatory on all Hypothesis tests
154
+
@pytest.mark.slow# required: mandatory on all @given tests
Copy file name to clipboardExpand all lines: .opencode/skills/verify/SKILL.md
-2Lines changed: 0 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -129,7 +129,6 @@ Read the source files changed in this feature. **Do this before running lint/sta
129
129
| Every `@id` has a mapped test | Match `@id` tags in `.feature` files to test functions | All mapped | Missing test | Write the missing test |
130
130
| No `@id` used by two functions | Check for duplicate `@id` hex in test function names | None | Duplicate found | Consolidate into Hypothesis `@given` + `@example` or escalate to PO |
131
131
| Function naming | Test names match `test_<rule_slug>_<8char_hex>`| All match | Mismatch | Rename function |
132
-
| All `tests/unit/` tests use `@given`| Read every test in `tests/unit/`; check for `@given` decorator | All have `@given`| Any test lacks `@given`| Rewrite as a Hypothesis property test |
133
132
| All Hypothesis tests have `@pytest.mark.slow`| Read every `@given`-decorated test for the `@slow` marker | All present | Any missing | Add `@pytest.mark.slow`|
134
133
135
134
#### 4g. Code Quality — any FAIL → REJECTED
@@ -225,5 +224,4 @@ OR
225
224
| Duplicate `@id` in tests | 0 |
226
225
| Empty evidence cells | 0 |
227
226
| Orphaned tests | 0 |
228
-
| Plain tests without `@given` in `tests/unit/`| 0 |
<anything>_test.py ← developer-authored extras (no @id traceability)
88
88
```
89
89
90
-
Every test in `tests/unit/`**must** be a Hypothesis property test:
91
-
-`@given(...)` is required — no plain `assert` tests without `@given`
92
-
-`@pytest.mark.slow` is mandatory on every Hypothesis test
93
-
-`@example(...)` is optional but encouraged for known corner cases
90
+
Tests in `tests/unit/` are developer-authored extras not covered by any `@id` criterion. Any test style is valid — plain `assert` or Hypothesis `@given`. Use Hypothesis when the test covers a **property** that holds across many inputs (mathematical invariants, parsing contracts, value object constraints). Use plain pytest for specific behaviors or single edge cases discovered during refactoring.
91
+
92
+
-`@pytest.mark.slow` is mandatory on every `@given`-decorated test (Hypothesis is genuinely slow)
93
+
-`@example(...)` is optional but encouraged when using `@given` to document known corner cases
94
+
- No `@id` tags — tests with `@id` belong in `tests/features/`, generated by `gen-tests`
0 commit comments