@educa-corp/sdd-framework 0.9.3 → 0.9.5
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/bin/build.js +11 -0
- package/bin/lint-trace.js +230 -2
- package/bin/qc-base-map.json +119 -49
- package/bin/self-check.js +54 -0
- package/bin/trace-schema.json +58 -4
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/generate-bdd.md +1 -0
- package/core/commands/generate-code.md +39 -2
- package/core/commands/generate-tech-docs.md +21 -2
- package/core/commands/map-testids.md +88 -8
- package/core/commands/qc-analyze.md +429 -472
- package/core/commands/qc-design-test.md +251 -207
- package/core/commands/qc-plan.md +97 -197
- package/core/commands/qc-report.md +76 -60
- package/core/commands/qc-review.md +135 -185
- package/core/commands/qc-run-test.md +235 -274
- package/core/commands/review-tech-docs.md +20 -0
- package/core/commands/setup-ai-first.md +5 -5
- package/core/commands/update-framework.md +1 -1
- package/core/commands/validate-traces.md +1 -1
- package/core/modules/qc-playwright/stack-profile.yaml +1 -1
- package/core/rules/data-protection.md +52 -0
- package/core/rules/workflow.md +1 -1
- package/core/skills/qc/_shared/self-review-principles.md +112 -0
- package/core/skills/qc/qa-analyst/DOC_GAP.template.md +1 -1
- package/core/skills/qc/qa-analyst/spec-breakdown.md +2 -2
- package/core/skills/qc/qa-designer/api/auth-chain.md +155 -0
- package/core/skills/qc/qa-designer/api/auth-sequence.md +75 -0
- package/core/skills/qc/qa-designer/api/common-headers.md +61 -0
- package/core/skills/qc/qa-designer/api/crud-sequence.md +122 -0
- package/core/skills/qc/qa-designer/api/endpoint.md +231 -0
- package/core/skills/qc/qa-designer/api/http-status-codes.md +102 -0
- package/core/skills/qc/qa-designer/e2e/journey.md +13 -8
- package/core/skills/qc/qa-designer/exploratory/charter.md +2 -0
- package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +7 -4
- package/core/skills/qc/qa-designer/functional/api.md +87 -18
- package/core/skills/qc/qa-designer/functional/gui-feature.md +12 -9
- package/core/skills/qc/qa-designer/functional/gui-screen.md +12 -10
- package/core/skills/qc/qa-designer/integration/api.md +12 -5
- package/core/skills/qc/qa-designer/integration/db.md +12 -6
- package/core/skills/qc/qa-designer/integration/gui.md +12 -5
- package/core/skills/qc/qa-designer/integration/kafka.md +12 -5
- package/core/skills/qc/qa-designer/non-functional.md +12 -5
- package/core/skills/qc/qa-designer/shared/action-keywords-glossary.md +91 -0
- package/core/skills/qc/qa-designer/shared/duplicate-check-procedure.md +105 -0
- package/core/skills/qc/qa-designer/shared/implicit-scenarios.md +22 -0
- package/core/skills/qc/qa-designer/shared/precision-rules.md +198 -0
- package/core/skills/qc/qa-designer/shared/read-doc-gap-inputs.md +25 -0
- package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +93 -0
- package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +243 -0
- package/core/skills/qc/qa-planner/risk-model.md +1 -1
- package/core/skills/qc/qa-reviewer/script/e2e.md +9 -1
- package/core/skills/qc/qa-reviewer/script/exploratory.md +9 -1
- package/core/skills/qc/qa-reviewer/script/functional.md +9 -1
- package/core/skills/qc/qa-reviewer/script/integration.md +9 -1
- package/core/skills/qc/qa-reviewer/script/non-functional.md +9 -1
- package/core/skills/qc/qa-reviewer/shared/read-doc-gap-inputs.md +26 -0
- package/core/skills/qc/qa-reviewer/shared/review-check-groups.md +207 -0
- package/core/skills/qc/qa-reviewer/shared/review-file-template.md +228 -0
- package/core/skills/qc/qa-reviewer/test-case/e2e.md +71 -13
- package/core/skills/qc/qa-reviewer/test-case/exploratory.md +53 -4
- package/core/skills/qc/qa-reviewer/test-case/functional.md +63 -15
- package/core/skills/qc/qa-reviewer/test-case/integration.md +64 -12
- package/core/skills/qc/qa-reviewer/test-case/non-functional.md +72 -13
- package/core/skills/qc/qa-runner/e2e.md +3 -3
- package/core/skills/qc/qa-runner/functional/gui-feature.md +9 -3
- package/core/skills/qc/qa-runner/functional/gui-screen.md +9 -3
- package/core/skills/qc/qa-runner/integration.md +1 -1
- package/core/skills/qc/qa-runner/non-functional.md +1 -1
- package/core/skills/spec/SKILL.md +1 -1
- package/core/steps/context-loader.md +7 -2
- package/core/steps/gap-verify.md +67 -0
- package/core/steps/report-footer.md +3 -3
- package/core/templates/feature.template +1 -0
- package/core/templates/tech-design.template.md +1 -0
- package/docs/02-concepts/pipeline-steps/09-validate-traces.md +1 -1
- package/docs/04-reference/commands.md +1 -1
- package/docs/04-reference/trace-schema.md +39 -1
- package/docs/explain/00-setup-ai-first.md +1 -1
- package/docs/explain/11-map-testids.md +70 -69
- package/docs/plans/qc-implementation-log.md +145 -3
- package/docs/plans/qc-surgery/00-nhat-ky.md +497 -0
- package/docs/plans/qc-surgery/01-checklist.md +92 -0
- package/docs/plans/qc-surgery/02-lo-trinh.md +266 -0
- package/docs/plans/qc-surgery/buoc/0-01-testid-attr-co-cho-o.md +157 -0
- package/docs/plans/qc-surgery/buoc/0-02-mot-nguon-cho-testid-attr.md +135 -0
- package/docs/plans/qc-surgery/buoc/0-03-skill-thoi-day-do-dom.md +167 -0
- package/docs/plans/qc-surgery/buoc/0-04-may-canh-hop-dong.md +173 -0
- package/docs/plans/qc-surgery/buoc/0-05-don-nhan-cot-va-2b.md +133 -0
- package/docs/plans/qc-surgery/buoc/0-06-hop-dong-truoc-code.md +226 -0
- package/docs/plans/qc-surgery/buoc/1-01-guard-br-tag.md +156 -0
- package/docs/plans/qc-surgery/buoc/1-02-guard-sc-coverage.md +153 -0
- package/docs/plans/qc-surgery/buoc/1-03-fail-3-nhan.md +176 -0
- package/docs/plans/qc-surgery/buoc/1-04-self-review-dung-chung.md +175 -0
- package/docs/plans/qc-surgery/buoc/1-05-spec-la-du-lieu.md +164 -0
- package/docs/plans/qc-surgery/buoc/1-06-gap-verify-du-bo.md +162 -0
- package/docs/plans/qc-surgery/buoc/README.md +85 -0
- package/docs/plans/qc-surgery/exec-d0-b1-testid-attr-header.md +147 -0
- package/docs/plans/qc-surgery/exec-d0-b2-thong-nhat-nguon-testid-attr.md +152 -0
- package/docs/plans/qc-surgery/exec-d0-b3-sua-skill-probe-dom.md +173 -0
- package/docs/plans/qc-surgery/exec-d0-b4-may-canh-4-5-6.md +168 -0
- package/docs/plans/qc-surgery/exec-d0-b5-don-nhan-lech.md +196 -0
- package/docs/plans/qc-surgery/exec-d0-b6-contract-truoc-code.md +350 -0
- package/docs/plans/qc-surgery/exec-d1-b1-guard-br-tag.md +129 -0
- package/docs/plans/qc-surgery/exec-d1-b2-guard-sc-coverage.md +159 -0
- package/docs/plans/qc-surgery/exec-d1-b3-fail-3-bucket.md +158 -0
- package/docs/plans/qc-surgery/exec-d1-b4-self-review-principles.md +145 -0
- package/docs/plans/qc-surgery/exec-d1-b5-noi-quy-spec-la-du-lieu.md +156 -0
- package/docs/plans/qc-surgery/exec-d1-b6-gap-verify-mo-rong.md +179 -0
- package/docs/plans/qc-surgery/exec-d2-b1-tach-qc-review.md +166 -0
- package/docs/plans/qc-surgery/exec-d2-b2-tach-qc-run-test-atomic.md +267 -0
- package/docs/plans/qc-surgery/exec-d2-b3-qc-automation-assess.md +198 -0
- package/docs/plans/qc-surgery/exec-d3-b1-qc-report-gate-decision.md +209 -0
- package/docs/plans/qc-surgery/exec-d4-b1-qc-design-testdata.md +146 -0
- package/docs/plans/qc-surgery/exec-d4-b2-qc-smoke-test.md +179 -0
- package/docs/plans/qc-surgery/exec-d4-b3-qc-metrics-va-lint.md +198 -0
- package/docs/plans/qc-surgery/exec-d4-b4-lint-spec-injection.md +199 -0
- package/package.json +1 -1
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
buoc: Đợt 2 — Bước 1
|
|
3
|
+
title: Tách /qc-review thành /qc-review-testcase và /qc-review-script
|
|
4
|
+
phu_thuoc: Đợt 1 xong
|
|
5
|
+
trang_thai: chưa làm
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Đợt 2 · Bước 1 — Một lệnh hai vai, không ai biết đang gọi vai nào
|
|
9
|
+
|
|
10
|
+
← [`01-checklist.md`](01-checklist.md) · [`02-lo-trinh.md`](02-lo-trinh.md)
|
|
11
|
+
|
|
12
|
+
## 1. Vì sao
|
|
13
|
+
|
|
14
|
+
`/qc-review` hiện là **một lệnh làm hai việc khác nhau ở hai thời điểm khác nhau**:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
sau /qc-design-test → soát test case (.Test.md) — coverage, độ rõ, trace
|
|
18
|
+
sau /qc-run-test → soát code test (Python/PO) — locator, assertion, hard-code
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Cách lệnh biết nó đang làm vai nào: **tự đoán**. Nguyên văn `commands/qc-review.tmpl:41-42`:
|
|
22
|
+
|
|
23
|
+
> *"Phát hiện mode: nếu artifact target là `.Test.md` → review test-case; nếu file Python
|
|
24
|
+
> test/PO tồn tại cho UC và mới hơn → review script. Nếu mơ hồ, hỏi."*
|
|
25
|
+
|
|
26
|
+
Ba vấn đề với việc đoán:
|
|
27
|
+
|
|
28
|
+
1. **Điều kiện "mới hơn" là một phép so ngày tháng, không phải ý định.** Sửa một dòng trong file
|
|
29
|
+
test hôm nay rồi gọi `/qc-review` để soát lại **test case** → lệnh chọn vai script.
|
|
30
|
+
2. **Người chạy không biết mình đã gọi vai nào cho tới khi đọc kết quả.** Bộ tiêu chí hai vai
|
|
31
|
+
khác nhau hoàn toàn (`skills/qc/qa-reviewer/test-case/*` vs `script/*`).
|
|
32
|
+
3. **Không đặt được điều kiện tiên quyết cho trạm sau.** Đây là hậu quả nặng nhất: `/qc-run-test`
|
|
33
|
+
không thể hỏi *"test case đã APPROVED chưa?"* vì không phân biệt được `REVIEW_<FEATURE>.md`
|
|
34
|
+
là kết quả soát test case hay soát script.
|
|
35
|
+
|
|
36
|
+
Chính file lệnh cũng ghi rõ hai vai không được lẫn — `:57`:
|
|
37
|
+
|
|
38
|
+
> *"gắn nhãn lỗi cho thứ đáng lẽ không có ở đó. Vai 2 dùng bộ tiêu chí riêng ở `script/*.md`."*
|
|
39
|
+
|
|
40
|
+
Đã biết là hai vai riêng, dùng tiêu chí riêng, chỉ còn thiếu việc gọi tên riêng.
|
|
41
|
+
|
|
42
|
+
## 2. Tình trạng hiện tại
|
|
43
|
+
|
|
44
|
+
**Lệnh tự khai là "gate hai chiều"** — `commands/qc-review.tmpl:9`:
|
|
45
|
+
|
|
46
|
+
> *"Một gate hai chiều: review test case (sau qc-design-test) VÀ script (sau qc-run-test)."*
|
|
47
|
+
|
|
48
|
+
**Hai bộ skill đã tách sẵn** — `:60-61`:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
- Soát test-case: test-case/{functional,e2e,integration,non-functional,exploratory}.md
|
|
52
|
+
- Soát script: script/{functional,e2e,integration,non-functional,exploratory}.md
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Tin tốt — bước này rẻ nhất trong cả Đợt 2:**
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
grep -c '"qc-review"' bin/trace-schema.json
|
|
59
|
+
# → 0
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`/qc-review` **không ghi cột trace nào**, nên nó không có trong `actors`, không có trong
|
|
63
|
+
`tsv_columns.written_by`, không có trong `positive_assertion_guards`. Tách nó **không đụng
|
|
64
|
+
schema** → không gặp ràng buộc nguyên tử của `bin/self-check.js` (R3/R14/R15) như bước 2.
|
|
65
|
+
|
|
66
|
+
## 3. Sẽ đổi thành gì
|
|
67
|
+
|
|
68
|
+
### 3.1 Hai lệnh, mỗi lệnh một vai
|
|
69
|
+
|
|
70
|
+
| Lệnh mới | Soát gì | Skill dùng | Chạy khi nào |
|
|
71
|
+
|---|---|---|---|
|
|
72
|
+
| `/qc-review-testcase` | `.Test.md` — coverage, độ rõ, trace | `qa-reviewer/test-case/*` | sau `/qc-design-test` |
|
|
73
|
+
| `/qc-review-script` | code test + Page Object | `qa-reviewer/script/{web,mobile}/*` | sau `/qc-design-script` (Đợt 2 bước 2) |
|
|
74
|
+
|
|
75
|
+
Bỏ hẳn phần tự đoán mode. Không còn `:41-42`.
|
|
76
|
+
|
|
77
|
+
### 3.2 Verdict thành điều kiện tiên quyết — đây là phần có giá trị thật
|
|
78
|
+
|
|
79
|
+
Mỗi lệnh ghi verdict rõ ràng vào `REVIEW_<FEATURE>.md`: **`APPROVED`** hoặc **`NEEDS_FIX`**.
|
|
80
|
+
|
|
81
|
+
Và trạm sau **đọc verdict rồi mới chạy**:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
/qc-automation-assess ← chỉ nhận TC có REVIEW verdict = APPROVED
|
|
85
|
+
TC còn Draft hoặc NEEDS_FIX → loại khỏi lượt, liệt kê ra
|
|
86
|
+
/qc-run-script ← đọc verdict của /qc-review-script;
|
|
87
|
+
NEEDS_FIX hoặc chưa có → DỪNG, báo chạy /qc-review-script trước
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Đây là điều `/qc-review` hiện **không làm được**, và là lý do chính để tách.
|
|
91
|
+
|
|
92
|
+
*(Hai trạm tiêu thụ này thuộc bước 2 và 3 của Đợt 2. Ở bước 1 chỉ cần ghi verdict đúng định
|
|
93
|
+
dạng; phần đọc verdict làm ở bước sau.)*
|
|
94
|
+
|
|
95
|
+
### 3.3 Thay 4 skill soát script dạng phẳng bằng web/mobile
|
|
96
|
+
|
|
97
|
+
Hiện `skills/qc/qa-reviewer/script/` có 5 file phẳng: `e2e.md`, `functional.md`,
|
|
98
|
+
`integration.md`, `non-functional.md`, `exploratory.md`. Stack mới có 2 nền (web Playwright /
|
|
99
|
+
mobile WebdriverIO) với tiêu chí khác nhau → thay bằng cấu trúc của đề xuất:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
qa-reviewer/script/
|
|
103
|
+
├── web/ { e2e, functional, functional/api, integration, non-functional }
|
|
104
|
+
├── mobile/ { e2e, functional, integration, non-functional }
|
|
105
|
+
└── exploratory.md ← giữ nguyên, không theo nền
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Kiểm trước khi gỡ 4 file cũ:** không có entry `ported` nào trong `bin/qc-base-map.json` cho
|
|
109
|
+
chúng → gỡ **không** trip R16(c) (*"target của entry `ported` phải tồn tại"*). Đã xác nhận bằng
|
|
110
|
+
cách quét bản đồ.
|
|
111
|
+
|
|
112
|
+
## 4. Sửa file nào
|
|
113
|
+
|
|
114
|
+
| File | Sửa gì |
|
|
115
|
+
|---|---|
|
|
116
|
+
| `commands/qc-review-testcase.tmpl` | **Mới** — dùng `{{include:steps/gate.md}}`, `{{include:steps/qc-scope.md}}`; khai nhãn `*Checkpoint:*` |
|
|
117
|
+
| `commands/qc-review-script.tmpl` | **Mới** — tương tự |
|
|
118
|
+
| `commands/qc-review.tmpl` + `.md` | **Gỡ** |
|
|
119
|
+
| `skills/qc/qa-reviewer/script/{e2e,functional,integration,non-functional}.md` | **Gỡ**, thay bằng `script/{web,mobile}/*` từ đề xuất |
|
|
120
|
+
| `skills/qc/qa-reviewer/script/exploratory.md` | Giữ |
|
|
121
|
+
| `steps/report-footer.md` | Bảng Phase + bảng Next — thay `/qc-review` bằng 2 lệnh mới |
|
|
122
|
+
| `docs/explain/18-qc-review.md` | Tách thành 2 mục, hoặc đổi tên file |
|
|
123
|
+
| `docs/04-reference/commands.md` | Cập nhật bảng lệnh |
|
|
124
|
+
| `bin/qc-base-map.json` | Entry cho skill `script/{web,mobile}/*` mới |
|
|
125
|
+
|
|
126
|
+
Nguồn nội dung: `D:\base\qcframework_proposal\command\qc-review-testcase.md` và
|
|
127
|
+
`qc-review-script.md` — **viết lại thành `.tmpl`**, thay gate cắt tay (5.4 KB của họ) bằng
|
|
128
|
+
`{{include:steps/gate.md}}` (11.1 KB thật). Gỡ khối comment provenance 10+ dòng ở đầu file, đưa
|
|
129
|
+
vào `bin/qc-base-map.json`.
|
|
130
|
+
|
|
131
|
+
## 5. Kiểm thế nào để biết đã xong
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# 1. Không còn dấu vết lệnh cũ
|
|
135
|
+
ls commands/qc-review.* # → không tồn tại
|
|
136
|
+
grep -rn "/qc-review\b" commands/ steps/ docs/ rules/ | grep -v "qc-review-testcase\|qc-review-script"
|
|
137
|
+
# → 0 kết quả (trừ file GAPS lịch sử)
|
|
138
|
+
|
|
139
|
+
# 2. Hai lệnh mới có nhãn Checkpoint và include gate thật
|
|
140
|
+
grep -n "Checkpoint:" commands/qc-review-testcase.tmpl commands/qc-review-script.tmpl
|
|
141
|
+
grep -n "{{include:steps/gate.md}}" commands/qc-review-testcase.tmpl commands/qc-review-script.tmpl
|
|
142
|
+
|
|
143
|
+
# 3. Mọi tham chiếu skill trỏ tới file có thật (R16d) + shortcut được sinh
|
|
144
|
+
node bin/build.js && node bin/self-check.js && node test/run.js
|
|
145
|
+
ls core/commands/qc-review-*.md # → 2 file
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Kiểm bằng tay:
|
|
149
|
+
|
|
150
|
+
1. `/qc-review-testcase {UC-ID}` → soát `.Test.md`, ghi `REVIEW_<FEATURE>.md` với verdict rõ
|
|
151
|
+
ràng. Phải **không** đi tìm file code test.
|
|
152
|
+
2. `/qc-review-script {UC-ID}` → soát code test. Phải **không** đi soát `.Test.md`.
|
|
153
|
+
3. `/qc-review {UC-ID}` → phải báo lệnh không tồn tại (đã gỡ).
|
|
154
|
+
|
|
155
|
+
## 6. Nếu bỏ qua thì hỏng gì
|
|
156
|
+
|
|
157
|
+
**Bước 2 và 3 của Đợt 2 mất phần chặn của chúng.** `/qc-run-script` được thiết kế để **DỪNG** khi
|
|
158
|
+
script chưa `APPROVED`; `/qc-automation-assess` để **loại** TC chưa `APPROVED` khỏi lượt đánh
|
|
159
|
+
giá. Cả hai đọc verdict — mà verdict của `/qc-review` hiện không nói nó thuộc vai nào. Nên nếu
|
|
160
|
+
không tách, hai cơ chế chặn đó không dựng được, và pipeline mới mất đúng hai điểm kiểm soát mà
|
|
161
|
+
nó thêm vào so với pipeline cũ.
|
|
162
|
+
|
|
163
|
+
Thêm nữa: `/qc-review` hiện đọc `.Test.md` **và** code Python. Đợt 2 bước 2 đổi stack sang
|
|
164
|
+
TypeScript. Lệnh hai vai sẽ phải mang cả hai bộ tiêu chí cho cả hai nền (web + mobile) trong
|
|
165
|
+
một file — tức là bốn bộ tiêu chí trong một lệnh, và phép đoán mode phải đoán thêm một chiều
|
|
166
|
+
nữa. Tách trước là để không phải viết cái đó.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
---
|
|
2
|
+
buoc: Đợt 2 — Bước 2
|
|
3
|
+
title: Tách /qc-run-test thành 3 lệnh — MỘT COMMIT DUY NHẤT
|
|
4
|
+
phu_thuoc: d2-b1
|
|
5
|
+
trang_thai: chưa làm
|
|
6
|
+
canh_bao: commit nguyên tử, ~30 file
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Đợt 2 · Bước 2 ⚠️ — Commit lớn nhất của cả đợt mổ
|
|
10
|
+
|
|
11
|
+
← [`01-checklist.md`](01-checklist.md) · [`02-lo-trinh.md`](02-lo-trinh.md)
|
|
12
|
+
|
|
13
|
+
> **Đọc §3.1 trước khi bắt tay.** Bước này **không chia nhỏ được** — nếu tách thành nhiều commit
|
|
14
|
+
> thì commit ở giữa sẽ làm `node bin/self-check.js` đỏ. Làm trên branch riêng.
|
|
15
|
+
|
|
16
|
+
## 1. Vì sao
|
|
17
|
+
|
|
18
|
+
### 1.1 Một lệnh gánh bốn việc
|
|
19
|
+
|
|
20
|
+
`/qc-run-test` hiện làm:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
1. quyết định test nào automate được ← ngầm định: TẤT CẢ
|
|
24
|
+
2. viết code test + Page Object
|
|
25
|
+
3. chạy test
|
|
26
|
+
4. phán "fail này là lỗi sản phẩm hay lỗi code test" → ghi qc_status
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Bốn việc, bốn loại quyết định, **không có chỗ nào dừng lại giữa chúng**. Hậu quả cụ thể:
|
|
30
|
+
|
|
31
|
+
- Không thể review code test **trước khi** chạy — lúc lệnh chạy xong thì code đã chạy rồi.
|
|
32
|
+
- Không thể sửa code test rồi chạy lại **mà không sinh lại từ đầu**.
|
|
33
|
+
- Việc số 1 không tồn tại như một bước, nên TC không automate được (OTP, captcha, thiết bị thật)
|
|
34
|
+
bị ép sinh script, rồi `pytest.skip` — và biến mất khỏi tầm nhìn.
|
|
35
|
+
|
|
36
|
+
### 1.2 Lỗ hổng test tay — lý do có lệnh thứ ba
|
|
37
|
+
|
|
38
|
+
Đề xuất của chị QC tách thành 2 lệnh (`design-script` + `run-script`). Nhưng như vậy còn thiếu
|
|
39
|
+
một chỗ: **ai ghi kết quả cho TC không automate được?**
|
|
40
|
+
|
|
41
|
+
`/qc-automation-assess` (bước 3) đóng dấu `Automatable: N` và nói *"giữ trong bộ manual"*. Rồi
|
|
42
|
+
hết. Không trạm nào chạy và ghi `qc_status` cho chúng.
|
|
43
|
+
|
|
44
|
+
Đến Đợt 3, `/qc-report` tính:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
Execution coverage = số SC có qc_status ∈ {pass, fail} / tổng số SC
|
|
48
|
+
Ngưỡng: coverage_min = 85 not_run_p0_max = 0
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Ví dụ PRD "Đăng nhập" 5 scenario, trong đó SC4 (OTP qua SMS, **P0**) và SC5 (sinh trắc học) phải
|
|
52
|
+
test tay:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
SC1 pass ← /qc-run-script ghi
|
|
56
|
+
SC2 pass ← /qc-run-script ghi
|
|
57
|
+
SC3 pass ← /qc-run-script ghi
|
|
58
|
+
SC4 not_run ← KHÔNG AI GHI. QC đã test tay, thấy OK, nhưng không có chỗ ghi lại
|
|
59
|
+
SC5 not_run ← KHÔNG AI GHI
|
|
60
|
+
|
|
61
|
+
→ Execution coverage = 3/5 = 60% < 85 ❌
|
|
62
|
+
→ SC P0 not_run = 1 > 0 ❌
|
|
63
|
+
→ VERDICT: FAIL ...và FAIL vĩnh viễn, không có cách nào sửa
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Nghịch lý: bước 3 **cho phép** đóng dấu `N`, Đợt 3 **trừng phạt** chính dấu đó. Hai trạm cùng
|
|
67
|
+
pipeline nói ngược nhau.
|
|
68
|
+
|
|
69
|
+
Nên thêm lệnh thứ ba: **`/qc-run-manualtest`** (tên do anh chọn).
|
|
70
|
+
|
|
71
|
+
Bonus: đề xuất định **gỡ** 9 skill `skills/qc/qa-runner/**` — đó đúng là bộ hướng dẫn chạy test
|
|
72
|
+
theo từng loại (màn hình, API, integration, exploratory session). `/qc-run-manualtest` dùng lại
|
|
73
|
+
chúng, nên **giữ**.
|
|
74
|
+
|
|
75
|
+
## 2. Tình trạng hiện tại
|
|
76
|
+
|
|
77
|
+
**Lệnh gộp** — `commands/qc-run-test.tmpl:7-9`:
|
|
78
|
+
|
|
79
|
+
> *"# /qc-run-test — QC Script Generation & Run (ghi qc_status)"*
|
|
80
|
+
> *"Sinh & chạy Python pytest-playwright từ `.Test.md` đã review, rồi ghi `qc_status` **chính
|
|
81
|
+
> thức** vào trace TSV."*
|
|
82
|
+
|
|
83
|
+
**Nó là chủ duy nhất của 4 cột trace** — `bin/trace-schema.json`:
|
|
84
|
+
|
|
85
|
+
| Cột | `qc-run-test` là | Dòng |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| 10 `qc_status` | **chủ ghi** (`"Chủ (ghi pass/fail/skip): qc-run-test — DUY NHẤT"`) | :785, :787 |
|
|
88
|
+
| 11 `qc_run_at` | chủ ghi | :804 |
|
|
89
|
+
| 12 `qc_owner` | chủ ghi | :818 |
|
|
90
|
+
| 13 `qc_blocked_by` | chủ ghi + đọc | :831, :837 |
|
|
91
|
+
|
|
92
|
+
Và nó xuất hiện **21 chỗ** trong schema:
|
|
93
|
+
|
|
94
|
+
| Khối | Số chỗ | Dòng |
|
|
95
|
+
|---|:---:|---|
|
|
96
|
+
| `actors` | 1 | :31 |
|
|
97
|
+
| `tags` | 3 | :197, :204, :480 |
|
|
98
|
+
| `tsv_columns` (`written_by`/`read_by`) | 10 | :666, :764, :779, :787, :804, :818, :831, :837, :933, :1004 |
|
|
99
|
+
| `queues` | 1 | :1060 |
|
|
100
|
+
| `positive_assertion_guards` → `owner` | 1 | :1769 |
|
|
101
|
+
| `strict_use_check` → `actors` | 1 | :1821 |
|
|
102
|
+
| Văn xuôi giải thích (`$comment`, `$history_note`, `why`) | 4 | :483, :484, :785, :802 |
|
|
103
|
+
|
|
104
|
+
## 3. Sẽ đổi thành gì
|
|
105
|
+
|
|
106
|
+
### 3.1 ⚠️ Vì sao phải là MỘT commit
|
|
107
|
+
|
|
108
|
+
`bin/self-check.js` phân giải tên lệnh → file nguồn ở ba rule:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
// bin/self-check.js:1050 (R14 — positive_assertion_guards)
|
|
112
|
+
const rel = `commands/${g.owner}.tmpl`;
|
|
113
|
+
if (!fs.existsSync(abs)) err('R14', `khai chủ cột ... là ${g.owner} — ${rel} không tồn tại`);
|
|
114
|
+
|
|
115
|
+
// bin/self-check.js:1159 (R15 — strict_use_check)
|
|
116
|
+
const rel = schema.actors[actor] || `commands/${actor}.tmpl`;
|
|
117
|
+
if (!fs.existsSync(abs)) err('R15', `khai actor ${actor} — ${rel} không tồn tại`);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Nên:
|
|
121
|
+
|
|
122
|
+
| Nếu làm | Kết quả |
|
|
123
|
+
|---|---|
|
|
124
|
+
| Đổi tên file trước, sửa schema sau | Commit giữa: schema trỏ `commands/qc-run-test.tmpl` không còn tồn tại → **R14 + R15 đỏ** |
|
|
125
|
+
| Sửa schema trước, đổi tên file sau | Commit giữa: schema trỏ `commands/qc-run-script.tmpl` chưa tồn tại → **R14 + R15 đỏ** |
|
|
126
|
+
|
|
127
|
+
Không có thứ tự nào an toàn. Nguyên tắc số 1 của đợt mổ (*mỗi commit đều xanh*) buộc gộp thành
|
|
128
|
+
một.
|
|
129
|
+
|
|
130
|
+
**Thêm một ràng buộc của R14:** file chủ cột phải **nhắc từng status bị chặn**. `bin/self-check.js`
|
|
131
|
+
đọc `positive_assertion_guards.blocked_when_status = ["DRIFT", "ORPHANED"]` rồi kiểm file chủ có
|
|
132
|
+
nhắc **cả hai token** — bằng `mentions()` (khớp ranh giới token, không phải `includes()`). Nên cả
|
|
133
|
+
`/qc-run-script` **và** `/qc-run-manualtest` đều phải có đoạn guard nhắc rõ `DRIFT` và
|
|
134
|
+
`ORPHANED`. Đề xuất đã có đoạn đó cho `run-script`; phải viết thêm cho `run-manualtest`.
|
|
135
|
+
|
|
136
|
+
### 3.2 Ba lệnh mới
|
|
137
|
+
|
|
138
|
+
| Lệnh | Việc | Ghi trace? |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| `/qc-design-script` | Viết code test + Page Object cho TC `Automatable: Y`. Sinh **Testability Improvement List** (`IMPROVE-{date}-{NN}`) khi gặp rào cản kỹ thuật. Đọc `Priority` → gắn tag `@smoke`/`@regression`. Điền cột `Script file` của `AUTOMATION_ASSESSMENT.md` | Không |
|
|
141
|
+
| `/qc-run-script` | Chạy code test đã `APPROVED`. Chạy lại ×2 → phân loại 3 loại → người xác nhận → ghi `qc_status` | **Có** — chủ cột 10–13 |
|
|
142
|
+
| `/qc-run-manualtest` | QC chạy tay TC `Automatable: N`, ghi kết quả vào sổ trace. Dùng lại `skills/qc/qa-runner/**` | **Có** — chủ cột 10–13 |
|
|
143
|
+
|
|
144
|
+
**Hai chủ cho cùng bốn cột** là điều mới. Cần khai đúng trong `positive_assertion_guards`
|
|
145
|
+
(`owner` hiện là một chuỗi, có thể phải thành mảng — kiểm cấu trúc rồi sửa `self-check.js:1050`
|
|
146
|
+
cho khớp nếu cần).
|
|
147
|
+
|
|
148
|
+
### 3.3 `/qc-run-manualtest` — điểm còn phải chốt với chị QC
|
|
149
|
+
|
|
150
|
+
Chưa chốt: **cách nhập kết quả**. Hai phương án:
|
|
151
|
+
|
|
152
|
+
| | Cách | Ưu | Nhược |
|
|
153
|
+
|---|---|---|---|
|
|
154
|
+
| A | Lệnh hỏi từng TC `Automatable: N`: pass/fail/skip + ghi chú | Không cần file trung gian; nhắc đủ TC | Nhiều lần hỏi nếu bộ manual lớn |
|
|
155
|
+
| B | QC điền một file checklist (`MANUAL_RUN.md`), lệnh đọc file đó rồi ghi trace | Điền offline, dễ nhiều người | Thêm một artifact phải bảo trì |
|
|
156
|
+
|
|
157
|
+
Không tự chọn — **hỏi chị QC trước khi viết lệnh này** (đã ghi trong `01-checklist.md`).
|
|
158
|
+
|
|
159
|
+
Bất kể phương án nào, hai luật giữ nguyên:
|
|
160
|
+
- Áp `positive_assertion_guards`: row `DRIFT`/`ORPHANED` → **không bao giờ ghi `pass`**, hạ
|
|
161
|
+
`not_run`.
|
|
162
|
+
- `qc_status = pass` phải có **bằng chứng** (ai chạy, ngày nào, ảnh/ghi chú). Không cho phép
|
|
163
|
+
"pass vì tôi nói vậy" — cùng tinh thần với `/qc-run-script` phải có output runner.
|
|
164
|
+
|
|
165
|
+
## 4. Sửa file nào
|
|
166
|
+
|
|
167
|
+
### 4.1 File lệnh
|
|
168
|
+
|
|
169
|
+
| File | Việc |
|
|
170
|
+
|---|---|
|
|
171
|
+
| `commands/qc-design-script.tmpl` | **Mới** |
|
|
172
|
+
| `commands/qc-run-script.tmpl` | **Mới** |
|
|
173
|
+
| `commands/qc-run-manualtest.tmpl` | **Mới** — không có trong đề xuất, tự viết |
|
|
174
|
+
| `commands/qc-run-test.tmpl` + `.md` | **Gỡ** |
|
|
175
|
+
|
|
176
|
+
Cả 3 file mới: `{{include:steps/gate.md}}` + `{{include:steps/qc-scope.md}}` + nhãn
|
|
177
|
+
`*Checkpoint:*`. Nguồn tham khảo: `D:\base\qcframework_proposal\command\{qc-design-script,
|
|
178
|
+
qc-run-script}.md` — gỡ comment provenance, thay gate cắt tay.
|
|
179
|
+
|
|
180
|
+
### 4.2 Schema — 21 chỗ (bảng ở §2)
|
|
181
|
+
|
|
182
|
+
- `actors` (:31): 1 entry → 3 entry.
|
|
183
|
+
- `tsv_columns` cột 10–13: `written_by` đổi `qc-run-test` → `qc-run-script` **+**
|
|
184
|
+
`qc-run-manualtest`. Cột 1, 8, 9, 21 (`read_by`) → cả 3 lệnh mới, tuỳ lệnh nào thật sự đọc.
|
|
185
|
+
- `positive_assertion_guards` (:1769): `owner` → 2 lệnh ghi trace.
|
|
186
|
+
- `strict_use_check` (:1821), `queues` (:1060), `tags` (:197, :204, :480).
|
|
187
|
+
- 4 chỗ văn xuôi (:483, :484, :785, :802): sửa cho khớp, đừng để giải thích nói tên lệnh đã chết.
|
|
188
|
+
|
|
189
|
+
### 4.3 Lệnh khác nhắc tên cũ — 12 file
|
|
190
|
+
|
|
191
|
+
`dev-gen-test` · `dev-run-test` · `fix-bug` · `generate-bdd` · `generate-code` · `qc-analyze` ·
|
|
192
|
+
`qc-design-test` · `qc-plan` · `qc-report` · `report-bug` · `validate-traces` (`.tmpl`).
|
|
193
|
+
|
|
194
|
+
### 4.4 Step, rule, skill, module
|
|
195
|
+
|
|
196
|
+
| File | Việc |
|
|
197
|
+
|---|---|
|
|
198
|
+
| `steps/context-loader.md`, `steps/report-footer.md`, `rules/workflow.md` | Đổi tên lệnh; cập nhật bảng Phase + Next |
|
|
199
|
+
| ~13 file `skills/qc/**` | Đổi tên lệnh (`DOC_GAP.template.md`, `spec-issue-reporter.md`, `tc-metadata-format.md`, `qa-reviewer/**`) |
|
|
200
|
+
| `skills/qc/qa-runner/**` (9 file) | **GIỮ** — `/qc-run-manualtest` dùng. Chỉ sửa chỗ nhắc `/qc-run-test` |
|
|
201
|
+
| `modules/qc-playwright/` | Thay bằng `modules/qc-playwright-ts/` (web: TypeScript + Playwright Test) + `modules/qc-wdio-appium/` (mobile: WebdriverIO + Appium `FlutterIntegration`). Giữ `qc-playwright` deprecated 1 version |
|
|
202
|
+
| `bin/qc-base-map.json` | Entry cho skill mới: `qa-script-designer/**`, `qa-script-runner/**`, `qa-testdata/**`, `_shared/**` |
|
|
203
|
+
|
|
204
|
+
### 4.5 Cấu hình & ngân sách
|
|
205
|
+
|
|
206
|
+
| File | Việc |
|
|
207
|
+
|---|---|
|
|
208
|
+
| `templates/project-context.yaml` + `path_keys` | Thêm `qc_automation_dir`, `feedback_dir` |
|
|
209
|
+
| `test/run.js` | Test *"tổng lệnh phải ở mức slim"*: `1200` → `1450`. **Comment nêu rõ vì sao**: thêm bộ QC 10+2, không phải vì một step lớn bị inline lại. Đo lại số thật rồi chốt |
|
|
210
|
+
|
|
211
|
+
### 4.6 Việc dọn bắt buộc — làm kèm, xem [`01-checklist.md`](01-checklist.md)
|
|
212
|
+
|
|
213
|
+
14 file skill còn gọi `TC_<FEATURE>.md` · 1 ref skill treo · 6 lệnh thiếu nhãn Checkpoint ·
|
|
214
|
+
12 comment provenance · 12 gate cắt tay.
|
|
215
|
+
|
|
216
|
+
### 4.7 Tài liệu
|
|
217
|
+
|
|
218
|
+
`docs/explain/19-qc-run-test.md` (tách thành 3) · `docs/04-reference/commands.md` ·
|
|
219
|
+
`docs/02-concepts/pipeline-steps/08-qc-automation.md` · `docs/03-guides/tester-qa.md` ·
|
|
220
|
+
`sdd-guide.html`.
|
|
221
|
+
|
|
222
|
+
## 5. Kiểm thế nào để biết đã xong
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
# 1. Không còn dấu vết tên cũ trong file nguồn
|
|
226
|
+
grep -rn "qc-run-test" commands/ steps/ rules/ skills/ bin/ modules/ templates/ | grep -v "^GAPS"
|
|
227
|
+
# → 0 kết quả
|
|
228
|
+
|
|
229
|
+
# 2. Bốn lệnh kiểm
|
|
230
|
+
node bin/build.js && node bin/self-check.js && node test/run.js && node bin/lint-trace.js
|
|
231
|
+
|
|
232
|
+
# 3. Ba lệnh mới được ship
|
|
233
|
+
ls core/commands/qc-design-script.md core/commands/qc-run-script.md core/commands/qc-run-manualtest.md
|
|
234
|
+
|
|
235
|
+
# 4. Ngân sách thật là bao nhiêu
|
|
236
|
+
node -e "const fs=require('fs'),p=require('path');let t=0;for(const f of fs.readdirSync('core/commands'))if(f.endsWith('.md'))t+=fs.statSync(p.join('core/commands',f)).size;console.log(Math.round(t/1024)+' KB')"
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Kiểm bằng tay trên 1 PRD thật — **phép thử quyết định là dòng cuối**:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
/qc-design-script {TICKET-ID} # cột Script file được điền; P0 có tag @smoke
|
|
243
|
+
/qc-review-script {TICKET-ID} # APPROVED
|
|
244
|
+
/qc-run-script {TICKET-ID} # ép 1 test flaky → qc_status = not_run, qc_owner = qc
|
|
245
|
+
/qc-run-manualtest {TICKET-ID} # ghi qc_status cho TC Automatable:N
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Rồi mở sổ trace: **mọi** SC phải có `qc_status ≠ not_run` (trừ SC thật sự chưa xử lý). Nếu SC
|
|
249
|
+
manual vẫn `not_run` thì `/qc-run-manualtest` chưa làm đúng việc — và Đợt 3 sẽ FAIL.
|
|
250
|
+
|
|
251
|
+
Thêm 2 ca âm:
|
|
252
|
+
- `/qc-run-script` khi `/qc-review-script` verdict `NEEDS_FIX` → phải **DỪNG**.
|
|
253
|
+
- Ghi `pass` trên row `DRIFT` → phải bị hạ `not_run` (cả `run-script` lẫn `run-manualtest`).
|
|
254
|
+
|
|
255
|
+
## 6. Nếu bỏ qua thì hỏng gì
|
|
256
|
+
|
|
257
|
+
**Bỏ cả bước:** pipeline giữ nguyên 6 trạm, `/qc-run-test` vẫn gánh 4 việc, và Đợt 3 + Đợt 4
|
|
258
|
+
không có nền để dựng (`/qc-report` cần `Automatable` + kết quả theo TC; `/qc-smoke-test` cần tag
|
|
259
|
+
`@smoke` do `design-script` gắn).
|
|
260
|
+
|
|
261
|
+
**Làm bước này mà bỏ `/qc-run-manualtest`:** tệ hơn cả bỏ cả bước. Ta sẽ có pipeline mới đầy đủ,
|
|
262
|
+
`/qc-report` với 8 ngưỡng và verdict — và verdict đó **luôn FAIL** với mọi PRD có test tay. Đội
|
|
263
|
+
QC sẽ làm điều hợp lý duy nhất còn lại: hạ `coverage_min` xuống 0 và `not_run_p0_max` lên vô
|
|
264
|
+
cùng, để verdict xanh. Lúc đó cả Đợt 3 thành trang trí.
|
|
265
|
+
|
|
266
|
+
**Chia nhỏ commit:** build đỏ ở commit giữa (§3.1). Nếu ai đó merge commit giữa vào `main` thì
|
|
267
|
+
`npm run build` của mọi người cùng đỏ, và không publish được.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
buoc: Đợt 2 — Bước 3
|
|
3
|
+
title: Thêm /qc-automation-assess + cột Script file
|
|
4
|
+
phu_thuoc: d2-b2
|
|
5
|
+
trang_thai: chưa làm
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Đợt 2 · Bước 3 — Quyết định "cái nào máy chạy, cái nào phải tay" thành một bước có hồ sơ
|
|
9
|
+
|
|
10
|
+
← [`01-checklist.md`](01-checklist.md) · [`02-lo-trinh.md`](02-lo-trinh.md)
|
|
11
|
+
|
|
12
|
+
## 1. Vì sao
|
|
13
|
+
|
|
14
|
+
### 1.1 Framework hiện ngầm định mọi test case đều automate được
|
|
15
|
+
|
|
16
|
+
`/qc-run-test` nhận `.Test.md` rồi sinh script cho **tất cả**. Nhưng thực tế luôn có TC không nên
|
|
17
|
+
hoặc không thể automate:
|
|
18
|
+
|
|
19
|
+
| TC | Vì sao không automate |
|
|
20
|
+
|---|---|
|
|
21
|
+
| Đăng nhập bằng OTP gửi SMS | Cần mã do người/bên thứ ba sinh ra |
|
|
22
|
+
| Xác minh captcha | Cùng lý do |
|
|
23
|
+
| In hoá đơn ra máy in thật | Thiết bị vật lý |
|
|
24
|
+
| Màn hình đang redesign hàng tuần | Chi phí bảo trì script > lợi ích |
|
|
25
|
+
| Test chạy 1 lần trước khi tính năng bị bỏ | Effort > ROI |
|
|
26
|
+
|
|
27
|
+
Hiện chúng vẫn bị sinh script, rồi `pytest.skip("lý do")`. Ba hệ quả:
|
|
28
|
+
|
|
29
|
+
1. **Quyết định không được ghi lại.** Sáu tháng sau không ai biết vì sao TC đó skip — là do
|
|
30
|
+
không automate được, hay do quên?
|
|
31
|
+
2. **Không có số liệu.** Câu "automation phủ bao nhiêu %?" không trả lời được, vì mẫu số lẫn cả
|
|
32
|
+
TC không bao giờ định automate.
|
|
33
|
+
3. **TC không automate được biến mất khỏi tầm nhìn.** Nó nằm trong file test case, có dòng
|
|
34
|
+
`skip`, và không ai chạy tay nó cả. Đây là nửa còn lại của lỗ hổng mà
|
|
35
|
+
[`exec-d2-b2`](exec-d2-b2-tach-qc-run-test-atomic.md) bịt bằng `/qc-run-manualtest` — bước
|
|
36
|
+
này là nửa *"biết TC nào cần chạy tay"*.
|
|
37
|
+
|
|
38
|
+
### 1.2 Không có đường từ test case → file code
|
|
39
|
+
|
|
40
|
+
Hiện muốn biết TC nào được test bởi file nào thì phải `grep` tag `@trace.verifies` trong code.
|
|
41
|
+
Ngược lại — *"file `login.spec.ts` phục vụ những TC nào"* — phải đọc cả file.
|
|
42
|
+
|
|
43
|
+
`/qc-run-script` cần biết **chạy file nào** cho UC này. Không có chỉ mục thì nó phải tự suy
|
|
44
|
+
đường dẫn từ quy ước đặt tên — và suy sai thì chạy sai bộ test, hoặc không chạy gì mà vẫn báo
|
|
45
|
+
xanh.
|
|
46
|
+
|
|
47
|
+
## 2. Tình trạng hiện tại
|
|
48
|
+
|
|
49
|
+
**Không có lệnh nào cho việc này.** Trong 33 lệnh hiện tại không có bước đánh giá khả năng
|
|
50
|
+
automate. `/qc-design-test` viết test case rồi chuyển thẳng sang `/qc-review` → `/qc-run-test`.
|
|
51
|
+
|
|
52
|
+
**`.Test.md` không có field nào ghi quyết định automate.** Kiểm
|
|
53
|
+
`skills/qc/qa-designer/shared/tc-metadata-format.md` — có `Priority`, có `@trace.verifies`, có
|
|
54
|
+
`Test Data`, **không có** `Automatable`.
|
|
55
|
+
|
|
56
|
+
**Không có chỉ mục ngược TC → file code.** `bin/lint-trace.js` có rule `T14` đi từ code → sổ
|
|
57
|
+
trace (`@trace.implements`), nhưng đó là code sản phẩm, không phải code test.
|
|
58
|
+
|
|
59
|
+
## 3. Sẽ đổi thành gì
|
|
60
|
+
|
|
61
|
+
### 3.1 Lệnh mới `/qc-automation-assess`
|
|
62
|
+
|
|
63
|
+
Chạy **sau** `/qc-review-testcase` (chỉ nhận TC verdict `APPROVED`) và **trước**
|
|
64
|
+
`/qc-design-script`. Ghi `AUTOMATION_ASSESSMENT.md` vào `qc_artifact_dir` (cấp PRD, cùng chỗ
|
|
65
|
+
`TEST_PLAN.md`):
|
|
66
|
+
|
|
67
|
+
```markdown
|
|
68
|
+
# Automation Assessment — {TICKET-ID} ({active_platform})
|
|
69
|
+
|
|
70
|
+
| TC ID | UC | Automatable | Lý do (nếu N) | Trace SC | Script file | Ghi chú |
|
|
71
|
+
|---|---|:---:|---|---|---|---|
|
|
72
|
+
| TC_LOGIN_001 | UC1 | Y | — | UC1-SC1 | — *(chưa qua design-script)* | |
|
|
73
|
+
| TC_LOGIN_004 | UC1 | N | Cần OTP/captcha thủ công | UC1-SC4 | — *(không automate)* | Giữ bộ manual |
|
|
74
|
+
|
|
75
|
+
**%Automated/Total: {automatable}/{total} = {pct}%**
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 3.2 Nhãn lý do — danh sách cố định, mở rộng được
|
|
79
|
+
|
|
80
|
+
| Nhãn | Khi dùng |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `Cần OTP/captcha thủ công` | Bước bắt buộc nhập mã do người/bên thứ ba sinh |
|
|
83
|
+
| `Phụ thuộc hệ thống ngoài` | App khác, thiết bị vật lý, email thật |
|
|
84
|
+
| `UI không ổn định` | Màn đang redesign/A-B test, bảo trì script > lợi ích |
|
|
85
|
+
| `Effort > ROI` | Tần suất chạy thấp, hoặc chi phí viết/bảo trì vượt giá trị |
|
|
86
|
+
| `Thiếu test-id contract` | Element không có test-id ổn định và dev chưa cam kết thêm |
|
|
87
|
+
|
|
88
|
+
Không khớp nhãn nào → **tạo nhãn mới** mô tả đúng lý do (không ép vào nhãn có sẵn), rồi ghi nhãn
|
|
89
|
+
mới đó trong report để bổ sung vào danh sách lần sau.
|
|
90
|
+
|
|
91
|
+
Vì sao chuẩn hoá nhãn: để đếm được. *"3 TC không automate vì thiếu test-id"* là một tín hiệu
|
|
92
|
+
hành động được (đi đàm phán với dev); *"3 TC vì lý do kỹ thuật"* thì không.
|
|
93
|
+
|
|
94
|
+
Riêng nhãn `Thiếu test-id contract` nối trực tiếp với Đợt 0: nếu Đợt 0 làm đúng thì nhãn này
|
|
95
|
+
phải **giảm dần** theo thời gian.
|
|
96
|
+
|
|
97
|
+
### 3.3 Cột `Script file` — chỉ mục ngược tường minh
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
Khởi tạo ở bước này → "—"
|
|
101
|
+
/qc-design-script điền → qc-automation/web/tests/academic/FT-101-login/login.spec.ts
|
|
102
|
+
/qc-run-script ĐỌC cột này → biết chạy file nào, KHÔNG tự suy path
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Đây là điều kiện để `/qc-run-script` không đoán. Đề xuất đã có ý này; giữ nguyên.
|
|
106
|
+
|
|
107
|
+
### 3.4 Cờ re-assessment tự động theo `DRIFT`
|
|
108
|
+
|
|
109
|
+
Trước khi đánh giá TC mới, quét cột `status` trong sổ trace. Với TC đã có dòng trong
|
|
110
|
+
`AUTOMATION_ASSESSMENT.md` từ lần trước mà scenario nó verify đang `DRIFT` (spec/BDD đã đổi):
|
|
111
|
+
|
|
112
|
+
- Gắn cờ `🔄 Re-assess` — quyết định `Y/N` cũ **không còn đáng tin**.
|
|
113
|
+
- Đánh giá lại **ngay trong lượt này**, không cần lịch định kỳ, không cần ai nhắc.
|
|
114
|
+
- Nếu kết quả đổi `Y → N` (đã có script, giờ không nên automate nữa): **giữ** path cũ trong cột
|
|
115
|
+
`Script file` + ghi chú `⚠️ Script đã lỗi thời — cân nhắc gỡ ở lần /qc-design-script kế tiếp`.
|
|
116
|
+
**Không tự xoá file** — để người quyết định.
|
|
117
|
+
- Nếu `N → Y`: cột vẫn `—`, chờ `/qc-design-script`.
|
|
118
|
+
|
|
119
|
+
### 3.5 TC `Automatable: N` không mất đi
|
|
120
|
+
|
|
121
|
+
Ba điều phải đúng:
|
|
122
|
+
|
|
123
|
+
1. **Không xoá khỏi `.Test.md`** — bộ test tay không đổi.
|
|
124
|
+
2. **Là đầu vào của `/qc-run-manualtest`** (d2-b2) — lệnh đó lọc `Automatable: N` từ file này để
|
|
125
|
+
biết phải chạy tay những gì. Đây là mắt xích khiến execution coverage của Đợt 3 đạt được.
|
|
126
|
+
3. **TC `Priority: P0` mà `Automatable: N` → cảnh báo riêng.** Tính năng lõi không có smoke test
|
|
127
|
+
tự động là tín hiệu đáng chú ý: cân nhắc `IMPROVE-xxx` để gỡ rào cản thay vì chấp nhận `N`
|
|
128
|
+
luôn.
|
|
129
|
+
|
|
130
|
+
### 3.6 Chốt một chỗ còn nhoè về phạm vi
|
|
131
|
+
|
|
132
|
+
`/qc-automation-assess` chạy theo **TICKET-ID** (cả PRD), còn `/qc-review-testcase` chạy theo
|
|
133
|
+
**UC-ID**. PRD 3 UC mà chỉ UC1 `APPROVED` thì sao? Chốt hành vi:
|
|
134
|
+
|
|
135
|
+
- Đánh giá TC của UC đã `APPROVED`.
|
|
136
|
+
- TC của UC còn `Draft`/`NEEDS_FIX` → **loại khỏi lượt**, và **liệt kê ra trong report** kèm
|
|
137
|
+
trạng thái thật.
|
|
138
|
+
- `%Automated/Total` tính trên mẫu số **chỉ gồm TC đã đánh giá**, và in kèm số TC bị loại — để
|
|
139
|
+
không ai đọc "100%" mà tưởng đã phủ cả PRD.
|
|
140
|
+
|
|
141
|
+
Nguyên tắc: *"chưa xét" khác "đã xét, sạch"* — cùng tinh thần bảng phạm vi của
|
|
142
|
+
`steps/qc-scope.md`.
|
|
143
|
+
|
|
144
|
+
## 4. Sửa file nào
|
|
145
|
+
|
|
146
|
+
| File | Việc |
|
|
147
|
+
|---|---|
|
|
148
|
+
| `commands/qc-automation-assess.tmpl` | **Mới** — `{{include:steps/gate.md}}` + `{{include:steps/qc-scope.md}}` + nhãn `*Checkpoint:*` |
|
|
149
|
+
| `skills/qc/qa-automation-assess/matrix.md` | **Mới** — tiêu chí đánh giá, danh sách nhãn, công thức ROI, khuôn bảng |
|
|
150
|
+
| `commands/qc-design-script.tmpl` | Đọc `AUTOMATION_ASSESSMENT.md`, lọc `Automatable: Y`; điền cột `Script file` sau khi sinh |
|
|
151
|
+
| `commands/qc-run-script.tmpl` | Đọc cột `Script file` để biết chạy file nào |
|
|
152
|
+
| `commands/qc-run-manualtest.tmpl` | Đọc `Automatable: N` để biết chạy tay những gì |
|
|
153
|
+
| `skills/qc/qa-designer/shared/tc-metadata-format.md` | Cân nhắc thêm ghi chú: quyết định `Automatable` **không** nằm trong `.Test.md`, nó ở `AUTOMATION_ASSESSMENT.md` (tránh hai chỗ ghi cùng một quyết định) |
|
|
154
|
+
| `steps/report-footer.md` | Bảng Phase + Next |
|
|
155
|
+
| `bin/qc-base-map.json` | Entry cho `qa-automation-assess/matrix.md` |
|
|
156
|
+
| `docs/04-reference/commands.md`, `docs/02-concepts/pipeline-steps/08-qc-automation.md` | Thêm lệnh mới |
|
|
157
|
+
|
|
158
|
+
Nguồn: `D:\base\qcframework_proposal\command\qc-automation-assess.md` +
|
|
159
|
+
`skills\qc\qa-automation-assess\matrix.md`. Gỡ comment provenance, thay gate cắt tay, và **sửa
|
|
160
|
+
`matrix.md` đang gọi `TC_<FEATURE>.md`** → `.Test.md` (nằm trong 14 file cần dọn).
|
|
161
|
+
|
|
162
|
+
⚠️ R16(d): tạo `skills/qc/qa-automation-assess/matrix.md` **trước hoặc cùng lúc** với việc lệnh
|
|
163
|
+
tham chiếu tới nó, không thì `self-check` đỏ.
|
|
164
|
+
|
|
165
|
+
## 5. Kiểm thế nào để biết đã xong
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
node bin/build.js && node bin/self-check.js && node test/run.js
|
|
169
|
+
ls core/commands/qc-automation-assess.md
|
|
170
|
+
grep -n "TC_<FEATURE>" skills/qc/qa-automation-assess/matrix.md # → 0 kết quả
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Kiểm bằng tay trên PRD có **cả hai loại** TC:
|
|
174
|
+
|
|
175
|
+
1. `/qc-automation-assess {TICKET-ID}` → `AUTOMATION_ASSESSMENT.md` có đủ TC, mỗi TC có `Y/N`,
|
|
176
|
+
`N` phải kèm nhãn từ danh sách; `%Automated` là **phép chia thật** trên số dòng bảng.
|
|
177
|
+
2. Cột `Script file` phải là `—` ở lượt này (script chưa tồn tại).
|
|
178
|
+
3. `/qc-design-script {TICKET-ID}` → chỉ sinh script cho `Y`; cột `Script file` được điền.
|
|
179
|
+
4. `/qc-run-script {TICKET-ID}` → chạy đúng file trong cột đó, **không** đoán path.
|
|
180
|
+
5. **Ca DRIFT:** đổi một scenario trong `.feature` để row trace thành `DRIFT`, chạy lại lệnh →
|
|
181
|
+
TC tương ứng phải có cờ `🔄 Re-assess` và được đánh giá lại.
|
|
182
|
+
6. **Ca phạm vi:** PRD 2 UC, để 1 UC `Draft` → report phải liệt kê TC bị loại, và `%Automated`
|
|
183
|
+
phải in kèm số TC bị loại.
|
|
184
|
+
7. **Ca P0+N:** đặt một TC `P0` thành `Automatable: N` → phải có cảnh báo riêng.
|
|
185
|
+
|
|
186
|
+
## 6. Nếu bỏ qua thì hỏng gì
|
|
187
|
+
|
|
188
|
+
Ba mắt xích đứt cùng lúc:
|
|
189
|
+
|
|
190
|
+
1. **`/qc-design-script` không biết sinh script cho TC nào** → quay lại ngầm định "tất cả", và
|
|
191
|
+
TC không automate được lại bị `skip` rồi biến mất.
|
|
192
|
+
2. **`/qc-run-manualtest` không biết chạy tay TC nào** → lệnh vừa thêm ở d2-b2 không có đầu vào
|
|
193
|
+
→ lỗ hổng execution coverage của Đợt 3 **không được bịt**, dù đã có lệnh.
|
|
194
|
+
3. **`/qc-run-script` phải tự suy đường dẫn file test** → suy sai thì chạy sai bộ test hoặc
|
|
195
|
+
không chạy gì mà vẫn báo xanh. Đây là kiểu hỏng im lặng tệ nhất: báo cáo xanh trên một lần
|
|
196
|
+
chạy không tồn tại.
|
|
197
|
+
|
|
198
|
+
Và mất luôn chỉ số `%Automated/Total` — con số đầu tiên mà Lead/PM sẽ hỏi khi thấy pipeline mới.
|