@pzy560117/opentest 0.1.6 → 0.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/assets/manifest.json +3 -1
- package/assets/skills/opentest/SKILL.md +15 -75
- package/assets/skills/opentest/references/complete-testing-workflow.md +51 -0
- package/assets/skills/opentest/scripts/opentest-detect.sh +2 -0
- package/assets/skills/opentest/scripts/opentest-state.sh +6 -3
- package/assets/skills/opentest/templates/acceptance-template.md +19 -0
- package/assets/skills/opentest/templates/fixtures-template.md +52 -0
- package/assets/skills/opentest/templates/matrix-template.md +9 -2
- package/assets/skills/opentest/templates/report-template.md +18 -0
- package/assets/skills/opentest-accept/SKILL.md +12 -14
- package/assets/skills/opentest-author/SKILL.md +13 -17
- package/assets/skills/opentest-plan/SKILL.md +14 -19
- package/assets/skills/opentest-run/SKILL.md +17 -17
- package/assets/skills/opentest-verify/SKILL.md +13 -15
- package/assets/skills-zh/opentest/SKILL.md +15 -75
- package/assets/skills-zh/opentest/references/complete-testing-workflow.md +51 -0
- package/assets/skills-zh/opentest/templates/acceptance-template.md +19 -0
- package/assets/skills-zh/opentest/templates/fixtures-template.md +52 -0
- package/assets/skills-zh/opentest/templates/matrix-template.md +9 -2
- package/assets/skills-zh/opentest/templates/report-template.md +18 -0
- package/assets/skills-zh/opentest-accept/SKILL.md +12 -14
- package/assets/skills-zh/opentest-author/SKILL.md +13 -17
- package/assets/skills-zh/opentest-plan/SKILL.md +13 -18
- package/assets/skills-zh/opentest-run/SKILL.md +17 -17
- package/assets/skills-zh/opentest-verify/SKILL.md +13 -15
- package/package.json +1 -1
- package/scripts/smoke-test.js +90 -0
package/assets/manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.1.
|
|
2
|
+
"version": "0.1.8",
|
|
3
3
|
"languages": [
|
|
4
4
|
{
|
|
5
5
|
"id": "en",
|
|
@@ -62,12 +62,14 @@
|
|
|
62
62
|
"opentest/references/acceptance-evidence.md",
|
|
63
63
|
"opentest/references/codex-harness-coverage-heuristics.md",
|
|
64
64
|
"opentest/references/command-routing.md",
|
|
65
|
+
"opentest/references/complete-testing-workflow.md",
|
|
65
66
|
"opentest/references/lifecycle.md",
|
|
66
67
|
"opentest/references/matrix-format.md",
|
|
67
68
|
"opentest/references/opentest-driven-development.md",
|
|
68
69
|
"opentest/references/quality-gate.md",
|
|
69
70
|
"opentest/templates/acceptance-template.md",
|
|
70
71
|
"opentest/templates/archive-layout.md",
|
|
72
|
+
"opentest/templates/fixtures-template.md",
|
|
71
73
|
"opentest/templates/matrix-template.md",
|
|
72
74
|
"opentest/templates/plan-template.md",
|
|
73
75
|
"opentest/templates/report-template.md",
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: opentest
|
|
3
|
-
description: "OpenTest router
|
|
3
|
+
description: "OpenTest router entry: detect .opentest.yaml, initialize lifecycle state, and route to plan/author/run/accept/verify/heal/archive."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# OpenTest
|
|
6
|
+
# OpenTest
|
|
7
7
|
|
|
8
|
-
OpenTest
|
|
8
|
+
OpenTest turns change requirements into a test-evidence lifecycle before implementation work proceeds.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Required references
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
12
|
+
- `opentest/references/command-routing.md`
|
|
13
|
+
- `opentest/references/lifecycle.md`
|
|
14
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
14
15
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
Run:
|
|
16
|
+
## Bootstrap
|
|
18
17
|
|
|
19
18
|
```bash
|
|
20
19
|
OPENTEST_SEARCH_ROOTS=("." ".codex/skills" ".claude/skills" ".cursor/skills" ".opencode/skills" ".gemini/skills" ".qwen/skills" ".qoder/skills" "$HOME/.codex/skills" "$HOME/.claude/skills" "$HOME/.cursor/skills" "$HOME/.config/opencode/skills" "$HOME/.gemini/skills" "$HOME/.qwen/skills" "$HOME/.qoder/skills")
|
|
@@ -23,71 +22,12 @@ OPENTEST_GUARD="${OPENTEST_GUARD:-$(find "${OPENTEST_SEARCH_ROOTS[@]}" -path '*/
|
|
|
23
22
|
OPENTEST_DETECT="${OPENTEST_DETECT:-$(find "${OPENTEST_SEARCH_ROOTS[@]}" -path '*/opentest/scripts/opentest-detect.sh' -type f -print -quit 2>/dev/null)}"
|
|
24
23
|
```
|
|
25
24
|
|
|
26
|
-
If any script is missing, stop and ask the user to install
|
|
27
|
-
|
|
28
|
-
## Step 1: Detect State
|
|
29
|
-
|
|
30
|
-
If `docs/loop-handoff/latest.md` exists, read it first to recover the previous OpenTest phase, matrix/acceptance/report paths, blockers, and next step. The handoff is only a recovery hint; it does not replace `.opentest.yaml`.
|
|
31
|
-
|
|
32
|
-
If `.opentest.yaml` does not exist, run:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
bash "$OPENTEST_STATE" init
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Then run:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
bash "$OPENTEST_STATE" check
|
|
42
|
-
bash "$OPENTEST_DETECT" summary
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Step 2: Dispatch Phase
|
|
46
|
-
|
|
47
|
-
Read `phase`:
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
bash "$OPENTEST_STATE" get phase
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Dispatch rules:
|
|
54
|
-
|
|
55
|
-
- `archived: true`: report that OpenTest is complete.
|
|
56
|
-
- `phase: plan`: invoke `opentest-plan`.
|
|
57
|
-
- `phase: author`: invoke `opentest-author`.
|
|
58
|
-
- `phase: run`: invoke `opentest-run`.
|
|
59
|
-
- `phase: accept`: invoke `opentest-accept`.
|
|
60
|
-
- `phase: verify`: invoke `opentest-verify`.
|
|
61
|
-
- `phase: heal`: invoke `opentest-heal`.
|
|
62
|
-
- `phase: archive`: invoke `opentest-archive`.
|
|
63
|
-
|
|
64
|
-
If state conflicts with verifiable files, trust the files and repair state with `opentest-state.sh set`. If a handoff exists, also update its current phase, next step, failures, and blockers.
|
|
65
|
-
|
|
66
|
-
## OpenTest-Driven Development Usage
|
|
67
|
-
|
|
68
|
-
When the user wants test-driven development, or when the requirement includes frontend interactions, login, forms, permissions, APIs, data writes, cross-page flows, or high-risk behavior, OpenTest must run before build work:
|
|
69
|
-
|
|
70
|
-
```text
|
|
71
|
-
Requirement / OpenSuper design
|
|
72
|
-
-> opentest plan # implicit scenario mining + acceptance-to-test matrix
|
|
73
|
-
-> opentest author # test assets / natural language acceptance cases
|
|
74
|
-
-> build # implement against the matrix
|
|
75
|
-
-> opentest run # unit / integration / smoke / e2e commands
|
|
76
|
-
-> opentest accept # real page, API, or workflow acceptance
|
|
77
|
-
-> opentest verify # quality gate report
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
The `plan` phase must not merely restate requirements. It must actively inspect:
|
|
81
|
-
|
|
82
|
-
- Happy paths, failure paths, boundary inputs, empty data, permissions, network failures, duplicate submissions, concurrency, and stale state.
|
|
83
|
-
- Frontend feedback location: field-level message, form-level alert, toast, modal, inline status, or page error state.
|
|
84
|
-
- Evidence layers: unit, component, integration, contract, E2E, smoke, visual/browser acceptance, and security/review.
|
|
85
|
-
- Which evidence is required, which is not applicable, and which is a gap or risk-accepted candidate.
|
|
86
|
-
|
|
87
|
-
After implementation, `OpenSuper verify` may reference the OpenTest verification report, but it does not replace the OpenTest matrix, run records, or acceptance evidence.
|
|
88
|
-
|
|
89
|
-
## Loop Handoff Integration
|
|
25
|
+
If any script is missing, stop and ask the user to install OpenTest.
|
|
90
26
|
|
|
91
|
-
|
|
27
|
+
## Route
|
|
92
28
|
|
|
93
|
-
|
|
29
|
+
1. If `.opentest.yaml` is missing, run `bash "$OPENTEST_STATE" init`.
|
|
30
|
+
2. Run `bash "$OPENTEST_STATE" check` and `bash "$OPENTEST_DETECT" summary`.
|
|
31
|
+
3. Read `phase` with `bash "$OPENTEST_STATE" get phase`.
|
|
32
|
+
4. Dispatch to `opentest-plan`, `opentest-author`, `opentest-run`, `opentest-accept`, `opentest-verify`, `opentest-heal`, or `opentest-archive`.
|
|
33
|
+
5. Keep generated user-facing artifacts in the installed skill language.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Complete Testing Workflow
|
|
2
|
+
|
|
3
|
+
Use this reference only when the phase skill asks for detailed coverage rules.
|
|
4
|
+
|
|
5
|
+
## Default Evidence Chain
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
plan -> matrix -> fixtures -> tests -> run -> accept -> smoke -> pre-push -> verify -> archive
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Test Data
|
|
12
|
+
|
|
13
|
+
Create `docs/opentest/fixtures/` for changes that touch data, files, roles, permissions, APIs, or stateful workflows.
|
|
14
|
+
|
|
15
|
+
Required sections:
|
|
16
|
+
|
|
17
|
+
- users and roles
|
|
18
|
+
- permissions
|
|
19
|
+
- entities for valid, existing, invalid, duplicate, unauthorized, and stale states
|
|
20
|
+
- files/images when uploads, previews, or media validation exist
|
|
21
|
+
- seed command and idempotency rule
|
|
22
|
+
- teardown command and cleanup scope
|
|
23
|
+
- assertions for UI, API, DB/storage, files, and logs
|
|
24
|
+
|
|
25
|
+
## CRUD Baseline
|
|
26
|
+
|
|
27
|
+
For persisted data, APIs, forms, files, or stateful flows, include these matrix dimensions:
|
|
28
|
+
|
|
29
|
+
- create: validation, success, visibility in list/detail
|
|
30
|
+
- read/list/detail: list, search, filter, pagination, empty state, detail
|
|
31
|
+
- update: initial values, validation failure, save, read back
|
|
32
|
+
- delete: confirmation, cancel, success, post-delete absence
|
|
33
|
+
- failure/boundary: invalid, empty, duplicate, unauthorized, stale, network/API error
|
|
34
|
+
- data consistency: UI, API, DB/storage, files, logs
|
|
35
|
+
- end-to-end CRUD: create -> list -> detail -> update -> read back -> delete -> confirm absence -> teardown
|
|
36
|
+
|
|
37
|
+
If a leg is not applicable, record why in `gap/blocker`.
|
|
38
|
+
|
|
39
|
+
## Run Gates
|
|
40
|
+
|
|
41
|
+
- targeted: evidence linked to changed matrix rows
|
|
42
|
+
- fast: type, lint, unit
|
|
43
|
+
- full: project full test set
|
|
44
|
+
- ci-like: CI order
|
|
45
|
+
- pre-push: format/check, lint, type, unit, targeted integration, smoke, `git diff --check`
|
|
46
|
+
|
|
47
|
+
Default code test command is `python -m pytest`. Coverage command is `python -m pytest --cov=. --cov-report=term-missing`.
|
|
48
|
+
|
|
49
|
+
## Verify Gates
|
|
50
|
+
|
|
51
|
+
Block pass when required fixtures, seed/teardown, smoke, pre-push, coverage, CRUD, or full-chain acceptance evidence is missing for an applicable high-risk change.
|
|
@@ -39,6 +39,8 @@ summary() {
|
|
|
39
39
|
if [ -f pom.xml ]; then printf 'maven_project: present\n'; else printf 'maven_project: missing\n'; fi
|
|
40
40
|
if [ -f Cargo.toml ]; then printf 'cargo_project: present\n'; else printf 'cargo_project: missing\n'; fi
|
|
41
41
|
if [ -d tests ]; then printf 'tests_dir: present\n'; else printf 'tests_dir: missing\n'; fi
|
|
42
|
+
if [ -d docs/opentest/fixtures ]; then printf 'fixtures_dir: present\n'; else printf 'fixtures_dir: missing\n'; fi
|
|
43
|
+
if [ -f docs/opentest/fixtures/seed.md ] || [ -f docs/opentest/fixtures/seed.json ]; then printf 'seed_data: present\n'; else printf 'seed_data: missing\n'; fi
|
|
42
44
|
if [ -d docs/opentest ]; then printf 'opentest_docs: present\n'; else printf 'opentest_docs: missing\n'; fi
|
|
43
45
|
if [ -d docs/opentest/acceptance ]; then printf 'acceptance_docs: present\n'; else printf 'acceptance_docs: missing\n'; fi
|
|
44
46
|
|
|
@@ -69,7 +69,7 @@ require_state_file() {
|
|
|
69
69
|
|
|
70
70
|
validate_known_field() {
|
|
71
71
|
case "$1" in
|
|
72
|
-
workflow|phase|plan|matrix|acceptance|run_mode|run_report|test_framework|coverage_report|verification_result|verification_report|archived|created_at|updated_at)
|
|
72
|
+
workflow|phase|plan|matrix|fixtures|acceptance|run_mode|run_report|smoke_report|pre_push_report|test_framework|coverage_report|verification_result|verification_report|archived|created_at|updated_at)
|
|
73
73
|
return 0
|
|
74
74
|
;;
|
|
75
75
|
*)
|
|
@@ -110,9 +110,12 @@ workflow: standard
|
|
|
110
110
|
phase: plan
|
|
111
111
|
plan: null
|
|
112
112
|
matrix: null
|
|
113
|
+
fixtures: null
|
|
113
114
|
acceptance: null
|
|
114
115
|
run_mode: targeted
|
|
115
116
|
run_report: null
|
|
117
|
+
smoke_report: null
|
|
118
|
+
pre_push_report: null
|
|
116
119
|
test_framework: pytest
|
|
117
120
|
coverage_report: null
|
|
118
121
|
verification_result: pending
|
|
@@ -144,7 +147,7 @@ cmd_set() {
|
|
|
144
147
|
validate_enum "$value" plan author run accept verify heal archive
|
|
145
148
|
;;
|
|
146
149
|
run_mode)
|
|
147
|
-
validate_enum "$value" targeted fast full ci-like
|
|
150
|
+
validate_enum "$value" targeted fast full ci-like pre-push
|
|
148
151
|
;;
|
|
149
152
|
verification_result)
|
|
150
153
|
validate_enum "$value" pending pass fail risk-accepted
|
|
@@ -246,7 +249,7 @@ cmd_check() {
|
|
|
246
249
|
|
|
247
250
|
validate_enum "$workflow" standard
|
|
248
251
|
validate_enum "$phase" plan author run accept verify heal archive
|
|
249
|
-
validate_enum "$run_mode" targeted fast full ci-like
|
|
252
|
+
validate_enum "$run_mode" targeted fast full ci-like pre-push
|
|
250
253
|
validate_enum "$verification_result" pending pass fail risk-accepted
|
|
251
254
|
validate_enum "$archived" true false
|
|
252
255
|
|
|
@@ -30,3 +30,22 @@
|
|
|
30
30
|
- status:
|
|
31
31
|
- notes:
|
|
32
32
|
- artifacts:
|
|
33
|
+
|
|
34
|
+
## Full CRUD Flow
|
|
35
|
+
|
|
36
|
+
Use this default full-chain case when the change touches create, read, update, delete, data writes, files, permissions, or cross-page flows.
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
create -> list -> detail -> update -> read back -> delete -> confirm absence -> teardown
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- fixture:
|
|
43
|
+
- actor/role:
|
|
44
|
+
- create assertion:
|
|
45
|
+
- list assertion:
|
|
46
|
+
- detail assertion:
|
|
47
|
+
- update assertion:
|
|
48
|
+
- read-back assertion:
|
|
49
|
+
- delete/cancel assertion:
|
|
50
|
+
- post-delete assertion:
|
|
51
|
+
- cleanup assertion:
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# OpenTest Test Data Fixtures
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Record the exact test data needed to prove every matrix item. Keep fixtures deterministic, isolated, and safe to rerun.
|
|
6
|
+
|
|
7
|
+
## users
|
|
8
|
+
|
|
9
|
+
| id | role | permissions | purpose |
|
|
10
|
+
| --- | --- | --- | --- |
|
|
11
|
+
| user-admin | admin | create/read/update/delete | CRUD happy path |
|
|
12
|
+
| user-readonly | viewer | read only | permission denial |
|
|
13
|
+
|
|
14
|
+
## roles
|
|
15
|
+
|
|
16
|
+
- admin:
|
|
17
|
+
- viewer:
|
|
18
|
+
- unauthorized:
|
|
19
|
+
|
|
20
|
+
## Entities
|
|
21
|
+
|
|
22
|
+
| id | state | fields | used by ACC IDs |
|
|
23
|
+
| --- | --- | --- | --- |
|
|
24
|
+
| entity-create-valid | valid new record | | ACC-001 |
|
|
25
|
+
| entity-existing | persisted record | | ACC-002, ACC-003, ACC-004 |
|
|
26
|
+
| entity-invalid | invalid/boundary data | | ACC-005 |
|
|
27
|
+
|
|
28
|
+
## files/images
|
|
29
|
+
|
|
30
|
+
| path | type | purpose | cleanup |
|
|
31
|
+
| --- | --- | --- | --- |
|
|
32
|
+
| docs/opentest/fixtures/files/sample-image.png | image | upload / preview / file validation | remove after test |
|
|
33
|
+
|
|
34
|
+
## Seed
|
|
35
|
+
|
|
36
|
+
- command:
|
|
37
|
+
- data source:
|
|
38
|
+
- idempotency rule:
|
|
39
|
+
|
|
40
|
+
## teardown
|
|
41
|
+
|
|
42
|
+
- command:
|
|
43
|
+
- cleanup scope:
|
|
44
|
+
- rollback notes:
|
|
45
|
+
|
|
46
|
+
## Assertions
|
|
47
|
+
|
|
48
|
+
- UI:
|
|
49
|
+
- API:
|
|
50
|
+
- DB/storage:
|
|
51
|
+
- files:
|
|
52
|
+
- logs:
|
|
@@ -2,5 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
| ID | Intent | Coverage dimension | Trigger/Input | Expected behavior | Risk | Evidence layer | Framework/command | Required evidence | Gap/blocker | Status |
|
|
4
4
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
5
|
-
| ACC-001 |
|
|
6
|
-
| ACC-002 |
|
|
5
|
+
| ACC-001 | create succeeds | create | valid fixture entity | entity is created and visible in list/detail | high | integration + acceptance | `python -m pytest` + real workflow | create evidence, UI/API/DB assertion, fixture used | none | pending |
|
|
6
|
+
| ACC-002 | read/list/detail succeeds | read/list/detail | seeded entity | list, search/filter, and detail show correct data | high | integration + acceptance | `python -m pytest` + real workflow | read/list/detail evidence and data consistency check | none | pending |
|
|
7
|
+
| ACC-003 | update succeeds | update | edited fixture entity | updated values persist after read back | high | integration + acceptance | `python -m pytest` + real workflow | update evidence and read-back assertion | none | pending |
|
|
8
|
+
| ACC-004 | delete succeeds safely | delete | existing fixture entity | confirm/cancel behavior works; deleted item disappears after confirmation | high | integration + acceptance | `python -m pytest` + real workflow | delete evidence, cancel evidence, post-delete read check | none | pending |
|
|
9
|
+
| ACC-005 | failure and boundary paths are handled | failure/boundary | invalid, empty, duplicate, unauthorized, or stale fixture data | clear feedback without corrupting data | high | unit/integration/acceptance | `python -m pytest` + acceptance | validation, permission, duplicate, stale-state evidence | none | pending |
|
|
10
|
+
| ACC-006 | data consistency holds | data consistency | create/update/delete flow | UI, API, database/storage, files, and logs agree | high | integration | project command or `python -m pytest` | consistency evidence across surfaces | none | pending |
|
|
11
|
+
| ACC-007 | end-to-end CRUD flow works | end-to-end CRUD | create -> list -> detail -> update -> read back -> delete | full user workflow completes and leaves clean state | high | E2E/acceptance | browser/API workflow | full-chain steps, screenshots/logs, cleanup evidence | none | pending |
|
|
12
|
+
| ACC-008 | smoke gate passes | smoke | app starts and core entry points open | core route/API/CRUD happy path does not crash | high | smoke | project smoke command or targeted workflow | smoke_report path | none | pending |
|
|
13
|
+
| ACC-009 | pre-push gate passes | pre-push | staged change before push | format/lint/type/unit/integration/smoke/diff checks pass or block push | high | pre-push | project command sequence | pre_push_report path | none | pending |
|
|
@@ -21,6 +21,24 @@
|
|
|
21
21
|
| ID | evidence layer | required evidence | result | gap/risk |
|
|
22
22
|
| --- | --- | --- | --- | --- |
|
|
23
23
|
|
|
24
|
+
## Test Data
|
|
25
|
+
|
|
26
|
+
- fixtures:
|
|
27
|
+
- seed:
|
|
28
|
+
- teardown:
|
|
29
|
+
- data cleanup result:
|
|
30
|
+
|
|
31
|
+
## Smoke
|
|
32
|
+
|
|
33
|
+
- smoke_report:
|
|
34
|
+
- result:
|
|
35
|
+
|
|
36
|
+
## Pre-Push
|
|
37
|
+
|
|
38
|
+
- pre_push_report:
|
|
39
|
+
- command sequence:
|
|
40
|
+
- result:
|
|
41
|
+
|
|
24
42
|
## Quality Gate
|
|
25
43
|
|
|
26
44
|
- blocking:
|
|
@@ -5,21 +5,19 @@ description: "OpenTest phase 4: execute natural language, MCP, or real workflow
|
|
|
5
5
|
|
|
6
6
|
# OpenTest Accept
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Execute required acceptance items and write PASS, FAIL, or blocked evidence back to cases and the matrix.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Required references
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
2. For frontend interactions, prefer Chrome DevTools MCP to execute real page acceptance.
|
|
16
|
-
3. For APIs or backend workflows, use existing project commands or direct API checks.
|
|
17
|
-
4. For feedback scenarios, observe the actual rendered location and shape. For example, field errors must not be recorded only as "failed"; record whether they appear below the field, at the top of the form, in a toast, in a modal, or in a page error region.
|
|
18
|
-
5. When tools, environment, or seed data are unavailable, record blocked evidence.
|
|
19
|
-
6. Update acceptance records.
|
|
20
|
-
7. If the project uses Loop Handoff, update `docs/loop-handoff/latest.md` with acceptance result, screenshot/step evidence paths, blocked evidence, and next step.
|
|
21
|
-
8. Run `bash "$OPENTEST_GUARD" accept --apply`.
|
|
12
|
+
- `opentest/references/acceptance-evidence.md`
|
|
13
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
14
|
+
- `opentest/templates/acceptance-template.md`
|
|
22
15
|
|
|
23
|
-
##
|
|
16
|
+
## Steps
|
|
24
17
|
|
|
25
|
-
|
|
18
|
+
1. Read the matrix, fixtures, and `docs/opentest/acceptance/`.
|
|
19
|
+
2. For frontend interactions, prefer Chrome DevTools MCP and observe the real rendered UI.
|
|
20
|
+
3. For API/backend workflows, use project commands or direct API checks.
|
|
21
|
+
4. For CRUD/data changes, execute the full chain from the workflow reference.
|
|
22
|
+
5. Record feedback location/shape, artifacts, blocked evidence, and matching ACC IDs.
|
|
23
|
+
6. Update acceptance records and run `bash "$OPENTEST_GUARD" accept --apply`.
|
|
@@ -1,28 +1,24 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: opentest-author
|
|
3
|
-
description: "OpenTest phase 2: create test assets and natural language acceptance cases from the matrix."
|
|
3
|
+
description: "OpenTest phase 2: create test assets, fixtures, and natural language acceptance cases from the matrix."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# OpenTest Author
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Turn the matrix into executable tests, fixtures, seed/teardown notes, and acceptance cases.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Required references
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- `opentest/references/opentest-driven-development.md`
|
|
13
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
14
|
+
- `opentest/templates/fixtures-template.md`
|
|
15
|
+
- `opentest/templates/acceptance-template.md`
|
|
13
16
|
|
|
14
17
|
## Steps
|
|
15
18
|
|
|
16
|
-
1. Read `matrix` from `.opentest.yaml`.
|
|
17
|
-
2. For
|
|
18
|
-
3.
|
|
19
|
-
4. For
|
|
20
|
-
5.
|
|
21
|
-
6.
|
|
22
|
-
7. Write the `.opentest.yaml` `acceptance` field.
|
|
23
|
-
8. If the project uses Loop Handoff, update `docs/loop-handoff/latest.md` with test assets, natural language acceptance cases, gaps/risks, and next step.
|
|
24
|
-
9. Run `bash "$OPENTEST_GUARD" author --apply`.
|
|
25
|
-
|
|
26
|
-
## Existing Skill Routing
|
|
27
|
-
|
|
28
|
-
When the matrix requires code-level test evidence, load the existing TDD guidance first. If project rules require a specific test framework, follow those rules. If no project framework is present, use pytest as the default instead of inventing a custom harness. If the current task is better proven by real acceptance than by adding test framework code, record the reason and hand it to `opentest-accept`.
|
|
19
|
+
1. Read `matrix` and `fixtures` from `.opentest.yaml`.
|
|
20
|
+
2. For code evidence, use the project framework; if none exists, Default to pytest with tests under `tests/` runnable by `python -m pytest`.
|
|
21
|
+
3. Create/update fixtures, seed, teardown, users, roles, entities, files/images, and assertion surfaces.
|
|
22
|
+
4. For CRUD/data changes, author the full acceptance flow: create -> list -> detail -> update -> read back -> delete -> confirm absence -> teardown.
|
|
23
|
+
5. Record any gap/blocker with reason and risk.
|
|
24
|
+
6. Write `.opentest.yaml` fields: `fixtures`, `acceptance`, then run `bash "$OPENTEST_GUARD" author --apply`.
|
|
@@ -1,32 +1,27 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: opentest-plan
|
|
3
|
-
description: "OpenTest phase 1: analyze the change, risks,
|
|
3
|
+
description: "OpenTest phase 1: analyze the change, risks, project facts, and create a test strategy plus acceptance-to-test matrix."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# OpenTest Plan
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Create `docs/opentest/plans/`, `docs/opentest/matrices/`, and a fixtures plan before implementation.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Required references
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- `opentest/references/codex-harness-coverage-heuristics.md`
|
|
13
|
+
- `opentest/references/matrix-format.md`
|
|
14
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
13
15
|
|
|
14
16
|
## Steps
|
|
15
17
|
|
|
16
|
-
1. Read project rules, requirements
|
|
17
|
-
2.
|
|
18
|
-
3.
|
|
19
|
-
4.
|
|
20
|
-
5.
|
|
21
|
-
6.
|
|
22
|
-
7. Write the `.opentest.yaml` `plan` and `matrix` fields.
|
|
23
|
-
8. If the project uses Loop Handoff, update `docs/loop-handoff/latest.md` with the plan path, matrix path, current phase, and next step.
|
|
24
|
-
9. Run `bash "$OPENTEST_GUARD" plan --apply`.
|
|
18
|
+
1. Read project rules, requirements/design/diff, existing commands, and detection output.
|
|
19
|
+
2. Classify risk, applicable coverage, test data, and whether code tests use an existing framework or default `pytest`.
|
|
20
|
+
3. Apply the CRUD baseline and test data requirements from the workflow reference for data-writing/API/form/file/stateful changes.
|
|
21
|
+
4. Produce a matrix with coverage dimension, framework/command, required evidence, gap/blocker, and status.
|
|
22
|
+
5. Write `.opentest.yaml` fields: `plan`, `matrix`, `fixtures`.
|
|
23
|
+
6. Update handoff if present, then run `bash "$OPENTEST_GUARD" plan --apply`.
|
|
25
24
|
|
|
26
|
-
##
|
|
25
|
+
## Gate
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Do not force all evidence into unit tests. The matrix must state which behavior is proven by unit, component, integration, contract, E2E, smoke, browser acceptance, or security review evidence.
|
|
31
|
-
|
|
32
|
-
Coverage completeness means every applicable product behavior, failure path, boundary, and risk surface has either required evidence or an explicit gap/blocker. It does not mean every task must run every possible test type.
|
|
27
|
+
Every applicable behavior, failure path, boundary, and risk surface needs evidence or a written gap/blocker. CRUD baseline and test data are default requirements unless the matrix says why they are not applicable.
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: opentest-run
|
|
3
|
-
description: "OpenTest phase 3: run project
|
|
3
|
+
description: "OpenTest phase 3: run project verification commands in targeted, fast, full, ci-like, or pre-push mode."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# OpenTest Run
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Run matrix-driven commands and write evidence reports under `docs/opentest/runs/`.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Required references
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- `targeted`: run only test commands related to the matrix.
|
|
15
|
-
- `fast`: run fast feedback commands, such as type, lint, and unit.
|
|
16
|
-
- `full`: run the project's full test command set.
|
|
17
|
-
- `ci-like`: reproduce CI verification order as closely as practical.
|
|
12
|
+
- `opentest/references/command-routing.md`
|
|
13
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
## Modes
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
- `targeted`: matrix-related commands only.
|
|
18
|
+
- `fast`: type/lint/unit feedback.
|
|
19
|
+
- `full`: full project command set.
|
|
20
|
+
- `ci-like`: reproduce CI order.
|
|
21
|
+
- `pre-push`: push gate sequence.
|
|
22
22
|
|
|
23
23
|
## Steps
|
|
24
24
|
|
|
25
|
-
1. Read `run_mode
|
|
26
|
-
2. Prefer explicit project commands
|
|
27
|
-
3.
|
|
28
|
-
4.
|
|
29
|
-
5.
|
|
30
|
-
6.
|
|
25
|
+
1. Read `run_mode`, matrix, fixtures, and required evidence.
|
|
26
|
+
2. Prefer explicit project commands; otherwise use `python -m pytest` for code-level tests.
|
|
27
|
+
3. For coverage, prefer `python -m pytest --cov=. --cov-report=term-missing`.
|
|
28
|
+
4. Smoke evidence is required unless the matrix says not applicable.
|
|
29
|
+
5. For `pre-push`, run or record format/check, lint, type, unit, targeted integration, smoke, and `git diff --check`.
|
|
30
|
+
6. Write `run_report`, plus `coverage_report`, `smoke_report`, or `pre_push_report` when produced/required.
|
|
31
31
|
7. Run `bash "$OPENTEST_GUARD" run --apply`.
|
|
@@ -5,22 +5,20 @@ description: "OpenTest phase 5: apply quality gates and generate a verification
|
|
|
5
5
|
|
|
6
6
|
# OpenTest Verify
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Apply quality gates and write `verification_report` plus `verification_result`.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Required references
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- `opentest/references/quality-gate.md`
|
|
13
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
14
|
+
- `opentest/templates/report-template.md`
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
## Steps
|
|
15
17
|
|
|
16
|
-
Organize evidence in build, type, lint, test, security, diff order.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
- High-risk behavior does not pass merely because tooling, a test framework, or seed data is missing.
|
|
24
|
-
- If code-level coverage was required and `test_framework: pytest` is active, the report must include the `python -m pytest` command result and the `coverage_report` path, or fail/block with a reason.
|
|
25
|
-
- Blocked evidence includes a blocker reason and recovery path.
|
|
26
|
-
- If product behavior fails, do not enter `heal` to patch test assets; return to implementation or requirement correction.
|
|
18
|
+
1. Organize evidence in build, type, lint, test, security, diff order.
|
|
19
|
+
2. Check every required evidence item has pass, fail, blocked, or risk-accepted.
|
|
20
|
+
3. Confirm Coverage completeness: every applicable coverage dimension has evidence or a gap/blocker with recovery path.
|
|
21
|
+
4. Smoke evidence is required unless the matrix marks smoke not applicable.
|
|
22
|
+
5. pre-push evidence is required before push/publish unless the user explicitly skips it and risk is recorded.
|
|
23
|
+
6. For CRUD/data changes, fixture, seed, teardown, cleanup, and `coverage_report` evidence are required when applicable.
|
|
24
|
+
7. High-risk behavior must not pass because tooling, fixture, seed data, or framework is missing.
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: opentest
|
|
3
|
-
description: "OpenTest 路由入口。自动检测 .opentest.yaml
|
|
3
|
+
description: "OpenTest 路由入口。自动检测 .opentest.yaml、初始化生命周期状态,并分发到 plan/author/run/accept/verify/heal/archive。"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# OpenTest
|
|
6
|
+
# OpenTest
|
|
7
7
|
|
|
8
|
-
OpenTest
|
|
8
|
+
OpenTest 在实现前把需求转成测试证据生命周期。
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## 必读引用
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
12
|
+
- `opentest/references/command-routing.md`
|
|
13
|
+
- `opentest/references/lifecycle.md`
|
|
14
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
14
15
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
运行:
|
|
16
|
+
## 启动
|
|
18
17
|
|
|
19
18
|
```bash
|
|
20
19
|
OPENTEST_SEARCH_ROOTS=("." ".codex/skills" ".claude/skills" ".cursor/skills" ".opencode/skills" ".gemini/skills" ".qwen/skills" ".qoder/skills" "$HOME/.codex/skills" "$HOME/.claude/skills" "$HOME/.cursor/skills" "$HOME/.config/opencode/skills" "$HOME/.gemini/skills" "$HOME/.qwen/skills" "$HOME/.qoder/skills")
|
|
@@ -23,71 +22,12 @@ OPENTEST_GUARD="${OPENTEST_GUARD:-$(find "${OPENTEST_SEARCH_ROOTS[@]}" -path '*/
|
|
|
23
22
|
OPENTEST_DETECT="${OPENTEST_DETECT:-$(find "${OPENTEST_SEARCH_ROOTS[@]}" -path '*/opentest/scripts/opentest-detect.sh' -type f -print -quit 2>/dev/null)}"
|
|
24
23
|
```
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
## 第 1 步:状态检测
|
|
29
|
-
|
|
30
|
-
如果存在 `docs/loop-handoff/latest.md`,先读取 handoff,确认上次 OpenTest 阶段、矩阵/验收/报告路径、阻塞项和下一步。handoff 只作为恢复线索,不替代 `.opentest.yaml`。
|
|
31
|
-
|
|
32
|
-
如果 `.opentest.yaml` 不存在,运行:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
bash "$OPENTEST_STATE" init
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
然后运行:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
bash "$OPENTEST_STATE" check
|
|
42
|
-
bash "$OPENTEST_DETECT" summary
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## 第 2 步:阶段分发
|
|
46
|
-
|
|
47
|
-
读取 `phase`:
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
bash "$OPENTEST_STATE" get phase
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
分发规则:
|
|
54
|
-
|
|
55
|
-
- `archived: true`:报告 OpenTest 已完成。
|
|
56
|
-
- `phase: plan`:调用 `opentest-plan`。
|
|
57
|
-
- `phase: author`:调用 `opentest-author`。
|
|
58
|
-
- `phase: run`:调用 `opentest-run`。
|
|
59
|
-
- `phase: accept`:调用 `opentest-accept`。
|
|
60
|
-
- `phase: verify`:调用 `opentest-verify`。
|
|
61
|
-
- `phase: heal`:调用 `opentest-heal`。
|
|
62
|
-
- `phase: archive`:调用 `opentest-archive`。
|
|
63
|
-
|
|
64
|
-
若状态与可验证文件冲突,以文件状态为准,并用 `opentest-state.sh set` 修正;如存在 handoff,也同步更新 handoff 的“当前阶段/下一步/失败阻塞”。
|
|
65
|
-
|
|
66
|
-
## OpenTest-Driven Development 用法
|
|
67
|
-
|
|
68
|
-
当用户想“以测试驱动开发”,或需求包含前端交互、登录、表单、权限、API、数据写入、跨页面流程或高风险行为时,OpenTest 必须前置到 build 之前:
|
|
69
|
-
|
|
70
|
-
```text
|
|
71
|
-
需求 / OpenSuper design
|
|
72
|
-
-> opentest plan # 隐性场景挖掘 + acceptance-to-test matrix
|
|
73
|
-
-> opentest author # 测试资产 / 自然语言验收用例
|
|
74
|
-
-> build # 按矩阵实现
|
|
75
|
-
-> opentest run # unit / integration / smoke / e2e 命令
|
|
76
|
-
-> opentest accept # 真实页面、API 或链路验收
|
|
77
|
-
-> opentest verify # 质量门报告
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
`plan` 阶段不能只复述需求。它必须主动检查:
|
|
81
|
-
|
|
82
|
-
- 主路径、失败路径、边界输入、空数据、权限、网络、重复提交、并发或过期状态。
|
|
83
|
-
- 前端反馈位置:字段下方、表单顶部、轻提示、模态框、行内状态、页面错误态。
|
|
84
|
-
- 证据分层:unit、component、integration、contract、E2E、smoke、visual/browser acceptance、security/review。
|
|
85
|
-
- 哪些证据是必需,哪些是不适用,哪些是 gap 或 risk-accepted 候选。
|
|
86
|
-
|
|
87
|
-
实现完成后,`OpenSuper verify` 可以引用 OpenTest 的 verification report,但不能替代 OpenTest 的矩阵、运行记录和验收证据。
|
|
88
|
-
|
|
89
|
-
## Loop Handoff 衔接
|
|
25
|
+
任一脚本缺失时停止,并提示安装 OpenTest。
|
|
90
26
|
|
|
91
|
-
|
|
27
|
+
## 分发
|
|
92
28
|
|
|
93
|
-
|
|
29
|
+
1. 若 `.opentest.yaml` 不存在,运行 `bash "$OPENTEST_STATE" init`。
|
|
30
|
+
2. 运行 `bash "$OPENTEST_STATE" check` 和 `bash "$OPENTEST_DETECT" summary`。
|
|
31
|
+
3. 用 `bash "$OPENTEST_STATE" get phase` 读取阶段。
|
|
32
|
+
4. 分发到 `opentest-plan`、`opentest-author`、`opentest-run`、`opentest-accept`、`opentest-verify`、`opentest-heal` 或 `opentest-archive`。
|
|
33
|
+
5. 面向人的产物使用已安装的 skill 语言。
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# 完整测试工作流
|
|
2
|
+
|
|
3
|
+
只有当阶段 skill 要求读取详细覆盖规则时,才加载本引用。
|
|
4
|
+
|
|
5
|
+
## 默认证据链
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
plan -> matrix -> fixtures -> tests -> run -> accept -> smoke -> pre-push -> verify -> archive
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 测试数据
|
|
12
|
+
|
|
13
|
+
变更涉及数据、文件、角色、权限、API 或有状态流程时,创建 `docs/opentest/fixtures/`。
|
|
14
|
+
|
|
15
|
+
必需内容:
|
|
16
|
+
|
|
17
|
+
- 用户和角色
|
|
18
|
+
- 权限
|
|
19
|
+
- 有效、已存在、非法、重复、无权限、过期状态的实体
|
|
20
|
+
- 涉及上传、预览或媒体校验时的文件/图片
|
|
21
|
+
- seed 命令和幂等规则
|
|
22
|
+
- teardown 命令和清理范围
|
|
23
|
+
- UI、API、DB/存储、文件、日志断言
|
|
24
|
+
|
|
25
|
+
## CRUD 基线
|
|
26
|
+
|
|
27
|
+
涉及持久化数据、API、表单、文件或有状态流程时,矩阵包含:
|
|
28
|
+
|
|
29
|
+
- 新增:校验、成功、列表/详情可见
|
|
30
|
+
- 查询/列表/详情:列表、搜索、筛选、分页、空态、详情
|
|
31
|
+
- 修改:初始回显、校验失败、保存、回读
|
|
32
|
+
- 删除:确认、取消、成功、删除后不可见
|
|
33
|
+
- 失败/边界:非法、空、重复、无权限、过期、网络/API 错误
|
|
34
|
+
- 数据一致性:UI、API、DB/存储、文件、日志
|
|
35
|
+
- 端到端 CRUD:新增 -> 列表 -> 详情 -> 修改 -> 回读 -> 删除 -> 确认消失 -> 清理
|
|
36
|
+
|
|
37
|
+
不适用的环节必须在 `缺口/阻塞` 中写明原因。
|
|
38
|
+
|
|
39
|
+
## 运行质量门
|
|
40
|
+
|
|
41
|
+
- targeted:与变更矩阵行相关的证据
|
|
42
|
+
- fast:type、lint、unit
|
|
43
|
+
- full:项目完整测试集
|
|
44
|
+
- ci-like:CI 顺序
|
|
45
|
+
- pre-push:format/check、lint、type、unit、targeted integration、smoke、`git diff --check`
|
|
46
|
+
|
|
47
|
+
默认代码测试命令是 `python -m pytest`。覆盖率命令是 `python -m pytest --cov=. --cov-report=term-missing`。
|
|
48
|
+
|
|
49
|
+
## Verify 质量门
|
|
50
|
+
|
|
51
|
+
适用的高风险变更缺少必需 fixtures、seed/teardown、冒烟、pre-push、覆盖率、CRUD 或全链路验收证据时,不允许通过。
|
|
@@ -30,3 +30,22 @@
|
|
|
30
30
|
- status:
|
|
31
31
|
- 备注:
|
|
32
32
|
- 产物:
|
|
33
|
+
|
|
34
|
+
## 完整 CRUD 链路
|
|
35
|
+
|
|
36
|
+
当变更涉及新增、查询、修改、删除、数据写入、文件、权限或跨页面流程时,默认补这个全链路用例。
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
新增 -> 列表 -> 详情 -> 修改 -> 回读 -> 删除 -> 确认消失 -> 清理
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- fixture:
|
|
43
|
+
- 执行角色:
|
|
44
|
+
- 新增断言:
|
|
45
|
+
- 列表断言:
|
|
46
|
+
- 详情断言:
|
|
47
|
+
- 修改断言:
|
|
48
|
+
- 回读断言:
|
|
49
|
+
- 删除/取消断言:
|
|
50
|
+
- 删除后断言:
|
|
51
|
+
- 清理断言:
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# OpenTest 测试数据 Fixtures
|
|
2
|
+
|
|
3
|
+
## 目的
|
|
4
|
+
|
|
5
|
+
记录每个矩阵项需要的测试数据。测试数据必须确定、隔离、可重复执行。
|
|
6
|
+
|
|
7
|
+
## 用户
|
|
8
|
+
|
|
9
|
+
| id | 角色 | 权限 | 用途 |
|
|
10
|
+
| --- | --- | --- | --- |
|
|
11
|
+
| user-admin | admin | 新增/查询/修改/删除 | CRUD 主路径 |
|
|
12
|
+
| user-readonly | viewer | 只读 | 权限拒绝 |
|
|
13
|
+
|
|
14
|
+
## 角色
|
|
15
|
+
|
|
16
|
+
- admin:
|
|
17
|
+
- viewer:
|
|
18
|
+
- unauthorized:
|
|
19
|
+
|
|
20
|
+
## 实体
|
|
21
|
+
|
|
22
|
+
| id | 状态 | 字段 | 对应 ACC |
|
|
23
|
+
| --- | --- | --- | --- |
|
|
24
|
+
| entity-create-valid | 有效新记录 | | ACC-001 |
|
|
25
|
+
| entity-existing | 已存在记录 | | ACC-002, ACC-003, ACC-004 |
|
|
26
|
+
| entity-invalid | 非法/边界数据 | | ACC-005 |
|
|
27
|
+
|
|
28
|
+
## 文件/图片
|
|
29
|
+
|
|
30
|
+
| 路径 | 类型 | 用途 | 清理 |
|
|
31
|
+
| --- | --- | --- | --- |
|
|
32
|
+
| docs/opentest/fixtures/files/sample-image.png | 图片 | 上传/预览/文件校验 | 测试后删除 |
|
|
33
|
+
|
|
34
|
+
## Seed
|
|
35
|
+
|
|
36
|
+
- 命令:
|
|
37
|
+
- 数据来源:
|
|
38
|
+
- 幂等规则:
|
|
39
|
+
|
|
40
|
+
## Teardown
|
|
41
|
+
|
|
42
|
+
- 命令:
|
|
43
|
+
- 清理范围:
|
|
44
|
+
- 回滚说明:
|
|
45
|
+
|
|
46
|
+
## 断言
|
|
47
|
+
|
|
48
|
+
- UI:
|
|
49
|
+
- API:
|
|
50
|
+
- DB/存储:
|
|
51
|
+
- 文件:
|
|
52
|
+
- 日志:
|
|
@@ -2,5 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
| ID | 意图 | 覆盖维度 | 触发/输入 | 期望行为 | 风险 | 证据层级 | 框架/命令 | 必需证据 | 缺口/阻塞 | 状态 |
|
|
4
4
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
5
|
-
| ACC-001 |
|
|
6
|
-
| ACC-002 |
|
|
5
|
+
| ACC-001 | 新增成功 | 新增 | 有效 fixture 实体 | 创建成功,并能在列表/详情中看到 | high | integration + acceptance | `python -m pytest` + 真实工作流 | 新增证据、UI/API/DB 断言、使用的测试数据 | 无 | pending |
|
|
6
|
+
| ACC-002 | 查询/列表/详情成功 | 查询/列表/详情 | 已 seed 的实体 | 列表、搜索/筛选、详情显示正确数据 | high | integration + acceptance | `python -m pytest` + 真实工作流 | 查询/列表/详情证据和数据一致性检查 | 无 | pending |
|
|
7
|
+
| ACC-003 | 修改成功 | 修改 | 编辑 fixture 实体 | 保存后回读仍是新值 | high | integration + acceptance | `python -m pytest` + 真实工作流 | 修改证据和回读断言 | 无 | pending |
|
|
8
|
+
| ACC-004 | 删除安全成功 | 删除 | 已存在 fixture 实体 | 删除确认/取消正确;确认删除后不可见 | high | integration + acceptance | `python -m pytest` + 真实工作流 | 删除证据、取消证据、删除后回读检查 | 无 | pending |
|
|
9
|
+
| ACC-005 | 失败/边界路径可控 | 失败/边界 | 非法、空、重复、无权限或过期 fixture 数据 | 给出清晰反馈且不污染数据 | high | unit/integration/acceptance | `python -m pytest` + 验收 | 校验、权限、重复提交、过期状态证据 | 无 | pending |
|
|
10
|
+
| ACC-006 | 数据一致性成立 | 数据一致性 | 新增/修改/删除闭环 | UI、API、数据库/存储、文件和日志一致 | high | integration | 项目命令或 `python -m pytest` | 跨界面一致性证据 | 无 | pending |
|
|
11
|
+
| ACC-007 | 端到端 CRUD 链路可用 | 端到端 CRUD | 新增 -> 列表 -> 详情 -> 修改 -> 回读 -> 删除 | 完整用户链路通过并留下干净状态 | high | E2E/acceptance | 浏览器/API 工作流 | 全链路步骤、截图/日志、清理证据 | 无 | pending |
|
|
12
|
+
| ACC-008 | 冒烟质量门通过 | 冒烟 | 应用启动且核心入口可访问 | 核心路由/API/CRUD 主路径不崩 | high | smoke | 项目冒烟命令或 targeted workflow | smoke_report 路径 | 无 | pending |
|
|
13
|
+
| ACC-009 | pre-push 质量门通过 | pre-push | push 前 staged change | format/lint/type/unit/integration/smoke/diff 检查通过,否则阻止 push | high | pre-push | 项目命令序列 | pre_push_report 路径 | 无 | pending |
|
|
@@ -21,6 +21,24 @@
|
|
|
21
21
|
| ID | 证据层级 | 必需证据 | result | 缺口/风险 |
|
|
22
22
|
| --- | --- | --- | --- | --- |
|
|
23
23
|
|
|
24
|
+
## 测试数据
|
|
25
|
+
|
|
26
|
+
- fixtures:
|
|
27
|
+
- seed:
|
|
28
|
+
- teardown:
|
|
29
|
+
- 数据清理结果:
|
|
30
|
+
|
|
31
|
+
## 冒烟
|
|
32
|
+
|
|
33
|
+
- smoke_report:
|
|
34
|
+
- result:
|
|
35
|
+
|
|
36
|
+
## Pre-Push
|
|
37
|
+
|
|
38
|
+
- pre_push_report:
|
|
39
|
+
- 命令序列:
|
|
40
|
+
- result:
|
|
41
|
+
|
|
24
42
|
## 质量门
|
|
25
43
|
|
|
26
44
|
- 阻塞项:
|
|
@@ -5,21 +5,19 @@ description: "OpenTest 阶段 4:执行自然语言验收、MCP 验收或真实
|
|
|
5
5
|
|
|
6
6
|
# OpenTest Accept
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
执行必需验收项,并把 PASS、FAIL 或 blocked evidence 回写到用例和矩阵。
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## 必读引用
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
2. 对前端交互,优先用 Chrome DevTools MCP 执行真实页面验收。
|
|
16
|
-
3. 对 API 或后台链路,使用项目已有命令或直接 API 检查。
|
|
17
|
-
4. 对反馈类场景,必须观察实际呈现位置和形态;例如字段错误不能只记录“失败”,要记录是否在字段下方、表单顶部、轻提示、模态框或页面错误区显示。
|
|
18
|
-
5. 工具、环境或前置数据不可用时,记录 blocked evidence。
|
|
19
|
-
6. 更新验收记录。
|
|
20
|
-
7. 更新 `docs/loop-handoff/latest.md`(如果项目使用 Loop Handoff),记录验收结果、截图/步骤证据路径、blocked evidence 和下一步。
|
|
21
|
-
8. 运行 `bash "$OPENTEST_GUARD" accept --apply`。
|
|
12
|
+
- `opentest/references/acceptance-evidence.md`
|
|
13
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
14
|
+
- `opentest/templates/acceptance-template.md`
|
|
22
15
|
|
|
23
|
-
##
|
|
16
|
+
## 步骤
|
|
24
17
|
|
|
25
|
-
|
|
18
|
+
1. 读取矩阵、fixtures 和 `docs/opentest/acceptance/`。
|
|
19
|
+
2. 前端交互优先用 Chrome DevTools MCP 执行真实页面验收。
|
|
20
|
+
3. API/后台链路使用项目命令或直接 API 检查。
|
|
21
|
+
4. CRUD/数据变更执行 workflow 引用中的完整链路。
|
|
22
|
+
5. 记录反馈位置/形态、产物、blocked evidence 和对应 ACC ID。
|
|
23
|
+
6. 更新验收记录并运行 `bash "$OPENTEST_GUARD" accept --apply`。
|
|
@@ -1,28 +1,24 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: opentest-author
|
|
3
|
-
description: "OpenTest 阶段 2
|
|
3
|
+
description: "OpenTest 阶段 2:根据矩阵补齐测试资产、fixtures 和自然语言验收用例。"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# OpenTest Author
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
把矩阵转成可执行测试、fixtures、seed/teardown 说明和验收用例。
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## 必读引用
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- `opentest/references/opentest-driven-development.md`
|
|
13
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
14
|
+
- `opentest/templates/fixtures-template.md`
|
|
15
|
+
- `opentest/templates/acceptance-template.md`
|
|
13
16
|
|
|
14
17
|
## 步骤
|
|
15
18
|
|
|
16
|
-
1. 读取 `.opentest.yaml`
|
|
17
|
-
2.
|
|
18
|
-
3.
|
|
19
|
-
4.
|
|
20
|
-
5.
|
|
21
|
-
6.
|
|
22
|
-
7. 写入 `.opentest.yaml` 的 `acceptance` 字段。
|
|
23
|
-
8. 更新 `docs/loop-handoff/latest.md`(如果项目使用 Loop Handoff),记录测试资产、自然语言验收用例、gap/risk 和下一步。
|
|
24
|
-
9. 运行 `bash "$OPENTEST_GUARD" author --apply`。
|
|
25
|
-
|
|
26
|
-
## 现有技能路由
|
|
27
|
-
|
|
28
|
-
当矩阵要求代码级测试证据时,优先加载现有 TDD guidance。若项目规则要求特定测试框架,遵循项目规则。若项目没有测试框架,默认使用 pytest,不临时发明自定义测试壳。若当前任务更适合真实验收而不是新增测试框架代码,记录原因并交给 `opentest-accept`。
|
|
19
|
+
1. 读取 `.opentest.yaml` 的 `matrix` 和 `fixtures`。
|
|
20
|
+
2. 代码级证据优先用项目框架;没有框架时默认使用 pytest,测试放入 `tests/` 并可用 `python -m pytest` 运行。
|
|
21
|
+
3. 创建/更新 fixtures、seed、teardown、用户、角色、实体、文件/图片和断言界面。
|
|
22
|
+
4. CRUD/数据变更必须补全链路:新增 -> 列表 -> 详情 -> 修改 -> 回读 -> 删除 -> 确认消失 -> 清理。
|
|
23
|
+
5. 记录 gap/blocker 的原因和风险。
|
|
24
|
+
6. 写入 `.opentest.yaml` 的 `fixtures`、`acceptance`,再运行 `bash "$OPENTEST_GUARD" author --apply`。
|
|
@@ -5,28 +5,23 @@ description: "OpenTest 阶段 1:分析变更、风险和项目事实,生成
|
|
|
5
5
|
|
|
6
6
|
# OpenTest Plan
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
在实现前生成 `docs/opentest/plans/`、`docs/opentest/matrices/` 和测试数据计划。
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## 必读引用
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- `opentest/references/codex-harness-coverage-heuristics.md`
|
|
13
|
+
- `opentest/references/matrix-format.md`
|
|
14
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
13
15
|
|
|
14
16
|
## 步骤
|
|
15
17
|
|
|
16
|
-
1.
|
|
17
|
-
2.
|
|
18
|
-
3.
|
|
19
|
-
4.
|
|
20
|
-
5.
|
|
21
|
-
6.
|
|
22
|
-
7. 写入 `.opentest.yaml` 的 `plan` 和 `matrix` 字段。
|
|
23
|
-
8. 更新 `docs/loop-handoff/latest.md`(如果项目使用 Loop Handoff),记录 plan、matrix 路径、当前阶段和下一步。
|
|
24
|
-
9. 运行 `bash "$OPENTEST_GUARD" plan --apply`。
|
|
18
|
+
1. 读取项目规则、需求/设计/diff、现有命令和 detect 输出。
|
|
19
|
+
2. 判断风险、适用覆盖面、测试数据,以及代码测试使用项目框架还是默认 `pytest`。
|
|
20
|
+
3. 数据写入、API、表单、文件或有状态流程默认套用 CRUD 基线和测试数据要求。
|
|
21
|
+
4. 生成矩阵,包含覆盖维度、框架/命令、必需证据、缺口/阻塞和状态。
|
|
22
|
+
5. 写入 `.opentest.yaml` 的 `plan`、`matrix`、`fixtures`。
|
|
23
|
+
6. 如存在 handoff,同步 plan/matrix/fixtures 路径,然后运行 `bash "$OPENTEST_GUARD" plan --apply`。
|
|
25
24
|
|
|
26
|
-
##
|
|
25
|
+
## 质量门
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
不要把所有证据都写成 unit test。矩阵要明确哪些用 unit/component/integration/contract/E2E/smoke/browser acceptance/security review 证明。
|
|
31
|
-
|
|
32
|
-
覆盖完整性指每个适用的产品行为、失败路径、边界和风险面都有必需证据,或有明确的 gap/blocker;不是要求每次任务都跑所有测试类型。
|
|
27
|
+
每个适用行为、失败路径、边界和风险面都要有证据或明确 gap/blocker。CRUD 基线和测试数据默认必需;不适用时必须在矩阵写明原因。
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: opentest-run
|
|
3
|
-
description: "OpenTest 阶段 3:按 targeted、fast、full 或
|
|
3
|
+
description: "OpenTest 阶段 3:按 targeted、fast、full、ci-like 或 pre-push 模式运行项目测试命令。"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# OpenTest Run
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
运行矩阵驱动的命令,并把证据写到 `docs/opentest/runs/`。
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## 必读引用
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- `targeted`:只运行与矩阵相关的测试命令。
|
|
15
|
-
- `fast`:运行快速反馈命令,例如 type、lint、unit。
|
|
16
|
-
- `full`:运行项目完整测试命令。
|
|
17
|
-
- `ci-like`:尽量复现 CI 验证顺序。
|
|
12
|
+
- `opentest/references/command-routing.md`
|
|
13
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
## 模式
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
- `targeted`:只跑矩阵相关命令。
|
|
18
|
+
- `fast`:type/lint/unit 快速反馈。
|
|
19
|
+
- `full`:项目完整命令集。
|
|
20
|
+
- `ci-like`:尽量复现 CI 顺序。
|
|
21
|
+
- `pre-push`:push 质量门。
|
|
22
22
|
|
|
23
23
|
## 步骤
|
|
24
24
|
|
|
25
|
-
1. 读取
|
|
26
|
-
2.
|
|
27
|
-
3.
|
|
28
|
-
4.
|
|
29
|
-
5.
|
|
30
|
-
6.
|
|
25
|
+
1. 读取 `run_mode`、矩阵、fixtures 和必需证据。
|
|
26
|
+
2. 优先使用项目命令;没有代码级命令时用 `python -m pytest`。
|
|
27
|
+
3. 覆盖率优先用 `python -m pytest --cov=. --cov-report=term-missing`。
|
|
28
|
+
4. 除非矩阵写明不适用,否则必须有冒烟证据。
|
|
29
|
+
5. `pre-push` 运行或记录 format/check、lint、type、unit、targeted integration、smoke、`git diff --check`。
|
|
30
|
+
6. 写入 `run_report`,必要时写入 `coverage_report`、`smoke_report`、`pre_push_report`。
|
|
31
31
|
7. 运行 `bash "$OPENTEST_GUARD" run --apply`。
|
|
@@ -5,22 +5,20 @@ description: "OpenTest 阶段 5:应用质量门并生成验证报告。"
|
|
|
5
5
|
|
|
6
6
|
# OpenTest Verify
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
应用质量门,并写入 `verification_report` 与 `verification_result`。
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## 必读引用
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- `opentest/references/quality-gate.md`
|
|
13
|
+
- `opentest/references/complete-testing-workflow.md`
|
|
14
|
+
- `opentest/templates/report-template.md`
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
## 步骤
|
|
15
17
|
|
|
16
|
-
按 build、type、lint、test、security、diff
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- 高风险行为不能因为没有工具、没有测试框架或没有 seed data 就直接通过。
|
|
24
|
-
- 如果要求代码级覆盖率且 `test_framework: pytest` 生效,报告必须包含 `python -m pytest` 命令结果和 `coverage_report` 路径;否则必须 fail/block 并写明原因。
|
|
25
|
-
- blocked evidence 必须包含阻塞原因和后续恢复路径。
|
|
26
|
-
- 若产品行为失败,不进入 `heal` 修测试资产;应返回实现或需求修正。
|
|
18
|
+
1. 按 build、type、lint、test、security、diff 组织证据。
|
|
19
|
+
2. 每个 required evidence 必须有 pass、fail、blocked 或 risk-accepted。
|
|
20
|
+
3. 检查覆盖完整性:每个适用覆盖维度都有证据,或有带恢复路径的 gap/blocker。
|
|
21
|
+
4. 除非矩阵标记不适用,否则必须有冒烟证据。
|
|
22
|
+
5. push/publish 前必须有 pre-push 证据;用户明确跳过时要记录风险。
|
|
23
|
+
6. CRUD/数据变更按适用性要求测试数据、fixture、seed、teardown、清理和 `coverage_report` 证据。
|
|
24
|
+
7. 不能因为缺工具、fixture、seed data 或测试框架就让高风险行为通过。
|
package/package.json
CHANGED
package/scripts/smoke-test.js
CHANGED
|
@@ -32,6 +32,15 @@ function assert(condition, message) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function readRequiredText(filePath, message) {
|
|
36
|
+
try {
|
|
37
|
+
return readFileSync(filePath, 'utf8');
|
|
38
|
+
} catch {
|
|
39
|
+
assert(false, message);
|
|
40
|
+
return '';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
35
44
|
function pathSegments(file) {
|
|
36
45
|
return file.split(/[\\/]+/).filter(Boolean);
|
|
37
46
|
}
|
|
@@ -183,6 +192,85 @@ function assertDefaultPytestContracts() {
|
|
|
183
192
|
assert(chineseMatrix.includes('覆盖维度') && chineseMatrix.includes('框架/命令') && chineseMatrix.includes('缺口/阻塞'), '[COVERAGE] Chinese matrix template must include coverage, command, and gap columns');
|
|
184
193
|
}
|
|
185
194
|
|
|
195
|
+
function assertCompleteTestingWorkflowContracts() {
|
|
196
|
+
const stateScript = readFileSync('assets/skills/opentest/scripts/opentest-state.sh', 'utf8');
|
|
197
|
+
const detectScript = readFileSync('assets/skills/opentest/scripts/opentest-detect.sh', 'utf8');
|
|
198
|
+
const manifestText = readFileSync('assets/manifest.json', 'utf8');
|
|
199
|
+
const englishPlan = readFileSync('assets/skills/opentest-plan/SKILL.md', 'utf8');
|
|
200
|
+
const chinesePlan = readFileSync('assets/skills-zh/opentest-plan/SKILL.md', 'utf8');
|
|
201
|
+
const englishAuthor = readFileSync('assets/skills/opentest-author/SKILL.md', 'utf8');
|
|
202
|
+
const chineseAuthor = readFileSync('assets/skills-zh/opentest-author/SKILL.md', 'utf8');
|
|
203
|
+
const englishRun = readFileSync('assets/skills/opentest-run/SKILL.md', 'utf8');
|
|
204
|
+
const chineseRun = readFileSync('assets/skills-zh/opentest-run/SKILL.md', 'utf8');
|
|
205
|
+
const englishVerify = readFileSync('assets/skills/opentest-verify/SKILL.md', 'utf8');
|
|
206
|
+
const chineseVerify = readFileSync('assets/skills-zh/opentest-verify/SKILL.md', 'utf8');
|
|
207
|
+
const englishMatrix = readFileSync('assets/skills/opentest/templates/matrix-template.md', 'utf8');
|
|
208
|
+
const chineseMatrix = readFileSync('assets/skills-zh/opentest/templates/matrix-template.md', 'utf8');
|
|
209
|
+
const englishFixture = readRequiredText('assets/skills/opentest/templates/fixtures-template.md', '[FIXTURES] missing English fixture template');
|
|
210
|
+
const chineseFixture = readRequiredText('assets/skills-zh/opentest/templates/fixtures-template.md', '[FIXTURES] missing Chinese fixture template');
|
|
211
|
+
const englishAcceptance = readFileSync('assets/skills/opentest/templates/acceptance-template.md', 'utf8');
|
|
212
|
+
const chineseAcceptance = readFileSync('assets/skills-zh/opentest/templates/acceptance-template.md', 'utf8');
|
|
213
|
+
|
|
214
|
+
assert(manifestText.includes('opentest/templates/fixtures-template.md'), '[FIXTURES] manifest must ship fixture templates');
|
|
215
|
+
assert(stateScript.includes('fixtures: null'), '[FIXTURES] state init must track fixtures');
|
|
216
|
+
assert(stateScript.includes('smoke_report: null'), '[SMOKE] state init must track smoke_report');
|
|
217
|
+
assert(stateScript.includes('pre_push_report: null'), '[PREPUSH] state init must track pre_push_report');
|
|
218
|
+
assert(stateScript.includes('fixtures|'), '[FIXTURES] state script must allow fixtures field updates');
|
|
219
|
+
assert(stateScript.includes('targeted fast full ci-like pre-push'), '[PREPUSH] state script must allow pre-push run mode');
|
|
220
|
+
assert(detectScript.includes('fixtures_dir:'), '[FIXTURES] detect summary must report fixtures_dir');
|
|
221
|
+
assert(detectScript.includes('seed_data:'), '[FIXTURES] detect summary must report seed_data');
|
|
222
|
+
|
|
223
|
+
for (const keyword of ['create', 'read/list/detail', 'update', 'delete', 'data consistency', 'smoke', 'pre-push', 'end-to-end CRUD']) {
|
|
224
|
+
assert(englishMatrix.includes(keyword), `[MATRIX] English matrix missing ${keyword}`);
|
|
225
|
+
}
|
|
226
|
+
for (const keyword of ['新增', '查询/列表/详情', '修改', '删除', '数据一致性', '冒烟', 'pre-push', '端到端 CRUD']) {
|
|
227
|
+
assert(chineseMatrix.includes(keyword), `[MATRIX] Chinese matrix missing ${keyword}`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
assert(englishFixture.includes('users') && englishFixture.includes('roles') && englishFixture.includes('files/images') && englishFixture.includes('teardown'), '[FIXTURES] English fixture template must cover users, roles, files/images, and teardown');
|
|
231
|
+
assert(chineseFixture.includes('用户') && chineseFixture.includes('角色') && chineseFixture.includes('文件/图片') && chineseFixture.includes('清理'), '[FIXTURES] Chinese fixture template must cover users, roles, files/images, and teardown');
|
|
232
|
+
assert(englishAcceptance.includes('create -> list -> detail -> update -> read back -> delete'), '[ACCEPTANCE] English acceptance template must include full CRUD flow');
|
|
233
|
+
assert(chineseAcceptance.includes('新增 -> 列表 -> 详情 -> 修改 -> 回读 -> 删除'), '[ACCEPTANCE] Chinese acceptance template must include full CRUD flow');
|
|
234
|
+
|
|
235
|
+
assert(englishPlan.includes('CRUD baseline') && englishPlan.includes('test data'), '[PLAN] English plan skill must require CRUD baseline and test data planning');
|
|
236
|
+
assert(chinesePlan.includes('CRUD 基线') && chinesePlan.includes('测试数据'), '[PLAN] Chinese plan skill must require CRUD baseline and test data planning');
|
|
237
|
+
assert(englishAuthor.includes('fixtures') && englishAuthor.includes('seed') && englishAuthor.includes('teardown'), '[AUTHOR] English author skill must require fixtures, seed, and teardown assets');
|
|
238
|
+
assert(chineseAuthor.includes('fixtures') && chineseAuthor.includes('seed') && chineseAuthor.includes('teardown'), '[AUTHOR] Chinese author skill must require fixtures, seed, and teardown assets');
|
|
239
|
+
assert(englishRun.includes('pre-push') && englishRun.includes('smoke_report') && englishRun.includes('pre_push_report'), '[RUN] English run skill must cover pre-push, smoke_report, and pre_push_report');
|
|
240
|
+
assert(chineseRun.includes('pre-push') && chineseRun.includes('smoke_report') && chineseRun.includes('pre_push_report'), '[RUN] Chinese run skill must cover pre-push, smoke_report, and pre_push_report');
|
|
241
|
+
assert(englishVerify.includes('Smoke evidence is required') && englishVerify.includes('pre-push evidence is required') && englishVerify.includes('fixture'), '[VERIFY] English verify skill must gate smoke, pre-push, and fixtures');
|
|
242
|
+
assert(chineseVerify.includes('必须有冒烟证据') && chineseVerify.includes('必须有 pre-push 证据') && chineseVerify.includes('测试数据'), '[VERIFY] Chinese verify skill must gate smoke, pre-push, and test data');
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function assertProgressiveDisclosureContracts() {
|
|
246
|
+
const stageSkillPaths = [
|
|
247
|
+
'assets/skills/opentest/SKILL.md',
|
|
248
|
+
'assets/skills/opentest-plan/SKILL.md',
|
|
249
|
+
'assets/skills/opentest-author/SKILL.md',
|
|
250
|
+
'assets/skills/opentest-run/SKILL.md',
|
|
251
|
+
'assets/skills/opentest-accept/SKILL.md',
|
|
252
|
+
'assets/skills/opentest-verify/SKILL.md',
|
|
253
|
+
'assets/skills-zh/opentest/SKILL.md',
|
|
254
|
+
'assets/skills-zh/opentest-plan/SKILL.md',
|
|
255
|
+
'assets/skills-zh/opentest-author/SKILL.md',
|
|
256
|
+
'assets/skills-zh/opentest-run/SKILL.md',
|
|
257
|
+
'assets/skills-zh/opentest-accept/SKILL.md',
|
|
258
|
+
'assets/skills-zh/opentest-verify/SKILL.md',
|
|
259
|
+
];
|
|
260
|
+
|
|
261
|
+
for (const skillPath of stageSkillPaths) {
|
|
262
|
+
const content = readFileSync(skillPath, 'utf8');
|
|
263
|
+
assert(content.length <= 1800, `[DISCLOSURE] ${skillPath} must stay concise and move detail into references`);
|
|
264
|
+
assert(
|
|
265
|
+
content.includes('Required references') || content.includes('必读引用'),
|
|
266
|
+
`[DISCLOSURE] ${skillPath} must declare required references near the top`,
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const manifestText = readFileSync('assets/manifest.json', 'utf8');
|
|
271
|
+
assert(manifestText.includes('opentest/references/complete-testing-workflow.md'), '[DISCLOSURE] manifest must ship complete testing workflow reference');
|
|
272
|
+
}
|
|
273
|
+
|
|
186
274
|
async function assertPrepublishRejectsPublishSecretTextFiles() {
|
|
187
275
|
const fixtureDir = path.join('assets', 'opentest-smoke-secret-fixtures');
|
|
188
276
|
const fixtures = [
|
|
@@ -487,6 +575,8 @@ runManifestPathRelativitySelfCheck();
|
|
|
487
575
|
assertManifestStructure();
|
|
488
576
|
assertPrepublishGateCoversManifestAssets();
|
|
489
577
|
assertDefaultPytestContracts();
|
|
578
|
+
assertCompleteTestingWorkflowContracts();
|
|
579
|
+
assertProgressiveDisclosureContracts();
|
|
490
580
|
assertOpenTestSearchRootsCoverPlatforms();
|
|
491
581
|
assertLanguageAssetContracts();
|
|
492
582
|
await assertPrepublishRejectsPublishSecretTextFiles();
|