@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,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.0
|
|
3
|
+
updated: 2026-09-04
|
|
4
|
+
ported_from: ui-automation-testing
|
|
5
|
+
upstream_path: skills/qa-tc-designer/shared/skill-decision-tree.md
|
|
6
|
+
upstream_sha: 57125f0c21512f2abcc55d00420e92c84c95fc8f
|
|
7
|
+
---
|
|
8
|
+
# Cây Quyết Định — Chọn Skill Đúng
|
|
9
|
+
|
|
10
|
+
> Đọc file này khi không chắc nên dùng skill nào. Trả lời lần lượt các câu hỏi từ trên xuống.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Bước 1 — Đối tượng test là gì?
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Đối tượng test
|
|
18
|
+
├── Hiển thị / validation / state của 1 screen → [A] Xét tiếp Bước 2 (UI vs Integration GUI)
|
|
19
|
+
├── User thực hiện workflow có mục tiêu nghiệp vụ → [B] Xét tiếp Bước 3 (E2E vs Integration)
|
|
20
|
+
├── 1 API endpoint (request/response/mã lỗi) → api-testcase-designer
|
|
21
|
+
├── NFR (performance/security/a11y/i18n) → nfr-testcase-designer
|
|
22
|
+
└── Luồng đa màn nằm trong 1 feature, không xuyên hệ thống → ui-testcase-designer (gui-feature)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Bước 2 — UI vs Integration GUI
|
|
28
|
+
|
|
29
|
+
**Câu hỏi:** TC này có thể chạy với dữ liệu tĩnh/mock mà vẫn valid không?
|
|
30
|
+
|
|
31
|
+
| Câu trả lời | Skill | Lý do (ISTQB) |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| **Có** — mock data đủ để verify | `ui-testcase-designer` | Component testing: verify UI behavior độc lập với backend |
|
|
34
|
+
| **Không** — phải có API thật/stub mới verify được | `integration/gui` trong `integration-testcase-designer` | Integration testing: verify contract UI layer ↔ API layer |
|
|
35
|
+
|
|
36
|
+
**Ví dụ phân biệt:**
|
|
37
|
+
|
|
38
|
+
| Tình huống | Skill | Lý do |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| Dropdown có placeholder, đóng khi click ngoài | UI | Behavior tĩnh, không cần API |
|
|
41
|
+
| Dropdown hiển thị đúng N item từ API response | Integration GUI | Verify data flow API → render |
|
|
42
|
+
| Form validate email format | UI | Client-side validation, không cần server |
|
|
43
|
+
| Form validate email "đã tồn tại" qua API | Integration GUI | Server-side validation = API call |
|
|
44
|
+
| Bảng danh sách render đúng số cột, format | UI | Layout/display |
|
|
45
|
+
| Bảng danh sách phản ánh đúng dữ liệu từ GET /list | Integration GUI | API data → UI sync |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Bước 3 — E2E vs Integration
|
|
50
|
+
|
|
51
|
+
**Câu hỏi:** Chủ thể của test là ai/cái gì?
|
|
52
|
+
|
|
53
|
+
| Câu trả lời | Skill | Lý do (ISTQB) |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| **User** hoàn thành 1 mục tiêu nghiệp vụ từ đầu đến cuối | `e2e-testcase-designer` | System testing: user journey perspective |
|
|
56
|
+
| **Module A ↔ Module B** trao đổi dữ liệu/contract đúng | `integration-testcase-designer` | Integration testing: system contract perspective |
|
|
57
|
+
|
|
58
|
+
**Câu hỏi phụ để phân biệt rõ hơn:**
|
|
59
|
+
|
|
60
|
+
> "Nếu tôi xóa hết step UI và chỉ test phần trao đổi dữ liệu, TC vẫn còn ý nghĩa không?"
|
|
61
|
+
> - Có → Integration (bản chất là test handshake, UI chỉ là trigger)
|
|
62
|
+
> - Không → E2E (user journey là trọng tâm, không thể tách ra)
|
|
63
|
+
|
|
64
|
+
**Ví dụ phân biệt:**
|
|
65
|
+
|
|
66
|
+
| Tình huống | Skill | Lý do |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| User đăng ký → nhận email → login → vào dashboard | E2E | User journey hoàn chỉnh, verify goal đạt được |
|
|
69
|
+
| User tạo lớp học → lớp hiện trong danh sách | E2E | End-to-end từ action đến kết quả nhìn thấy |
|
|
70
|
+
| Frontend gọi POST /enroll → DB ghi đúng bản ghi | Integration | Module contract: API ↔ DB, không phụ thuộc UI |
|
|
71
|
+
| Service A gửi event Kafka → Service B xử lý đúng | Integration | System-to-system, không liên quan user |
|
|
72
|
+
| Tạo đơn hàng qua UI → kiểm tra DB có bản ghi | Cả hai? | Nếu mục tiêu là "user đặt hàng thành công" → E2E; nếu mục tiêu là "POST /order ghi DB đúng" → Integration |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Tóm tắt nhanh
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Có API thật mới verify được?
|
|
80
|
+
└─ Không → UI
|
|
81
|
+
└─ Có, verify data flow 1 điểm → Integration GUI
|
|
82
|
+
└─ Có, user journey đầu-cuối → E2E
|
|
83
|
+
└─ Có, handshake 2 module/hệ thống → Integration
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Quy tắc ưu tiên khi vẫn còn mơ hồ
|
|
89
|
+
|
|
90
|
+
1. **UI ưu tiên nhỏ nhất:** viết TC nhỏ nhất có thể verify 1 behavior cụ thể.
|
|
91
|
+
2. **Integration GUI** khi có server-side behavior: validation, lookup, list.
|
|
92
|
+
3. **E2E chỉ cho P0/P1 critical path** (ISTQB Test Pyramid: E2E ít nhất, UI/Unit nhiều nhất).
|
|
93
|
+
4. **Integration** khi tách được khỏi UI và vẫn có giá trị test.
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.0
|
|
3
|
+
updated: 2026-09-04
|
|
4
|
+
ported_from: ui-automation-testing
|
|
5
|
+
upstream_path: skills/qa-tc-designer/shared/tc-metadata-format.md
|
|
6
|
+
upstream_sha: a31d66a7a8dab19cf821c9102a88282b09e16cb9
|
|
7
|
+
---
|
|
8
|
+
# TC Metadata Format (Chuẩn chung)
|
|
9
|
+
|
|
10
|
+
## ⚠️ Nguyên tắc format file TC (BẮT BUỘC — QC yêu cầu)
|
|
11
|
+
|
|
12
|
+
- **TOÀN BỘ file TC viết dạng LIST — KHÔNG dùng bảng Markdown** (không ký tự `|`). Áp dụng cho: Test Steps, Tổng hợp TC, Trace Matrix, TC bị Block, metadata đầu file. *(Chỉ file TC output; tài liệu skill này giữ bảng minh hoạ bình thường.)*
|
|
13
|
+
- **Gom nhóm theo LOẠI test** (không theo luồng nghiệp vụ): thứ tự cố định **GUI → Validation → Functional → Integration → NFR → E2E** (xem §Phân nhóm).
|
|
14
|
+
- Khi tái cấu trúc/đảo nhóm: **GIỮ NGUYÊN mã `TC_<FEATURE>_NNN`**, chỉ đổi vị trí (mã không cần liền mạch theo thứ tự đọc).
|
|
15
|
+
- **App/Web là 2 bộ TC ĐỘC LẬP, mỗi nền chạy FULL business-logic** — trùng logic giữa 2 nền là chủ đích, KHÔNG tính duplicate defect; mỗi file phải độc lập đạt full coverage — mỗi nền một thư mục riêng (`{qc_dir}/{TICKET-ID}/web/` vs `/app/`), và sổ trace cũng tách theo nền.
|
|
16
|
+
|
|
17
|
+
## ⚠️ Quy tắc "1 bullet Expected = 1 TC ĐỘC LẬP" (BẮT BUỘC — QC yêu cầu, testcase ATOMIC)
|
|
18
|
+
|
|
19
|
+
> **Cập nhật 2026-07-09 (QC chốt — ĐẢO rule cũ):** trước đây cho GỘP nhiều checkpoint cùng-1-hành-vi vào 1 Expected nhiều bullet. **Nay: mỗi Expected chỉ ĐÚNG 1 bullet; mọi TC nhiều bullet phải TÁCH thành nhiều TC độc lập.** KHÔNG còn ngoại lệ "gộp checkpoint".
|
|
20
|
+
|
|
21
|
+
- **Test Steps chỉ chứa hành động.** Mỗi bước là `[Action]` hoặc `[Verify]` THUẦN — **KHÔNG gắn `→ [Expected] ...` ở cuối bước.** Oracle nằm ở `#### Expected Result`.
|
|
22
|
+
- **Atomic = 1 OUTCOME, không chỉ đếm "1 bullet".** Mỗi TC đúng 1 `#### Expected Result` với ĐÚNG 1 bullet. Bullet compound (`A, B`) **chỉ OK khi cùng 1 outcome** (vd "chỉ 5 slide: đúng 5 dots; slide 6,7 không xuất hiện" · "form hiển thị đủ 3 trường"). **Bullet nối bằng `;` kiểu "khẳng-định + phủ-định/outcome độc lập"** (vd "Có lối Đăng nhập**;** KHÔNG có OTP" · "sang routing**;** không OTP") **= 2 outcome → TÁCH tiếp** — soi nhanh khi review: grep bullet chứa `;` + `không/KHÔNG`. Tuyệt đối KHÔNG ≥2 bullet trong 1 Expected.
|
|
23
|
+
- **Nhiều điểm-kiểm / outcome → TÁCH thành nhiều TC ĐỘC LẬP, mỗi TC 1 bullet.** Áp cho MỌI trường hợp: outcome độc lập (BVA/Decision-rule/tiền đề khác) LẪN nhiều checkpoint của **cùng 1 hành vi** (VD "màn hiển thị đủ ô A + nút B + lối C" → **3 TC**, không còn gộp).
|
|
24
|
+
- **⚠️ Chế độ ATOMIC TỐI ĐA (QC chốt 2026-07-14 — GIẢI mâu thuẫn 2 gạch trên):** khi user YÊU CẦU THẲNG "tách nhỏ nhất", **completeness list nổ từng thành phần** (kể cả "form đủ 3 trường" → **3 TC**; thẻ khung giờ đủ 5 field → 5 TC) — tức áp gạch "→ 3 TC", KHÔNG dùng ngoại lệ "compound cùng-1-outcome" cho completeness. **NHƯNG GIỮ 1 TC** cho: *predicate đa-điều-kiện định-nghĩa-1-khái-niệm* ("chưa bắt đầu & ≥10' = slot-hợp-lệ"), *ngưỡng* ("≥44pt·48dp", "WCAG AA ≥4.5:1"), *exclusivity* chọn-một, *qualifier* ("không chỉ bằng màu"). Trước khi thực thi: **hỏi 1 câu chốt ranh giới completeness** (quy mô ~95 vs ~130 TC) + dựng **bản đồ tách** (số mảnh/TC cha) rồi mới ghi. Chi tiết + thủ tục verify: `precision-rules.md §2.1`. (Mặc định lúc SINH MỚI vẫn cho compound cùng-1-outcome; chế độ tối đa chỉ khi user yêu cầu.)
|
|
25
|
+
- **Mỗi TC tách là testcase ĐỘC LẬP** — KHÔNG phải "con", KHÔNG đánh `(1/N)`, KHÔNG suffix `001a/001b`:
|
|
26
|
+
- **Tiêu đề mô tả riêng** self-contained (ngữ cảnh màn/hành vi + điểm được kiểm), heading khớp `**Title:**`.
|
|
27
|
+
- **Giữ FULL Test Steps** — lặp đủ bước để tới trạng thái assert (KHÔNG cắt bước theo từng bullet).
|
|
28
|
+
- Metadata (Feature/Module/Priority/Status/Tags/Trace) + Preconditions **copy nguyên** từ TC gốc.
|
|
29
|
+
- **`#### Teardown` là SECTION riêng, KHÔNG phải bullet Expected.** Khi tách bằng script: parse `#### Teardown` riêng — **đừng nuốt bullet teardown vào `#### Expected Result`** (bug đã gặp → sinh "TC teardown giả" có Expected="Xoá dữ liệu test…", steps↔expected mâu thuẫn, không pass/fail được). Mỗi TC tách **TẠO bản ghi DB** (register/tạo tài khoản mới) phải giữ `#### Teardown` riêng; flow **login trên seed** không cần.
|
|
30
|
+
- **Renumber TUẦN TỰ toàn dải** khi tách. Đổi số cascade → **đồng bộ NGAY**: `Mục lục` (range mỗi nhóm) · `Tổng hợp` (count + priority) · note `· N TC` mỗi Nhóm · `Trace Matrix` (**expand range** cũ thành list id mới) · `TC bị Block` (map id cũ → các id con). Dùng script xác định + backup trước–sau (agent ghi file lớn hay lỗi âm thầm — xem gạch cuối mục này).
|
|
31
|
+
- **Assertion loại-trừ (KHÔNG hiển thị / KHÔNG xảy ra) là oracle THẬT** → mỗi cái là 1 bullet = 1 TC riêng. Khi tách bằng script cơ học, **kiểm lại không đánh rơi** (đối chiếu backup).
|
|
32
|
+
- **Bullet metadata KHÔNG phải outcome.** `- Mobile: \`@pytest.mark.flaky(...)\`` lọt trong Expected là **marker** → loại khỏi phép đếm outcome, **dời ra meta** (`- **Chạy (mobile):** …`). Đếm nhầm marker là "bullet thứ 2" sẽ kết luận SAI rằng file cần tách. Reviewer cờ `[MARKER_IN_EXPECTED]`.
|
|
33
|
+
- **⚠️ Trước khi viết script tách/renumber — biết 5 bẫy này trước.** 5 bug **không throw exception** (script "chạy xong" rồi ghi file hỏng):
|
|
34
|
+
1. **Double-remap**: transformer vừa *sinh* ID vừa *remap* ID → regex khớp luôn **heading vừa sinh** → ID trùng. **Chỉ remap `preamble` + `tail`, KHÔNG remap phần vừa sinh.**
|
|
35
|
+
2. **2 namespace ID**: liệt kê namespace TRƯỚC khi rename (vd FEAT-01-2: nội bộ `TC_FEAT-01-2_{APP,WEB}_NNN` remap ĐƯỢC · **master** `TC_NNN`/`TC_FEAT-01-2_NNN` ở BLOCKED/TODO **KHÔNG remap**). Verify: `diff` tập master-ID backup↔new.
|
|
36
|
+
3. **Replace-section làm rơi dòng chưa mô hình hoá** (dòng `>` note trong Expected). Giữ trailing note.
|
|
37
|
+
4. **Tiêu đề cha ≠ prefix con**: auto-title `"<heading cha> — <bullet>"` nhân đôi khi heading cha liệt kê cả 2 vế.
|
|
38
|
+
5. **Invariant phải gồm DIFF ĐỊNH DẠNG**, không chỉ đếm: liên tục ID · 0 trùng · 1 bullet/TC · oracle lossless (diff vs backup) · 0 dead-ref · **0 dòng-trống-kép/nhiễu whitespace** · master-ID không đổi.
|
|
39
|
+
- **Có file ĐÃ atomic sẵn** — phân tích phân bố bullet/TC trước, đừng tách lấy được. Quy trình bền: sửa **source/backup** → **tái sinh** bằng script xác định → verify → sai thì restore.
|
|
40
|
+
|
|
41
|
+
## Content Oracle — exact-copy phải self-contained + đúng nguồn
|
|
42
|
+
|
|
43
|
+
- Chuỗi text spec-defined mà TC assert (tiêu đề màn, nhãn, copy nút, thông báo lỗi) → **ghi nguyên văn trong Expected Result** để TC tự chứa, người đọc không phải mở spec mới biết kỳ vọng.
|
|
44
|
+
- **BẮT BUỘC kiểm nguồn ĐÚNG feature trước khi chép:** mở design-spec/PRD của **chính feature đó** và xác nhận chuỗi tồn tại. **KHÔNG mượn chuỗi từ feature anh em** — VD copy P2 của FEAT-01-1 là *"Việc tạo **tài khoản** đang tạm thời bị gián đoạn…"* còn FEAT-01-2 là *"Việc tạo **câu hỏi** đang tạm thời bị gián đoạn…"*; chép nhầm → oracle sai.
|
|
45
|
+
- Chuỗi **chưa** có trong PRD/design-spec (chỉ ở Figma / chưa chốt) → **KHÔNG bịa oracle**: để trống + gắn `🚫 Block: [GAP-UC{N}-{nnn}]` hoặc `Status: PENDING`, ghi rõ chờ ai chốt.
|
|
46
|
+
- Cờ "MIỄN coverage / thuộc Design Spec" trong BDD **không** cấm assert nếu PRD/design-spec vẫn enumerate đủ chuỗi — vẫn được đưa vào Expected Result; chỉ hạ về mức generic khi thực sự không có nguồn chốt.
|
|
47
|
+
|
|
48
|
+
## Metadata (bắt buộc, dạng list)
|
|
49
|
+
|
|
50
|
+
Mỗi trường 1 dòng, không bảng, không emoji dư:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
- **Title:** <tên TC ngắn gọn>
|
|
54
|
+
- **Feature:** <tên feature>
|
|
55
|
+
- **Priority:** P0 | P1 | P2
|
|
56
|
+
- **Status:** Draft
|
|
57
|
+
- **Author:** AI
|
|
58
|
+
- **Tags:** <lane>, <loại: smoke|sanity|regression>, <feature-tag>
|
|
59
|
+
- **Trace:** BR-xx (ID gốc trong PRD/BDD ở `{paths.specs_dir}`)
|
|
60
|
+
- **🚫 Block:** [GAP-UC{N}-{nnn}](../DOC_GAP.md) — <lý do> *(chỉ khi có)*
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Quy tắc Trace & Block
|
|
64
|
+
|
|
65
|
+
- **Trace:** ghi `BR-xx` lấy từ ID trong `{paths.specs_dir}`; không có BR → `⚠️ Chưa có Business Rule`.
|
|
66
|
+
- **🚫 Block:** TC phụ thuộc gap **vẫn viết đủ** + ghi `[GAP-UC{N}-{nnn}] — lý do`; chưa chạy tới khi gap Answered.
|
|
67
|
+
|
|
68
|
+
## Cấu trúc TC
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
### [TC_ID] — [Tên TC]
|
|
72
|
+
- **Title:** ...
|
|
73
|
+
- **Feature:** ...
|
|
74
|
+
- **Priority:** P0|P1|P2
|
|
75
|
+
- **Status:** Draft
|
|
76
|
+
- **Author:** AI
|
|
77
|
+
- **Tags:** ...
|
|
78
|
+
- **Trace:** BR-xx
|
|
79
|
+
- **🚫 Block:** (nếu có)
|
|
80
|
+
|
|
81
|
+
#### Preconditions
|
|
82
|
+
- ...
|
|
83
|
+
|
|
84
|
+
#### Test Data
|
|
85
|
+
- field: giá trị
|
|
86
|
+
|
|
87
|
+
#### Test Steps
|
|
88
|
+
1. [Action] ... ← chỉ hành động; KHÔNG gắn "→ [Expected] ..."
|
|
89
|
+
2. [Verify] ... ← chỉ điểm quan sát; oracle nằm ở Expected Result
|
|
90
|
+
|
|
91
|
+
#### Expected Result
|
|
92
|
+
- <1 bullet kết quả cuối cụ thể, đo được — xem §"1 Expected Result / TC">
|
|
93
|
+
|
|
94
|
+
#### Teardown ← CHỈ khi TC tạo/sửa bản ghi hoặc state THẬT
|
|
95
|
+
- <cách cleanup: API DELETE / reset tài khoản test / fixture / `⚠️ Manual teardown required`>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Quy tắc Teardown (khi nào CÓ / KHÔNG)
|
|
99
|
+
|
|
100
|
+
- **CÓ Teardown** chỉ khi TC tạo/sửa **bản ghi DB hoặc state thật** tồn tại sau test (vd: ghi phân khúc vào tài khoản test, tạo bản ghi qua API thật).
|
|
101
|
+
- **KHÔNG cần Teardown** khi TC chỉ cấu hình **mock / route intercept / network monitoring** — việc reset mock về default là trách nhiệm của **fixture `conftest.py`** (scope `function` tự teardown mỗi test). Ghi "Reset mock về default" trong từng TC là **thừa** → không thêm.
|
|
102
|
+
- Lane test qua mock hoàn toàn (vd lane UI/E2E khi API SKIP) → hầu hết TC KHÔNG có Teardown; chỉ TC chạm tài khoản/state thật mới có.
|
|
103
|
+
|
|
104
|
+
## Phân nhóm TC & đánh số nhóm (chuẩn chung)
|
|
105
|
+
|
|
106
|
+
TC trong file được gom theo **nhóm phân loại nội dung** và đánh **số CỐ ĐỊNH theo LOẠI** — số nhóm gắn cứng với loại, loại KHÔNG có TC thì **BỎ TRỐNG số đó** (KHÔNG đánh tuần tự lại). *(QC chốt 2026-07-08 — thay quy ước "liên tục" cũ.)*
|
|
107
|
+
|
|
108
|
+
Gom theo **LOẠI test**, số nhóm CỐ ĐỊNH theo loại, chỉ tạo nhóm THỰC SỰ có TC:
|
|
109
|
+
|
|
110
|
+
1. **GUI** — UI tĩnh, label, layout, placeholder, icon, trạng thái hiển thị (không đổi state).
|
|
111
|
+
2. **Validation** — field-level: validate input, EP/BVA, biên, error message, trạng thái nút enabled/disabled theo điều kiện, read-only, ràng buộc.
|
|
112
|
+
3. **Functional** — nghiệp vụ/luồng: business logic, submit/navigation, decision table, use case hoàn chỉnh.
|
|
113
|
+
4. **Integration** — bắt tay ≥2 module/dịch vụ (kể cả qua mock): đọc/ghi cross-service, handshake, data flow, contract.
|
|
114
|
+
5. **NFR** — phi chức năng: performance, a11y/keyboard, WCAG, security, i18n, compatibility.
|
|
115
|
+
6. **E2E** — journey đầu-cuối nhiều use case.
|
|
116
|
+
|
|
117
|
+
**Quy tắc đánh số & phân nhóm:**
|
|
118
|
+
- Gán số CỐ ĐỊNH theo loại: **GUI=1 · Validation=2 · Functional=3 · Integration=4 · NFR=5 · E2E=6**. Loại KHÔNG có TC → **BỎ TRỐNG số đó**. VD file chỉ có GUI + Validation + Functional + E2E → `Nhóm 1 — GUI` / `Nhóm 2 — Validation` / `Nhóm 3 — Functional` / **`Nhóm 6 — E2E`** (bỏ trống 4 Integration, 5 NFR). **E2E LUÔN là Nhóm 6, NFR luôn 5, Integration luôn 4** — KHÔNG dồn số.
|
|
119
|
+
- Phân vân **Validation vs Functional**: chỉ test trạng thái field/nút/biên → Validation; có luồng/submit/navigation/logic → Functional. **KHÔNG tạo nhóm "Tương tác"/"Happy Path" riêng.**
|
|
120
|
+
- Lane chỉ có functional (API/Integration/NFR, không có GUI) → bỏ nhóm GUI, bắt đầu từ nhóm phù hợp.
|
|
121
|
+
- **GIỮ NGUYÊN mã TC** khi gom/đảo nhóm — chỉ đổi vị trí; mã không cần liền mạch theo thứ tự đọc.
|
|
122
|
+
- Mọi tham chiếu số nhóm trong file (Trace Matrix, ghi chú) phải khớp số CỐ ĐỊNH đã gán.
|
|
123
|
+
|
|
124
|
+
## Cuối file (bắt buộc)
|
|
125
|
+
|
|
126
|
+
Cả 2 mục dạng LIST (không bảng):
|
|
127
|
+
|
|
128
|
+
```markdown
|
|
129
|
+
## Trace Matrix
|
|
130
|
+
- **BR-xx:** TC_001, TC_002
|
|
131
|
+
- **⚠️ BR-yy:** — (Chưa có TC)
|
|
132
|
+
|
|
133
|
+
## TC bị Block
|
|
134
|
+
- **GAP-03** — TC_005: Chờ openapi.yaml
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
> Không thêm section `#### Python Test Mapping`. Bỏ nội dung gạch ngang.
|
|
138
|
+
|
|
139
|
+
> ⚠️ **Bổ sung khi Edit thêm TC mới:** nối bullet mới **ngay liền sau bullet cuối** của list (Trace Matrix / TC bị Block), KHÔNG chèn dòng trắng giữa các bullet. Kiểm lại số TC khớp sau khi thêm.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Tài liệu shared liên quan (bắt buộc nạp khi viết TC)
|
|
144
|
+
|
|
145
|
+
| File | Mục đích |
|
|
146
|
+
|---|---|
|
|
147
|
+
| `shared/action-keywords-glossary.md` | Từ điển action keywords chuẩn — Click/Enter/Verify/Assert... |
|
|
148
|
+
| `shared/precision-rules.md` | Quy tắc lượng hóa Expected Result, cấm từ mơ hồ, đơn vị chuẩn |
|
|
149
|
+
| `shared/duplicate-check-procedure.md` | Quy trình kiểm tra TC trùng lặp trước khi viết mới |
|
|
150
|
+
| `shared/implicit-scenarios.md` | Danh sách implicit scenarios cần xét thêm |
|
|
151
|
+
| `shared/skill-decision-tree.md` | Cây quyết định chọn đúng skill |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Gap Escalation Path (Xử lý khi TC bị Block)
|
|
156
|
+
|
|
157
|
+
Khi TC có `🚫 Block: [GAP-UC{N}-{nnn}]` — thực hiện theo timeline:
|
|
158
|
+
|
|
159
|
+
| Thời điểm | Hành động |
|
|
160
|
+
|---|---|
|
|
161
|
+
| **T+0 (phát hiện gap)** | Ghi GAP vào `DOC_GAP.md` — ID, loại, mô tả, tác động, nguồn |
|
|
162
|
+
| **T+2 (2 ngày)** | Chưa có phản hồi → ping QA Lead / PO |
|
|
163
|
+
| **T+5 (5 ngày)** | Vẫn chưa có → ghi **assumption tạm thời** vào TC bị Block |
|
|
164
|
+
| **T+7 (7 ngày)** | Leo thang PO/PM — gap ảnh hưởng sprint delivery |
|
|
165
|
+
|
|
166
|
+
### Format Assumption khi gap chưa được trả lời (T+5):
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
⚠️ Assumption (T+5): API trả về HTTP 422 khi tên lớp trùng — dựa trên pattern UC1.
|
|
170
|
+
Nếu behavior khác → cập nhật Expected Result và re-review.
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Quy trình khi gap được giải quyết (Answered):
|
|
174
|
+
1. Cập nhật `DOC_GAP.md`: status → `Answered`, ghi note giải thích.
|
|
175
|
+
2. Bỏ `🚫 Block` trong TC → cập nhật Expected Result nếu có assumption sai.
|
|
176
|
+
3. Thông báo `qa-tc-reviewer` review lại TC.
|
|
177
|
+
4. Nếu answer thay đổi scope → tạo TC mới hoặc split TC hiện tại.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
# Phần riêng của framework *(B12 — không có ở upstream)*
|
|
182
|
+
|
|
183
|
+
Mọi thứ trên là chuẩn của đội QC. Bốn thứ dưới đây là **của framework**, và mọi skill tầng test
|
|
184
|
+
đều theo — đừng lặp lại chúng trong từng skill.
|
|
185
|
+
|
|
186
|
+
## Hai file TC, chia theo "có qua giao diện"
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
{qc_artifact_dir}test-cases/
|
|
190
|
+
├── TC_<FEATURE>.Test.md ← mặc định
|
|
191
|
+
│ ## Nhóm 1 — GUI ## Nhóm 4 — Integration (qua UI)
|
|
192
|
+
│ ## Nhóm 2 — Validation ## Nhóm 5 — NFR
|
|
193
|
+
│ ## Nhóm 3 — Functional ## Nhóm 6 — E2E
|
|
194
|
+
└── TC_<FEATURE>_API.Test.md ← cờ --api
|
|
195
|
+
## Nhóm 1 — Endpoint
|
|
196
|
+
## Nhóm 2 — Integration API/DB/Kafka
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Câu hỏi phân file:** *"TC này verify được mà **không cần UI** không?"*
|
|
200
|
+
→ **có** = file API · **không** = file giao diện. *(Trùng Bước 2 của `skill-decision-tree.md`.)*
|
|
201
|
+
|
|
202
|
+
⚠️ **Đuôi file là `.Test.md`, không phải `.md`.** `/qc-run-test` và `/qc-review` tìm `*.Test.md`;
|
|
203
|
+
ghi ra file thiếu phần `.Test` là ghi ra thứ **không trạm nào tìm thấy**, và không có gì báo lỗi.
|
|
204
|
+
|
|
205
|
+
Đánh số `TC_<FEATURE>_NNN` **liên tục toàn file**, không đánh lại theo từng nhóm.
|
|
206
|
+
|
|
207
|
+
## Trace — hai hệ, ghi cả hai
|
|
208
|
+
|
|
209
|
+
| Trường | Dạng | Vì sao cần |
|
|
210
|
+
|---|---|---|
|
|
211
|
+
| `**Trace:**` | `[BR-xx](../REQUIREMENT_ANALYSIS.md#3-business-rules)` — không có BR → `⚠️ Chưa có Business Rule` | truy về luật nghiệp vụ |
|
|
212
|
+
| `**@trace.verifies:**` | `{UC-ID}-SC{N}` (lấy từ `@trace.scenario` của file `.feature`) | **join key** để `/qc-run-test` ghi `qc_status` theo từng kịch bản vào sổ trace |
|
|
213
|
+
|
|
214
|
+
Một `SC` map được nhiều TC. **Thiếu `@trace.verifies` thì kết quả chạy không vào được sổ** — TC
|
|
215
|
+
vẫn chạy, vẫn pass/fail, nhưng không ai biết nó phủ kịch bản nào.
|
|
216
|
+
|
|
217
|
+
Cuối file: **Trace matrix** (BR ↔ TC ↔ SC) + **danh sách TC bị block** — cả hai **dạng danh
|
|
218
|
+
sách**, không bảng (§Nguyên tắc format file đầu tài liệu này).
|
|
219
|
+
|
|
220
|
+
## `🚫 Block` trỏ về file gap cấp PRD
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
- **🚫 Block:** [GAP-UC{N}-{nnn}](../DOC_GAP.md) — <lý do>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
`DOC_GAP.md` nằm ở **thư mục cha** của `test-cases/`, nên liên kết đi lên một cấp. Mã gap mang
|
|
227
|
+
UC (`GAP-UC1-001`) vì một file gap phủ cả PRD.
|
|
228
|
+
|
|
229
|
+
## Dòng `Test-ID attribute`
|
|
230
|
+
|
|
231
|
+
Ghi một dòng ở phần metadata **đầu file**:
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
Test-ID attribute: {attr}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Đọc `@trace.testid_attr` từ header tech-doc gộp (do `/map-testids` ghi). Bảng §4.5.6 chỉ cho
|
|
238
|
+
**giá trị** test-id; đây là **tên thuộc tính** chứa chúng. `/qc-run-test` cần nó để cấu hình
|
|
239
|
+
locator, `/qc-review` cần nó để biết selector trong script có đúng hợp đồng không.
|
|
240
|
+
|
|
241
|
+
Thiếu field trong tech-doc → ghi `Test-ID attribute: — (thiếu @trace.testid_attr, chạy /map-testids)`.
|
|
242
|
+
**Đừng bỏ trống và đừng tự đoán** — đoán sai thì mọi locator trượt 100%, và trượt vì lý do
|
|
243
|
+
không liên quan gì tới thứ đang test.
|
|
@@ -102,5 +102,5 @@ tiền không đáng.
|
|
|
102
102
|
|---|---|---|---|---|---|
|
|
103
103
|
| … | 2 · tiền | Cao | Cao | **P0** | functional/api + giá trị biên; e2e luồng thanh toán |
|
|
104
104
|
|
|
105
|
-
Mỗi dòng rủi ro phải **trỏ được về BR-xx hoặc GAP-
|
|
105
|
+
Mỗi dòng rủi ro phải **trỏ được về `BR-xx` hoặc `GAP-UC{N}-{nnn}`** đã có ở `REQUIREMENT_ANALYSIS.md` /
|
|
106
106
|
`DOC_GAP.md` — rủi ro không neo vào yêu cầu nào là rủi ro tự nghĩ ra.
|
|
@@ -84,4 +84,12 @@ F. CONVENTION:
|
|
|
84
84
|
|
|
85
85
|
Mỗi issue: `file:line` | severity | mô tả | suggestion fix.
|
|
86
86
|
Severity: 🔴 fix ngay (missing cleanup, dữ liệu không verify cross-module, shortcut journey) · 🟠 quan trọng (timeout thiếu, assertion chỉ ở bước cuối) · 🟡 nhỏ (style, docstring/title sai).
|
|
87
|
-
|
|
87
|
+
**Điểm `XX/100`** — ánh xạ mức độ sang điểm trừ: 🔴 = `FAIL` (−5đ) · 🟠 = `WARN` (−2đ) ·
|
|
88
|
+
🟡 = ghi nhận, không trừ. ≥80 đạt · 60–79 cần cải thiện · <60 không đạt.
|
|
89
|
+
**Verdict:** `≥80` VÀ không còn 🔴 → **`APPROVED`**; ngược lại **`NEEDS_FIX`**.
|
|
90
|
+
|
|
91
|
+
**Ghi vào `{qc_artifact_dir}test-cases/REVIEW_<FEATURE>.md`** — thêm một hàng vào bảng Tổng quan
|
|
92
|
+
(cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
|
|
93
|
+
Khuôn + quy tắc ghi: `../shared/review-file-template.md`.
|
|
94
|
+
|
|
95
|
+
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-run-test`.
|
|
@@ -39,7 +39,15 @@ Review session note sau khi test, coaching QC cải thiện kỹ năng.
|
|
|
39
39
|
|
|
40
40
|
## Output
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
**Điểm `XX/100`** — ánh xạ mức độ sang điểm trừ: 🔴 = `FAIL` (−5đ) · 🟠 = `WARN` (−2đ) ·
|
|
43
|
+
🟡 = ghi nhận, không trừ. ≥80 đạt · 60–79 cần cải thiện · <60 không đạt.
|
|
44
|
+
**Verdict:** `≥80` VÀ không còn 🔴 → **`APPROVED`**; ngược lại **`NEEDS_FIX`**.
|
|
45
|
+
|
|
46
|
+
**Ghi vào `{qc_artifact_dir}test-cases/REVIEW_<FEATURE>.md`** — thêm một hàng vào bảng Tổng quan
|
|
47
|
+
(cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
|
|
48
|
+
Khuôn + quy tắc ghi: `../shared/review-file-template.md`.
|
|
49
|
+
|
|
50
|
+
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-run-test`.
|
|
43
51
|
Mỗi tiêu chí: ✅/⚠️/❌ + feedback cụ thể
|
|
44
52
|
Top 3 improvement suggestions (coaching tone)
|
|
45
53
|
Đề xuất charter tiếp theo nếu chưa đủ coverage
|
|
@@ -98,4 +98,12 @@ empty step `:pass` · test gọi `_private()` · Counter≠Pagination → xfail
|
|
|
98
98
|
|
|
99
99
|
Mỗi issue: file:line | severity | mô tả | suggestion fix.
|
|
100
100
|
Severity: 🔴 fix ngay (sai logic, POM breach, silent fail) · 🟠 quan trọng (fragile selector, wrong column, missing assert) · 🟡 nhỏ (style, thừa wait, orphan constant).
|
|
101
|
-
|
|
101
|
+
**Điểm `XX/100`** — ánh xạ mức độ sang điểm trừ: 🔴 = `FAIL` (−5đ) · 🟠 = `WARN` (−2đ) ·
|
|
102
|
+
🟡 = ghi nhận, không trừ. ≥80 đạt · 60–79 cần cải thiện · <60 không đạt.
|
|
103
|
+
**Verdict:** `≥80` VÀ không còn 🔴 → **`APPROVED`**; ngược lại **`NEEDS_FIX`**.
|
|
104
|
+
|
|
105
|
+
**Ghi vào `{qc_artifact_dir}test-cases/REVIEW_<FEATURE>.md`** — thêm một hàng vào bảng Tổng quan
|
|
106
|
+
(cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
|
|
107
|
+
Khuôn + quy tắc ghi: `../shared/review-file-template.md`.
|
|
108
|
+
|
|
109
|
+
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-run-test`.
|
|
@@ -88,4 +88,12 @@ F. CONVENTION:
|
|
|
88
88
|
|
|
89
89
|
Mỗi issue: `file:line` | severity | mô tả | suggestion fix.
|
|
90
90
|
Severity: 🔴 fix ngay (mock thay real call, missing DB verify, no cleanup) · 🟠 quan trọng (thiếu error state, hardcode ID, timeout ngắn) · 🟡 nhỏ (style, marker thiếu sub-domain).
|
|
91
|
-
|
|
91
|
+
**Điểm `XX/100`** — ánh xạ mức độ sang điểm trừ: 🔴 = `FAIL` (−5đ) · 🟠 = `WARN` (−2đ) ·
|
|
92
|
+
🟡 = ghi nhận, không trừ. ≥80 đạt · 60–79 cần cải thiện · <60 không đạt.
|
|
93
|
+
**Verdict:** `≥80` VÀ không còn 🔴 → **`APPROVED`**; ngược lại **`NEEDS_FIX`**.
|
|
94
|
+
|
|
95
|
+
**Ghi vào `{qc_artifact_dir}test-cases/REVIEW_<FEATURE>.md`** — thêm một hàng vào bảng Tổng quan
|
|
96
|
+
(cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
|
|
97
|
+
Khuôn + quy tắc ghi: `../shared/review-file-template.md`.
|
|
98
|
+
|
|
99
|
+
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-run-test`.
|
|
@@ -123,4 +123,12 @@ def test_compatibility(browser_name, playwright):
|
|
|
123
123
|
|
|
124
124
|
Mỗi issue: `file:line` | severity | mô tả | suggestion fix.
|
|
125
125
|
Severity: 🔴 fix ngay (assertion không có ngưỡng, gọi production endpoint, hardcode credential) · 🟠 quan trọng (ngưỡng không khớp TC, thiếu parametrize, không teardown data) · 🟡 nhỏ (style, marker thiếu sub-domain, docstring thiếu ngưỡng).
|
|
126
|
-
|
|
126
|
+
**Điểm `XX/100`** — ánh xạ mức độ sang điểm trừ: 🔴 = `FAIL` (−5đ) · 🟠 = `WARN` (−2đ) ·
|
|
127
|
+
🟡 = ghi nhận, không trừ. ≥80 đạt · 60–79 cần cải thiện · <60 không đạt.
|
|
128
|
+
**Verdict:** `≥80` VÀ không còn 🔴 → **`APPROVED`**; ngược lại **`NEEDS_FIX`**.
|
|
129
|
+
|
|
130
|
+
**Ghi vào `{qc_artifact_dir}test-cases/REVIEW_<FEATURE>.md`** — thêm một hàng vào bảng Tổng quan
|
|
131
|
+
(cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
|
|
132
|
+
Khuôn + quy tắc ghi: `../shared/review-file-template.md`.
|
|
133
|
+
|
|
134
|
+
**KHÔNG tự sửa code** — chỉ nêu `file:line` + cách sửa. Người sửa là `/qc-run-test`.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.0
|
|
3
|
+
updated: 2026-09-04
|
|
4
|
+
ported_from: ui-automation-testing
|
|
5
|
+
upstream_path: skills/qa-tc-reviewer/shared/read-doc-gap-inputs.md
|
|
6
|
+
upstream_sha: 3caa1562399ef1167ac2dc620add2c6c729e55df
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Thủ tục: Nạp TOÀN BỘ tài liệu input từ DOC_GAP (BẮT BUỘC trước khi review TC)
|
|
10
|
+
|
|
11
|
+
> Mục tiêu: reviewer phải đọc **đúng bộ tài liệu nguồn mà `/qc-analyze` đã dùng** để dựng TEST_PLAN + DOC_GAP — không chỉ file domain. Chỉ khi nắm đủ ngữ cảnh nguồn mới bắt được TC hiểu sai nghiệp vụ, thiếu case, hoặc trace sai spec.
|
|
12
|
+
|
|
13
|
+
## Các bước
|
|
14
|
+
|
|
15
|
+
1. **Tìm file DOC_GAP** tại `{qc_artifact_dir}DOC_GAP.md` — **một file cho cả PRD**, các UC là các hàng phân biệt bằng cột `UC`. Không có → chạy `/qc-analyze {TICKET-ID} {platform}` trước; **đừng soát TC trên ngữ cảnh thiếu** (soát mù thì kết luận "0 lỗi" là vô nghĩa).
|
|
16
|
+
2. **`Read` toàn bộ DOC_GAP.** Định vị mục **`## Tài liệu đầu vào đã đọc để phân tích`** — bảng liệt kê **đầy đủ** file nguồn (cột "Đường dẫn", tính từ `{paths.specs_dir}/`), kèm vai trò & phiên bản.
|
|
17
|
+
3. **`Read` TỪNG file trong bảng đó** — ghép prefix `{paths.specs_dir}/` vào đường dẫn ở cột. Đọc HẾT, không bỏ sót dòng nào (spec chính + ref bắt buộc + transitive 1-hop). Nếu bảng liệt kê phiên bản, kiểm tra file hiện tại khớp; lệch phiên bản → ghi chú vào REVIEW.
|
|
18
|
+
4. **Đối chiếu chéo:** file nào có mặt ở header DOC_GAP ("Tài liệu nguồn (spec chính)"/"Coverage Attestation") mà thiếu trong bảng → vẫn đọc.
|
|
19
|
+
5. Chỉ sau khi đã nạp xong toàn bộ input + file domain (`business-dictionary.md`, `product-definition/`) mới bắt đầu review — dùng chúng làm chuẩn đối chiếu để phán quyết `APPROVED` / `NEEDS_FIX`.
|
|
20
|
+
|
|
21
|
+
## Nguyên tắc
|
|
22
|
+
|
|
23
|
+
- **Chuẩn đối chiếu = tài liệu nguồn**, không phải suy đoán riêng của reviewer. Mọi nhận xét "TC hiểu sai/thiếu case" phải chỉ được về đoạn spec cụ thể trong các file đã đọc.
|
|
24
|
+
- **Không đọc thiếu:** nếu DOC_GAP nói "Tổng: N tài liệu" thì phải mở đủ N.
|
|
25
|
+
- Gap còn `Open` trong DOC_GAP: TC chạm vùng đó phải phản ánh đúng (đánh dấu blocked/assumption), không được coi như spec đã rõ.
|
|
26
|
+
- Lane API: nếu DOC_GAP ghi SKIP → không đòi hỏi TC endpoint không tồn tại.
|