@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,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
buoc: Đợt 3 — Bước 1
|
|
3
|
+
title: Nâng cấp /qc-report — coverage kép, 8 ngưỡng, verdict
|
|
4
|
+
phu_thuoc: d2-b2 (CỨNG)
|
|
5
|
+
trang_thai: chưa làm
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Đợt 3 · Bước 1 — Từ "báo cáo" thành "phán quyết"
|
|
9
|
+
|
|
10
|
+
← [`01-checklist.md`](01-checklist.md) · [`02-lo-trinh.md`](02-lo-trinh.md)
|
|
11
|
+
|
|
12
|
+
> ⚠️ **Phụ thuộc cứng vào `/qc-run-manualtest`** (d2-b2). Làm trước là biến lệnh giá trị nhất
|
|
13
|
+
> của cả đề xuất thành lệnh không ai dùng được — xem §6.
|
|
14
|
+
|
|
15
|
+
## 1. Vì sao
|
|
16
|
+
|
|
17
|
+
Đây là phần giá trị nhất trong toàn bộ đề xuất của chị QC, và nó giải quyết ba câu hỏi mà
|
|
18
|
+
`/qc-report` hiện không trả lời được.
|
|
19
|
+
|
|
20
|
+
### 1.1 "Coverage bao nhiêu?" — hiện là một số, đáng ra là hai
|
|
21
|
+
|
|
22
|
+
Hai câu hỏi rất khác nhau bị gộp vào một chữ:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Đã VIẾT test case cho bao nhiêu % scenario? → design coverage = 100%
|
|
26
|
+
Đã CHẠY và có kết quả bao nhiêu % scenario? → execution coverage = 40%
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Báo "coverage 100%" khi mới chạy 40% là **báo cáo sai** — và nó sai theo hướng nguy hiểm: người
|
|
30
|
+
đọc kết luận đã kiểm xong.
|
|
31
|
+
|
|
32
|
+
### 1.2 "Được release chưa?" — hiện không có ai trả lời
|
|
33
|
+
|
|
34
|
+
`/qc-report` hiện in ra kết quả rồi hết. Người đọc tự quyết định. Nghe có vẻ đúng vai (QC không
|
|
35
|
+
quyết định release), nhưng thực tế nó đẩy một quyết định kỹ thuật thành một quyết định cảm tính:
|
|
36
|
+
*"38/42 pass, 2 fail, 2 skip — thế là được hay không?"*
|
|
37
|
+
|
|
38
|
+
Cái thiếu không phải quyền quyết định, mà là **ngưỡng khai báo trước**. Có ngưỡng thì QC đưa ra
|
|
39
|
+
tín hiệu kỹ thuật rõ ràng (PASS/FAIL/INCOMPLETE), Lead/PM vẫn giữ quyền quyết định cuối.
|
|
40
|
+
|
|
41
|
+
### 1.3 "Không có test nào fail" ≠ "tốt"
|
|
42
|
+
|
|
43
|
+
Đây là lỗ hổng logic nghiêm trọng nhất. Một PRD chạy 0 test sẽ có: 0 fail, 0 bug, không gì đỏ.
|
|
44
|
+
Nếu verdict dựa trên "có fail hay không" thì nó **PASS**.
|
|
45
|
+
|
|
46
|
+
Framework đã học chính bài này ở phía dev — `bin/trace-schema.json` →
|
|
47
|
+
`positive_assertion_guards` (G55):
|
|
48
|
+
|
|
49
|
+
> *"AI KHẲNG ĐỊNH MỘT GIÁ TRỊ DƯƠNG THÌ PHẢI KIỂM RẰNG MÌNH ĐƯỢC PHÉP KHẲNG ĐỊNH."*
|
|
50
|
+
|
|
51
|
+
Bước này là **mệnh đề đối ngẫu ở cấp báo cáo**: không được kết luận PASS chỉ vì không có tin
|
|
52
|
+
xấu.
|
|
53
|
+
|
|
54
|
+
## 2. Tình trạng hiện tại
|
|
55
|
+
|
|
56
|
+
`commands/qc-report.tmpl` — 217 dòng, tổng hợp kết quả từ `/qc-run-test`, liệt kê bug, in báo
|
|
57
|
+
cáo. Không có:
|
|
58
|
+
|
|
59
|
+
- Phân biệt design vs execution coverage.
|
|
60
|
+
- Ngưỡng nào.
|
|
61
|
+
- Verdict nào.
|
|
62
|
+
- Risk matrix nào.
|
|
63
|
+
|
|
64
|
+
Và số liệu nó tổng hợp lấy từ một lần chạy `/qc-run-test`, nên không phân biệt được *"SC này
|
|
65
|
+
chưa chạy"* với *"SC này chạy rồi và pass"* ở cấp báo cáo — thông tin đó có trong sổ trace nhưng
|
|
66
|
+
không được đưa lên thành chỉ số.
|
|
67
|
+
|
|
68
|
+
## 3. Sẽ đổi thành gì
|
|
69
|
+
|
|
70
|
+
### 3.1 Hai số coverage, không gộp
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
Design coverage = số SC có ≥1 TC-approved trỏ tới / tổng số SC (đếm từ .feature, trừ ORPHANED)
|
|
74
|
+
Execution coverage = số SC có qc_status ∈ {pass, fail} / tổng số SC
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
In **cạnh nhau**, kèm ghi chú rõ **không được gộp**:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
Coverage : Design 100% · Execution 90% ← KHÔNG gộp hai số này
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Chú ý: `design coverage` là **cùng phép đếm** với Guard SC coverage ở
|
|
84
|
+
[`exec-d1-b2`](exec-d1-b2-guard-sc-coverage.md). Khác nhau ở thời điểm: guard đếm **lúc thiết
|
|
85
|
+
kế** (còn kịp viết bù), báo cáo đếm **ở cuối** (chỉ còn kịp báo). Đó là lý do d1-b2 làm trước.
|
|
86
|
+
|
|
87
|
+
### 3.2 Cờ `INVERSION`
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
Design coverage < Execution coverage → 🔴 INVERSION
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Nghĩa: có SC **đã chạy** mà **không có test case approved** đứng sau. Bất thường — hoặc trace
|
|
94
|
+
matrix sai, hoặc có test chạy ngoài quy trình. Phải kiểm lại, không được bỏ qua.
|
|
95
|
+
|
|
96
|
+
### 3.3 Tám ngưỡng khai báo được
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
coverage_min = 85 # % execution coverage tổng, tối thiểu
|
|
100
|
+
p0_pass_rate_min = 100 # % P0 pass / P0 ĐÃ CHẠY (không tính not_run vào mẫu)
|
|
101
|
+
p1_pass_rate_min = 95
|
|
102
|
+
overall_pass_rate_min = 90
|
|
103
|
+
skip_rate_max = 5 # % skip / tổng SC
|
|
104
|
+
critical_risk_max = 0 # số SC risk CRITICAL còn tồn đọng
|
|
105
|
+
high_risk_max = 3
|
|
106
|
+
not_run_p0_max = 0 # số SC P0 not_run — giữ 0: P0 chưa chạy là rủi ro chưa đánh giá được
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Override qua `$ARGUMENTS` (`--coverage-min=80`…), hoặc hỏi **một lần** cho `{TICKET-ID}` nếu
|
|
110
|
+
chưa từng đặt trong phiên.
|
|
111
|
+
|
|
112
|
+
Chú ý cách tính `p0_pass_rate_min`: mẫu số là *P0 **đã chạy***, không phải *tổng P0*. Nếu tính
|
|
113
|
+
trên tổng thì một P0 chưa chạy sẽ làm tỷ lệ tụt và bị hiểu là "có test đỏ" — sai bản chất. Việc
|
|
114
|
+
"P0 chưa chạy" do ngưỡng #8 canh riêng. Hai chuyện khác nhau, hai ngưỡng khác nhau.
|
|
115
|
+
|
|
116
|
+
### 3.4 Risk matrix — Severity × Impact × Test-type
|
|
117
|
+
|
|
118
|
+
Với mỗi SC còn `fail` hoặc `not_run`, tính điểm rủi ro tồn đọng, xếp
|
|
119
|
+
`CRITICAL / HIGH / MEDIUM / LOW`. Đầu vào: severity của bug đã file, `Priority` của TC, loại test
|
|
120
|
+
(smoke/functional/integration/e2e). Ngưỡng #6, #7 dùng số này.
|
|
121
|
+
|
|
122
|
+
### 3.5 Verdict — ba trạng thái, không có trung gian
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
≥1 ô "⚠️ THIẾU DỮ LIỆU" → INCOMPLETE (chạy lại phần thiếu trước khi ra verdict)
|
|
126
|
+
≥1 ô ❌ → FAIL
|
|
127
|
+
mọi ô ✅ → PASS
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Thiếu dữ liệu thì ghi "thiếu dữ liệu", không tự ước lượng.** Đây là điều khoản chống chính lỗi
|
|
131
|
+
"số liệu ước lượng" ở [`exec-d1-b4`](exec-d1-b4-self-review-principles.md) nhóm 3.
|
|
132
|
+
|
|
133
|
+
Và điều khoản trung tâm:
|
|
134
|
+
|
|
135
|
+
> **KHÔNG BAO GIỜ ra PASS khi execution coverage thấp hoặc 0, dù 0 FAIL thật.**
|
|
136
|
+
> Ngưỡng #1 (`coverage_min`), #5 (`skip_rate_max`), #8 (`not_run_p0_max`) tự chặn ca này:
|
|
137
|
+
> coverage 0% « 85 · skip 100% » 5 · not-run P0 » 0 → verdict tự động rơi về **FAIL**.
|
|
138
|
+
|
|
139
|
+
### 3.6 Vai trò — QC đưa tín hiệu, Lead/PM quyết định
|
|
140
|
+
|
|
141
|
+
Verdict là **tín hiệu kỹ thuật**, không phải quyết định release. Report phải nói rõ điều đó, và
|
|
142
|
+
ghi cả bộ ngưỡng đã dùng để người đọc biết verdict được tính trên cơ sở nào:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
Ngưỡng dùng: coverage≥85% | P0=100% | P1≥95% | overall≥90% | skip≤5% |
|
|
146
|
+
critical≤0 | high≤3 | p0-not-run≤0
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## 4. Sửa file nào
|
|
150
|
+
|
|
151
|
+
| File | Việc |
|
|
152
|
+
|---|---|
|
|
153
|
+
| `commands/qc-report.tmpl` | Viết lại: thêm §Coverage (design vs execution) · §Risk Matrix · §Gate Decision (8 ngưỡng + verdict) · giữ phần liệt kê bug và handoff product-gap |
|
|
154
|
+
| `skills/qc/qa-script-runner/report.md` | **Mới** (thay `qa-runner/report/report.md` cho phần automation) — khuôn report theo stack mới: Playwright HTML Report + Trace Viewer (web) · WDIO + Allure (mobile) |
|
|
155
|
+
| `skills/qc/qa-runner/report/report.md` | **Giữ** — phần report cho `/qc-run-manualtest` |
|
|
156
|
+
| `steps/report-footer.md` | Bảng Next sau `/qc-report` |
|
|
157
|
+
| `docs/explain/20-qc-report.md`, `docs/02-concepts/pipeline-steps/08-qc-automation.md` | Cập nhật |
|
|
158
|
+
|
|
159
|
+
Nguồn: `D:\base\qcframework_proposal\command\qc-report.md` (§Bước 2 Coverage · §Bước 3 Risk
|
|
160
|
+
Matrix · §Bước 4 Gate Decision). Gỡ comment provenance, thay gate cắt tay, và **sửa tham chiếu
|
|
161
|
+
skill treo** `qa-script-runner/report/coverage-evaluator.md` → file này không tồn tại (chỉ có
|
|
162
|
+
`report.md`); hoặc tạo file đó, hoặc sửa tham chiếu. Không sửa thì `self-check.js:1235`
|
|
163
|
+
(R16(d)) fail build.
|
|
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
|
+
grep -n "coverage-evaluator" commands/qc-report.tmpl # → hoặc 0, hoặc file đó phải tồn tại
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Kiểm bằng **bốn ca**, và ca 4 là phép thử quyết định của cả đợt mổ:
|
|
173
|
+
|
|
174
|
+
| Ca | Dựng thế nào | Kỳ vọng |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| **1 — PASS** | PRD chạy đủ, mọi ngưỡng đạt | `VERDICT: PASS`, in đủ 8 ô ✅ |
|
|
177
|
+
| **2 — FAIL vì fail thật** | 1 test đỏ nhất quán, đã xác nhận `product-gap` | `VERDICT: FAIL`, ngưỡng #2 hoặc #4 ❌ |
|
|
178
|
+
| **3 — FAIL vì chưa chạy** | Không chạy `/qc-run-script` lần nào | `VERDICT: FAIL` (**không** phải PASS dù 0 fail). Ngưỡng #1, #5, #8 phải ❌ |
|
|
179
|
+
| **4 — PRD có test tay** | PRD có ≥1 SC `Automatable: N`, trong đó ≥1 là **P0**. Chạy `/qc-run-script` **và** `/qc-run-manualtest` | `VERDICT: PASS`. Execution coverage phải **đạt** |
|
|
180
|
+
|
|
181
|
+
**Ca 3** kiểm điều khoản "Untested ≠ Pass". Nếu nó ra PASS thì lỗ hổng logic vẫn còn.
|
|
182
|
+
|
|
183
|
+
**Ca 4** kiểm việc `/qc-run-manualtest` đã bịt được lỗ hổng. Nếu nó ra FAIL/INCOMPLETE thì
|
|
184
|
+
hoặc `/qc-run-manualtest` chưa ghi trace đúng, hoặc công thức execution coverage chưa tính SC
|
|
185
|
+
manual. **Không được xử lý bằng cách hạ ngưỡng** — đó là bỏ qua vấn đề chứ không sửa.
|
|
186
|
+
|
|
187
|
+
Thêm ca 5 nếu dựng được: tạo tình huống `INVERSION` (một SC có `qc_status = pass` mà không TC
|
|
188
|
+
approved nào trỏ tới) → phải hiện cờ 🔴.
|
|
189
|
+
|
|
190
|
+
## 6. Nếu bỏ qua thì hỏng gì
|
|
191
|
+
|
|
192
|
+
**Bỏ cả bước:** `/qc-report` vẫn là bản tổng hợp mỏng. Câu "được release chưa?" vẫn trả lời bằng
|
|
193
|
+
cảm tính, và "coverage 100%" vẫn là con số gộp hai thứ khác nhau.
|
|
194
|
+
|
|
195
|
+
**Làm bước này TRƯỚC d2-b2 (`/qc-run-manualtest`) — đây là cái phải tránh:**
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
PRD nào có ≥1 SC phải test tay
|
|
199
|
+
→ SC đó mãi not_run (không trạm nào ghi)
|
|
200
|
+
→ execution coverage không bao giờ đạt 85
|
|
201
|
+
→ nếu SC đó là P0 thì ngưỡng #8 cũng trượt
|
|
202
|
+
→ VERDICT: FAIL vĩnh viễn, không có cách sửa
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Và điều sẽ xảy ra sau đó là điều hợp lý duy nhất còn lại cho đội QC: **hạ `coverage_min` xuống 0
|
|
206
|
+
và `not_run_p0_max` lên vô cùng** để verdict xanh. Lúc đó cả 8 ngưỡng thành trang trí, và ta đã
|
|
207
|
+
làm một lệnh phán quyết mà phán quyết của nó bị vô hiệu hoá ngay từ ngày đầu.
|
|
208
|
+
|
|
209
|
+
Vì vậy thứ tự d2-b2 → d3-b1 **không phải sở thích**, nó là điều kiện để bước này có nghĩa.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
buoc: Đợt 4 — Bước 1
|
|
3
|
+
title: Thêm /qc-design-testdata — kế hoạch dữ liệu test cho phần automation
|
|
4
|
+
phu_thuoc: d2-b3
|
|
5
|
+
trang_thai: chưa làm
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Đợt 4 · Bước 1 — Dữ liệu test dùng chung là nguồn gốc phổ biến nhất của test chập chờn
|
|
9
|
+
|
|
10
|
+
← [`01-checklist.md`](01-checklist.md) · [`02-lo-trinh.md`](02-lo-trinh.md)
|
|
11
|
+
|
|
12
|
+
## 1. Vì sao
|
|
13
|
+
|
|
14
|
+
Kể một chuyện quen:
|
|
15
|
+
|
|
16
|
+
Hai test dùng cùng một tài khoản `qa_student_01`. Test A đổi mật khẩu tài khoản đó. Test B đăng
|
|
17
|
+
nhập bằng mật khẩu cũ. Chạy tuần tự thì B đỏ. Chạy song song thì tuỳ thứ tự — đỏ hoặc xanh.
|
|
18
|
+
|
|
19
|
+
Ai điều tra sẽ thấy test B "chập chờn", gắn nhãn `flaky`, quarantine, rồi tuần sau nó lại nổ. Vì
|
|
20
|
+
nguyên nhân không nằm trong test B — nó nằm ở chỗ **hai test cùng sở hữu một tài khoản mà không
|
|
21
|
+
ai khai điều đó ra**.
|
|
22
|
+
|
|
23
|
+
Đây là loại lỗi có đặc điểm riêng: nó **không sửa được bằng cách sửa test**. Phải sửa **quyết
|
|
24
|
+
định về dữ liệu** — tài khoản nào dùng riêng, tài khoản nào dùng chung, chạy xong có dọn không.
|
|
25
|
+
Và quyết định đó hiện không được ghi ở đâu.
|
|
26
|
+
|
|
27
|
+
Bốn câu hỏi cần trả lời trước khi viết script, không phải sau:
|
|
28
|
+
|
|
29
|
+
| Câu hỏi | Nếu không trả lời |
|
|
30
|
+
|---|---|
|
|
31
|
+
| Dữ liệu này lấy ở đâu? | Hard-code vào test, đổi môi trường là vỡ hết |
|
|
32
|
+
| Có dùng chung với test khác không? | Chuyện ở trên |
|
|
33
|
+
| Chạy xong có phải dọn không? | DB test phình dần, đến lúc test đỏ vì trùng khoá |
|
|
34
|
+
| Có chứa mật khẩu/PII thật không? | Credential lọt vào git |
|
|
35
|
+
|
|
36
|
+
## 2. Tình trạng hiện tại
|
|
37
|
+
|
|
38
|
+
Test data hiện là **một field mô tả trong test case**. Kiểm
|
|
39
|
+
`skills/qc/qa-designer/shared/tc-metadata-format.md` — có field `Test Data`, dạng văn xuôi kiểu
|
|
40
|
+
*"tài khoản học sinh đã kích hoạt"*.
|
|
41
|
+
|
|
42
|
+
Field đó **đủ cho test tay** (người đọc tự hiểu, tự chuẩn bị) nhưng **không đủ cho automation**:
|
|
43
|
+
nó không nói tài khoản nào, ai sở hữu, có dùng chung không, dọn thế nào.
|
|
44
|
+
|
|
45
|
+
Và `modules/qc-playwright/stack-profile.yaml` có thư mục `test_data/` với ghi chú *"JSON
|
|
46
|
+
datasets"* — tức là chỗ chứa thì có, còn **kế hoạch** thì không.
|
|
47
|
+
|
|
48
|
+
## 3. Sẽ đổi thành gì
|
|
49
|
+
|
|
50
|
+
### 3.1 Lệnh mới `/qc-design-testdata`
|
|
51
|
+
|
|
52
|
+
Chạy **sau** `/qc-automation-assess` (cần biết TC nào `Automatable: Y`) và **trước**
|
|
53
|
+
`/qc-design-script`. Ghi **một** file `TEST_DATA_PLAN.md` cho cả PRD, vào `qc_artifact_dir`.
|
|
54
|
+
|
|
55
|
+
**Chỉ phục vụ automation.** Test data cho test tay vẫn nằm ở field `Test Data` của `.Test.md`,
|
|
56
|
+
độc lập, không tham chiếu qua lại. Lý do tách: người chạy tay tự xoay được dữ liệu; script thì
|
|
57
|
+
không — nó cần địa chỉ chính xác.
|
|
58
|
+
|
|
59
|
+
### 3.2 Chín cột của `TEST_DATA_PLAN.md`
|
|
60
|
+
|
|
61
|
+
| Cột | Ý nghĩa | Vì sao cần |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `TD-xxx` | ID, trace được tới TC/SC | Để biết dữ liệu nào phục vụ test nào |
|
|
64
|
+
| **Type** | `Account` / `Boundary Value` / `Negative Value` / `Seed/Reference Data` / `Env Config` | Phân loại để biết cách chuẩn bị |
|
|
65
|
+
| **Dùng bởi** | `{UC-ID}-SC{N}` / `TC_xxx` | **Cột quan trọng nhất** — nhìn là biết dữ liệu bị dùng ở mấy chỗ |
|
|
66
|
+
| **Nguồn** | `Static fixture` / `Factory` (sinh runtime) / `DB seed` / `Env var` (secret) | Script biết lấy ở đâu |
|
|
67
|
+
| **Cách ly** | `Dedicated` / `Pool` / `Stateless` | Đây là cột chặn đúng chuyện ở §1 |
|
|
68
|
+
| **Vòng đời** | `Persistent` / `Ephemeral` | Biết có được sửa hay không |
|
|
69
|
+
| **Cleanup** | Có/không + cách dọn | Chặn DB phình |
|
|
70
|
+
| **Nhạy cảm** | Có chứa PII/credential không → **bắt buộc** qua `Env.*`/`CONFIG` | Chặn credential vào git |
|
|
71
|
+
| **Owner & refresh** | Ai bảo trì, khi nào cần làm mới | Tài khoản test hết hạn thì ai biết |
|
|
72
|
+
|
|
73
|
+
Hai cột **Dùng bởi** + **Cách ly** là cặp giải quyết vấn đề ở §1: nhìn thấy một tài khoản
|
|
74
|
+
`Dedicated` mà cột "Dùng bởi" có 3 TC là **mâu thuẫn tự lộ ra** — hoặc nó phải là `Pool`, hoặc
|
|
75
|
+
phải tách thành 3 tài khoản.
|
|
76
|
+
|
|
77
|
+
### 3.3 Nối với nội quy bảo vệ dữ liệu
|
|
78
|
+
|
|
79
|
+
Cột **Nhạy cảm** không chỉ là ghi chú. Nếu một dòng đánh dấu có chứa credential thì cột
|
|
80
|
+
**Nguồn** **bắt buộc** phải là `Env var`, không được là `Static fixture`. Đây là kiểm được bằng
|
|
81
|
+
máy (một phép so hai cột) — cân nhắc thêm vào `bin/lint-spec.js` (d4-b4) hoặc kiểm ngay trong
|
|
82
|
+
lệnh.
|
|
83
|
+
|
|
84
|
+
Nối với `rules/data-protection.md` (đã mở rộng ở d1-b5): agent không được in giá trị secret vào
|
|
85
|
+
`TEST_DATA_PLAN.md` — chỉ ghi **tên biến môi trường**, không ghi giá trị.
|
|
86
|
+
|
|
87
|
+
### 3.4 Escape hatch — không thiết kế trước
|
|
88
|
+
|
|
89
|
+
Nếu sau này phát hiện một tài khoản/dữ liệu bị dùng lại ở **≥2 PRD khác nhau**, mới cân nhắc
|
|
90
|
+
tách phần đó ra một registry dùng chung (tránh sửa N nơi khi tài khoản đổi). **Không làm trước
|
|
91
|
+
khi thấy dấu hiệu thật** — đúng ý chị QC đã ghi trong đề xuất, và đúng nguyên tắc không dựng hạ
|
|
92
|
+
tầng cho vấn đề chưa có.
|
|
93
|
+
|
|
94
|
+
## 4. Sửa file nào
|
|
95
|
+
|
|
96
|
+
| File | Việc |
|
|
97
|
+
|---|---|
|
|
98
|
+
| `commands/qc-design-testdata.tmpl` | **Mới** — `{{include:steps/gate.md}}` + `{{include:steps/qc-scope.md}}` + nhãn `*Checkpoint:*` |
|
|
99
|
+
| `skills/qc/qa-testdata/test-data-plan.md` | **Mới** — khuôn 9 cột, cách chọn giá trị mỗi cột, ví dụ |
|
|
100
|
+
| `commands/qc-design-script.tmpl` | Đọc `TEST_DATA_PLAN.md`; thiếu file → dừng, báo chạy bước này trước |
|
|
101
|
+
| `steps/report-footer.md` | Bảng Phase + Next |
|
|
102
|
+
| `bin/qc-base-map.json` | Entry cho skill mới |
|
|
103
|
+
| `docs/04-reference/commands.md` | Thêm lệnh |
|
|
104
|
+
|
|
105
|
+
Nguồn: `D:\base\qcframework_proposal\command\qc-design-testdata.md` +
|
|
106
|
+
`skills\qc\qa-testdata\test-data-plan.md`. **Sửa `test-data-plan.md` đang gọi `TC_<FEATURE>.md`**
|
|
107
|
+
→ `.Test.md` (nằm trong 14 file cần dọn).
|
|
108
|
+
|
|
109
|
+
### Cân nhắc gộp
|
|
110
|
+
|
|
111
|
+
Chính chị QC đề xuất *"cân nhắc gộp `qc-automation-assess` + `qc-design-testdata` thành 1 lệnh
|
|
112
|
+
nếu đội QC thực tế thấy 2 bước tách biệt là thừa cho case đơn giản"*. Nếu chọn gộp, phần này
|
|
113
|
+
thành một mục trong `/qc-design-script` thay vì một lệnh — **quyết định sau khi chạy thật 2–3
|
|
114
|
+
PRD**, không quyết trước.
|
|
115
|
+
|
|
116
|
+
## 5. Kiểm thế nào để biết đã xong
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
node bin/build.js && node bin/self-check.js && node test/run.js
|
|
120
|
+
grep -n "TC_<FEATURE>" skills/qc/qa-testdata/test-data-plan.md # → 0 kết quả
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Kiểm bằng tay:
|
|
124
|
+
|
|
125
|
+
1. `/qc-design-testdata {TICKET-ID}` → `TEST_DATA_PLAN.md` có đủ 9 cột, chỉ phủ TC
|
|
126
|
+
`Automatable: Y`.
|
|
127
|
+
2. **Ca mâu thuẫn cách ly:** dựng tình huống một tài khoản `Dedicated` mà cột "Dùng bởi" có 2 TC
|
|
128
|
+
→ lệnh phải chỉ ra mâu thuẫn, không im lặng ghi.
|
|
129
|
+
3. **Ca nhạy cảm:** một dòng đánh `Nhạy cảm = có` mà `Nguồn = Static fixture` → phải báo lỗi,
|
|
130
|
+
đòi đổi sang `Env var`.
|
|
131
|
+
4. **Ca không ghi giá trị secret:** kiểm `TEST_DATA_PLAN.md` không chứa mật khẩu/token thật, chỉ
|
|
132
|
+
chứa tên biến.
|
|
133
|
+
5. `/qc-design-script` khi **chưa** có `TEST_DATA_PLAN.md` → phải dừng, báo chạy bước này trước.
|
|
134
|
+
|
|
135
|
+
## 6. Nếu bỏ qua thì hỏng gì
|
|
136
|
+
|
|
137
|
+
Không có gì vỡ ngay — đây là lý do bước này ở Đợt 4, không phải Đợt 1. Script vẫn viết được, vẫn
|
|
138
|
+
chạy được, dữ liệu vẫn hard-code hoặc dùng chung ngầm.
|
|
139
|
+
|
|
140
|
+
Cái vỡ đến muộn và khó truy: **tỷ lệ test chập chờn tăng dần theo số test**. Với 20 test thì hiếm
|
|
141
|
+
khi đụng nhau; với 200 test dùng chung một pool tài khoản thì đụng liên tục. Và mỗi lần đụng,
|
|
142
|
+
`/qc-run-script` sẽ gắn nhãn `flaky` rồi quarantine — tức là **triệu chứng được xử lý, nguyên
|
|
143
|
+
nhân thì không**, và số test bị quarantine chỉ tăng.
|
|
144
|
+
|
|
145
|
+
Chỉ số **flaky rate trend** ở d4-b3 sẽ cho thấy điều đó bằng số. Nếu đường đó đi lên đều mà
|
|
146
|
+
không rõ vì sao, thì bước này là chỗ đầu tiên nên xem.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
buoc: Đợt 4 — Bước 2
|
|
3
|
+
title: Thêm smoke suite — chạy nhanh tính năng lõi khi có build mới
|
|
4
|
+
phu_thuoc: d2-b2
|
|
5
|
+
trang_thai: chưa làm
|
|
6
|
+
can_chot: TÊN LỆNH (không được nhầm /dev-smoke-test)
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Đợt 4 · Bước 2 — Cổng nhanh trước khi chạy hết regression
|
|
10
|
+
|
|
11
|
+
← [`01-checklist.md`](01-checklist.md) · [`02-lo-trinh.md`](02-lo-trinh.md)
|
|
12
|
+
|
|
13
|
+
> ⚠️ **Chưa chốt tên lệnh.** Xem §3.1 — phải chốt trước khi viết, vì `/dev-smoke-test` đã tồn
|
|
14
|
+
> tại với nghĩa khác hẳn.
|
|
15
|
+
|
|
16
|
+
## 1. Vì sao
|
|
17
|
+
|
|
18
|
+
Hai tình huống mà pipeline hiện không có câu trả lời nhanh:
|
|
19
|
+
|
|
20
|
+
**a) Có build mới, cần biết ngay tính năng lõi còn sống không.** Cách duy nhất hiện tại: chạy
|
|
21
|
+
`/qc-run-script` cho **từng UC**. Một PRD 5 UC × vài chục test = rất lâu, và phần lớn thời gian
|
|
22
|
+
dành cho test không phải tính năng lõi.
|
|
23
|
+
|
|
24
|
+
**b) Gấp trước bàn giao, chưa kịp chạy đủ.** Cần một tín hiệu go/no-go trong 5 phút thay vì báo
|
|
25
|
+
cáo đầy đủ trong 2 giờ.
|
|
26
|
+
|
|
27
|
+
Cả hai cần cùng một thứ: **chạy riêng tập test của tính năng lõi**, phạm vi linh hoạt (1 feature
|
|
28
|
+
/ 1 domain / toàn app), và ra một kết luận đi/không-đi.
|
|
29
|
+
|
|
30
|
+
Điều kiện để làm được: phải biết test nào là "lõi". Cái đó đã có — `Priority: P0` trong test
|
|
31
|
+
case, và `/qc-design-script` (d2-b2) gắn tag tự động:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
P0 → @smoke + @regression
|
|
35
|
+
P1/P2 → @regression
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Nên bước này là **thu hoạch** của việc gắn tag ở d2-b2, không phải hạ tầng mới.
|
|
39
|
+
|
|
40
|
+
## 2. Tình trạng hiện tại
|
|
41
|
+
|
|
42
|
+
**Không có lệnh nào chạy theo tag.** `/qc-run-test` luôn khoá **một UC**, chạy toàn bộ test của
|
|
43
|
+
UC đó.
|
|
44
|
+
|
|
45
|
+
**Đã có một lệnh tên gần giống, nghĩa khác hẳn** — `commands/dev-smoke-test.tmpl:1-3`:
|
|
46
|
+
|
|
47
|
+
> *"# /dev-smoke-test — Smoke Test Service hoặc App đang chạy*
|
|
48
|
+
> *Dùng khi service/app **đang chạy sẵn**. Khác `/dev-run-test` (không cần live server)."*
|
|
49
|
+
|
|
50
|
+
Tức `/dev-smoke-test` là **của dev**, kiểm một service đang chạy có sống không (health check,
|
|
51
|
+
gọi vài endpoint). Không liên quan gì tới tag `@smoke` của bộ test QC.
|
|
52
|
+
|
|
53
|
+
Hai lệnh cùng chữ "smoke test" với hai nghĩa khác nhau trong cùng một framework là mời gọi gọi
|
|
54
|
+
sai lệnh — đúng loại lỗi mà việc tách `/qc-review` (d2-b1) vừa xử lý.
|
|
55
|
+
|
|
56
|
+
## 3. Sẽ đổi thành gì
|
|
57
|
+
|
|
58
|
+
### 3.1 Chốt tên trước — 3 phương án
|
|
59
|
+
|
|
60
|
+
| Phương án | Ưu | Nhược |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| `/qc-smoke-run` | Ngắn, giữ chữ "smoke" mà đội QC quen | Vẫn gần `/dev-smoke-test`, đọc nhanh dễ lẫn |
|
|
63
|
+
| `/qc-run-smoke` | Cùng họ với `/qc-run-script`, `/qc-run-manualtest` — nhìn là biết nhóm "chạy test" | Dài hơn một chút |
|
|
64
|
+
| `/qc-gate-check` | Không lẫn với gì; nói đúng mục đích (cổng nhanh go/no-go) | Mất chữ "smoke" mà đội QC đã quen dùng |
|
|
65
|
+
|
|
66
|
+
**Nghiêng về `/qc-run-smoke`**: nó xếp cùng nhóm với hai lệnh chạy test khác, nên khi gõ `/qc-run`
|
|
67
|
+
là thấy đủ ba lựa chọn — `script` (chạy tự động), `manualtest` (chạy tay), `smoke` (chạy nhanh
|
|
68
|
+
tập lõi). Không tự quyết, **cần chốt với anh + chị QC**.
|
|
69
|
+
|
|
70
|
+
### 3.2 Phạm vi linh hoạt — khác mọi lệnh QC khác
|
|
71
|
+
|
|
72
|
+
| `$ARGUMENTS` | Phạm vi |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `{domain}/{prd-slug}` | 1 feature |
|
|
75
|
+
| `{domain}` | cả domain |
|
|
76
|
+
| rỗng hoặc `all` | toàn app |
|
|
77
|
+
|
|
78
|
+
Đây là điểm **khác biệt có chủ ý**: mọi lệnh QC khác khoá một PRD/UC. Lệnh này không — vì câu hỏi
|
|
79
|
+
nó trả lời là *"build này có sống không"*, không phải *"PRD này đã kiểm xong chưa"*.
|
|
80
|
+
|
|
81
|
+
Nên nó **không dùng** `steps/qc-scope.md` như 11 lệnh kia (`qc-scope` chốt `TICKET-ID` +
|
|
82
|
+
`active_platform` + `uc_list`). Cần cách phân giải phạm vi riêng — và phải viết rõ vì sao, để
|
|
83
|
+
người sau không "sửa cho đồng bộ".
|
|
84
|
+
|
|
85
|
+
### 3.3 Chỉ chạy script ĐÃ CÓ
|
|
86
|
+
|
|
87
|
+
Không tự sinh script mới. Chỉ chạy file đã qua `/qc-design-script` + `/qc-review-script` verdict
|
|
88
|
+
`APPROVED`. Không có script `@smoke` nào trong phạm vi → **báo rõ là chưa có**, đừng báo xanh:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
⚠️ Không tìm thấy test @smoke nào trong phạm vi {scope}.
|
|
92
|
+
Chưa có nghĩa là "sạch" — nghĩa là chưa có gì để kiểm.
|
|
93
|
+
Chạy /qc-design-script cho các UC có TC Priority P0 trước.
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Câu này quan trọng: "0 test chạy, 0 fail" **không phải** go. Cùng logic "Untested ≠ Pass" của
|
|
97
|
+
Đợt 3.
|
|
98
|
+
|
|
99
|
+
### 3.4 Retry + 3 loại như d1-b3, nhưng rút gọn
|
|
100
|
+
|
|
101
|
+
Cùng cơ chế phân loại (`script-bug` / `product-gap` / `flaky`), nhưng **1 lần chạy lại** thay vì
|
|
102
|
+
2 — mục đích của lệnh là nhanh.
|
|
103
|
+
|
|
104
|
+
Đánh đổi phải nói ra: 1 lần chạy lại thì độ chắc chắn thấp hơn. Nên kết quả của lệnh này
|
|
105
|
+
**không** thay `qc_status` chính thức. Xem §3.6.
|
|
106
|
+
|
|
107
|
+
### 3.5 `product-gap` → báo bug NGAY
|
|
108
|
+
|
|
109
|
+
Khác `/qc-run-script` (đợi xác nhận hết mọi fail rồi mới file bug): ở đây, `product-gap` được xác
|
|
110
|
+
nhận thì gọi `/report-bug` **ngay lập tức**, không đợi chạy hết phạm vi. Severity đề xuất mặc
|
|
111
|
+
định Critical, nhãn `🔥 Smoke-fail`.
|
|
112
|
+
|
|
113
|
+
Vì sao: mục đích chính của lệnh là **báo sớm cho dev**. Đợi chạy hết toàn app rồi mới báo là mất
|
|
114
|
+
đúng cái giá trị đó.
|
|
115
|
+
|
|
116
|
+
### 3.6 Không thay `/qc-run-script`
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
Output: Smoke Test Summary — go / no-go ← bản tóm tắt nhẹ, gắn với lần chạy này
|
|
120
|
+
KHÔNG ghi qc_status chính thức vào sổ trace ← đó là việc của /qc-run-script + /qc-run-manualtest
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Lý do: `qc_status` là kết quả QC **chính thức**, và nó phải dựa trên một lần chạy đầy đủ với
|
|
124
|
+
retry ×2. Smoke chỉ là cổng nhanh trước đó.
|
|
125
|
+
|
|
126
|
+
Nếu ghi `qc_status` từ smoke thì Đợt 3 sẽ tính execution coverage trên dữ liệu chạy rút gọn —
|
|
127
|
+
tức là báo cáo "đã kiểm 85%" trên một tập test P0 mà thôi. Đó là làm sai chính chỉ số vừa xây.
|
|
128
|
+
|
|
129
|
+
### 3.7 Ai quyết định
|
|
130
|
+
|
|
131
|
+
🔴 no-go → **báo Lead/PM**, QC không tự quyết định hoãn hay tiếp tục release. QC đưa tín hiệu kỹ
|
|
132
|
+
thuật; quyết định là của Lead/PM — cùng nguyên tắc với verdict của Đợt 3.
|
|
133
|
+
|
|
134
|
+
## 4. Sửa file nào
|
|
135
|
+
|
|
136
|
+
| File | Việc |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `commands/{tên-đã-chốt}.tmpl` | **Mới** — `{{include:steps/gate.md}}`; **không** include `qc-scope` (xem §3.2); nhãn `*Checkpoint:*` |
|
|
139
|
+
| `skills/qc/qa-script-runner/smoke.md` | **Mới** — cách chạy theo tag, khuôn Smoke Test Summary |
|
|
140
|
+
| `steps/report-footer.md` | Bảng Next — thêm lệnh này vào nhóm utility, ghi rõ nó **ngoài** luồng tuần tự |
|
|
141
|
+
| `docs/04-reference/commands.md` | Thêm lệnh, **ghi rõ khác gì `/dev-smoke-test`** |
|
|
142
|
+
| `bin/qc-base-map.json` | Entry cho skill mới |
|
|
143
|
+
|
|
144
|
+
Nguồn: `D:\base\qcframework_proposal\command\qc-smoke-test.md` +
|
|
145
|
+
`skills\qc\qa-script-runner\smoke.md`. Gỡ comment provenance, thay gate cắt tay, đổi tên lệnh
|
|
146
|
+
theo §3.1.
|
|
147
|
+
|
|
148
|
+
## 5. Kiểm thế nào để biết đã xong
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
node bin/build.js && node bin/self-check.js && node test/run.js
|
|
152
|
+
ls core/commands/{tên-đã-chốt}.md
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Kiểm bằng tay — **ca 3 và 4 là quan trọng nhất**:
|
|
156
|
+
|
|
157
|
+
| Ca | Dựng thế nào | Kỳ vọng |
|
|
158
|
+
|---|---|---|
|
|
159
|
+
| 1 | Chạy phạm vi 1 feature có test `@smoke` | Chỉ chạy test `@smoke`, không chạy `@regression` khác |
|
|
160
|
+
| 2 | Chạy phạm vi 1 domain, rồi `all` | Phạm vi mở rộng đúng |
|
|
161
|
+
| **3** | Phạm vi **không có** test `@smoke` nào | Phải báo *"chưa có gì để kiểm"*, **không** báo go |
|
|
162
|
+
| **4** | Sau khi chạy smoke thành công, mở sổ trace | `qc_status` **KHÔNG** bị ghi bởi lệnh này |
|
|
163
|
+
| 5 | Ép 1 test `@smoke` fail nhất quán, xác nhận `product-gap` | `/report-bug` được gọi **ngay**, severity Critical, nhãn `🔥 Smoke-fail` |
|
|
164
|
+
|
|
165
|
+
Ca 4 là chỗ dễ làm sai nhất: rất tự nhiên để lệnh "ghi luôn kết quả cho tiện", và làm vậy là phá
|
|
166
|
+
chỉ số của Đợt 3.
|
|
167
|
+
|
|
168
|
+
## 6. Nếu bỏ qua thì hỏng gì
|
|
169
|
+
|
|
170
|
+
Không có gì vỡ — đây là utility, không nằm trong luồng tuần tự. Đội QC vẫn làm việc được, chỉ là
|
|
171
|
+
mỗi lần có build mới thì phải chạy `/qc-run-script` cho từng UC.
|
|
172
|
+
|
|
173
|
+
Cái mất là **thu hoạch của việc gắn tag `@smoke` ở d2-b2**: tag được gắn, được lưu trong script,
|
|
174
|
+
và không lệnh nào dùng. Tức là d2-b2 làm một việc không ai tiêu thụ — và sáu tháng sau sẽ có
|
|
175
|
+
người hỏi "cái tag này để làm gì?" rồi gỡ nó đi.
|
|
176
|
+
|
|
177
|
+
Rủi ro thứ hai nếu làm mà **không chốt tên**: hai lệnh "smoke test" với hai nghĩa. Người gọi sai
|
|
178
|
+
lệnh sẽ nhận một kết quả trông hợp lý nhưng trả lời câu hỏi khác — `/dev-smoke-test` báo "service
|
|
179
|
+
sống" không có nghĩa "tính năng lõi đúng".
|