@educa-corp/sdd-framework 0.9.2 → 0.9.4

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.
Files changed (76) hide show
  1. package/bin/build.js +11 -0
  2. package/bin/qc-base-map.json +119 -49
  3. package/bin/self-check.js +30 -0
  4. package/core/FRAMEWORK_VERSION +1 -1
  5. package/core/commands/qc-analyze.md +85 -75
  6. package/core/commands/qc-design-test.md +144 -25
  7. package/core/commands/qc-plan.md +40 -7
  8. package/core/commands/qc-review.md +74 -7
  9. package/core/commands/qc-run-test.md +21 -1
  10. package/core/commands/setup-ai-first.md +5 -5
  11. package/core/commands/update-framework.md +1 -1
  12. package/core/commands/validate-traces.md +1 -1
  13. package/core/modules/qc-playwright/stack-profile.yaml +3 -3
  14. package/core/rules/workflow.md +1 -1
  15. package/core/skills/qc/qa-analyst/DOC_GAP.template.md +47 -17
  16. package/core/skills/qc/qa-analyst/acceptance-criteria.md +1 -1
  17. package/core/skills/qc/qa-analyst/business-rules.md +2 -2
  18. package/core/skills/qc/qa-analyst/data-flow.md +2 -2
  19. package/core/skills/qc/qa-analyst/spec-breakdown.md +4 -4
  20. package/core/skills/qc/qa-analyst/spec-issue-reporter.md +14 -2
  21. package/core/skills/qc/qa-designer/api/auth-chain.md +155 -0
  22. package/core/skills/qc/qa-designer/api/auth-sequence.md +75 -0
  23. package/core/skills/qc/qa-designer/api/common-headers.md +61 -0
  24. package/core/skills/qc/qa-designer/api/crud-sequence.md +122 -0
  25. package/core/skills/qc/qa-designer/api/endpoint.md +231 -0
  26. package/core/skills/qc/qa-designer/api/http-status-codes.md +102 -0
  27. package/core/skills/qc/qa-designer/e2e/journey.md +13 -8
  28. package/core/skills/qc/qa-designer/exploratory/charter.md +2 -0
  29. package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +7 -4
  30. package/core/skills/qc/qa-designer/functional/api.md +87 -18
  31. package/core/skills/qc/qa-designer/functional/gui-feature.md +12 -9
  32. package/core/skills/qc/qa-designer/functional/gui-screen.md +12 -10
  33. package/core/skills/qc/qa-designer/integration/api.md +12 -5
  34. package/core/skills/qc/qa-designer/integration/db.md +12 -6
  35. package/core/skills/qc/qa-designer/integration/gui.md +12 -5
  36. package/core/skills/qc/qa-designer/integration/kafka.md +12 -5
  37. package/core/skills/qc/qa-designer/non-functional.md +12 -5
  38. package/core/skills/qc/qa-designer/shared/action-keywords-glossary.md +91 -0
  39. package/core/skills/qc/qa-designer/shared/duplicate-check-procedure.md +105 -0
  40. package/core/skills/qc/qa-designer/shared/implicit-scenarios.md +22 -0
  41. package/core/skills/qc/qa-designer/shared/precision-rules.md +198 -0
  42. package/core/skills/qc/qa-designer/shared/read-doc-gap-inputs.md +25 -0
  43. package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +93 -0
  44. package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +243 -0
  45. package/core/skills/qc/qa-planner/risk-model.md +1 -1
  46. package/core/skills/qc/qa-planner/test-plan.md +24 -13
  47. package/core/skills/qc/qa-reviewer/script/e2e.md +9 -1
  48. package/core/skills/qc/qa-reviewer/script/exploratory.md +9 -1
  49. package/core/skills/qc/qa-reviewer/script/functional.md +9 -1
  50. package/core/skills/qc/qa-reviewer/script/integration.md +9 -1
  51. package/core/skills/qc/qa-reviewer/script/non-functional.md +9 -1
  52. package/core/skills/qc/qa-reviewer/shared/read-doc-gap-inputs.md +26 -0
  53. package/core/skills/qc/qa-reviewer/shared/review-check-groups.md +207 -0
  54. package/core/skills/qc/qa-reviewer/shared/review-file-template.md +228 -0
  55. package/core/skills/qc/qa-reviewer/test-case/e2e.md +71 -13
  56. package/core/skills/qc/qa-reviewer/test-case/exploratory.md +53 -4
  57. package/core/skills/qc/qa-reviewer/test-case/functional.md +63 -15
  58. package/core/skills/qc/qa-reviewer/test-case/integration.md +64 -12
  59. package/core/skills/qc/qa-reviewer/test-case/non-functional.md +72 -13
  60. package/core/skills/qc/qa-runner/e2e.md +1 -1
  61. package/core/skills/qc/qa-runner/exploratory/session.md +1 -1
  62. package/core/steps/context-loader.md +1 -1
  63. package/core/steps/qc-scope.md +119 -0
  64. package/core/templates/project-context.yaml +3 -1
  65. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +1 -1
  66. package/docs/02-concepts/pipeline-steps/09-validate-traces.md +1 -1
  67. package/docs/04-reference/configuration.md +146 -146
  68. package/docs/04-reference/trace-schema.md +1 -1
  69. package/docs/explain/00-setup-ai-first.md +1 -1
  70. package/docs/explain/15-qc-analyze.md +1 -1
  71. package/docs/explain/16-qc-plan.md +1 -1
  72. package/docs/explain/17-qc-design-test.md +1 -1
  73. package/docs/plans/qc-implementation-log.md +288 -5
  74. package/docs/plans/qc-sync-command.md +2 -1
  75. package/package.json +1 -1
  76. package/scripts/migrate-qc-docs.js +261 -0
@@ -17,10 +17,14 @@ insert/update/soft-delete đúng giá trị, side-effect, toàn vẹn. Chỉ c
17
17
 
18
18
  ---
19
19
 
20
- ## Format file TC (bắt buộc)
21
- - Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](DOC_GAP.md)`.
22
- - **Test Data** dạng list (giá trị input) · **Steps** `[Action]`/`[Verify]` · **Expected** 1 bullet nêu rõ **bảng.cột = giá trị**.
23
- - Cuối file: Trace matrix + bảng TC block · bỏ nội dung gạch ngang.
20
+ ## Format file TC
21
+
22
+ > **Nạp `{paths.qc_skills_dir}/qa-designer/shared/tc-metadata-format.md`** khuôn TC, luật
23
+ > ATOMIC (1 kết cục = 1 TC), cách phân nhóm, hai file `.Test.md`, Trace + `@trace.verifies`,
24
+ > `🚫 Block`, dòng `Test-ID attribute`. **Không lặp lại luật format ở đây.**
25
+ >
26
+ > Khi viết Expected Result / Test Data: nạp thêm `shared/precision-rules.md` (cấm từ mơ hồ,
27
+ > đơn vị, toán tử) + `shared/action-keywords-glossary.md` (một hành động một từ).
24
28
 
25
29
  ## Kỹ thuật áp dụng
26
30
  - **State/DB verification:** verify bản ghi sau action (giá trị từng cột, flag, timestamp).
@@ -35,5 +39,7 @@ Nhóm TC: ghi đúng giá trị (happy) → default/null đúng → update khôn
35
39
  → audit log → ràng buộc/unique (negative). Mỗi TC bám Format; trace BR; gap chặn → 🚫 Block.
36
40
 
37
41
  ## Output
38
- File TC trong `{paths.qc_dir}/{UC-ID}/test-cases/`. Ghi rõ query kiểm tra DB + yêu cầu cleanup;
39
- không hardcode ID, chuẩn bị/dọn data qua fixture. Bàn giao `qa-reviewer`.
42
+
43
+ Ghi vào `{qc_artifact_dir}test-cases/TC_<FEATURE>_API.Test.md` — **Nhóm 2 Integration API/DB/Kafka**. Ghi rõ query kiểm tra DB + yêu cầu cleanup; không hardcode ID, chuẩn bị/dọn data qua fixture (3 mức teardown: `../shared/precision-rules.md` §8).
44
+
45
+ **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review`.
@@ -18,10 +18,14 @@ lỗi từ server, đồng bộ trạng thái hai chiều. Chỉ cần load file
18
18
 
19
19
  ---
20
20
 
21
- ## Format file TC (bắt buộc)
22
- - Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](DOC_GAP.md)`.
23
- - **Test Data** dạng list · **Steps** `[Action]`/`[Verify]` · **Expected** 1 bullet (API liên quan + biểu hiện UI kỳ vọng).
24
- - Cuối file: Trace matrix + bảng TC block · bỏ nội dung gạch ngang.
21
+ ## Format file TC
22
+
23
+ > **Nạp `{paths.qc_skills_dir}/qa-designer/shared/tc-metadata-format.md`** khuôn TC, luật
24
+ > ATOMIC (1 kết cục = 1 TC), cách phân nhóm, hai file `.Test.md`, Trace + `@trace.verifies`,
25
+ > `🚫 Block`, dòng `Test-ID attribute`. **Không lặp lại luật format ở đây.**
26
+ >
27
+ > Khi viết Expected Result / Test Data: nạp thêm `shared/precision-rules.md` (cấm từ mơ hồ,
28
+ > đơn vị, toán tử) + `shared/action-keywords-glossary.md` (một hành động một từ).
25
29
 
26
30
  ## Kỹ thuật áp dụng
27
31
  - **Data flow UI→API→UI:** verify request gửi đúng + render response đúng.
@@ -37,4 +41,7 @@ Nhóm TC: UI render đúng dữ liệu backend (happy) → empty state → lỗi
37
41
  Mỗi TC bám Format; trace BR; gap chặn → 🚫 Block.
38
42
 
39
43
  ## Output
40
- File TC trong `{paths.qc_dir}/{UC-ID}/test-cases/`. Mỗi TC nêu API liên quan + biểu hiện UI. Bàn giao `qa-reviewer`.
44
+
45
+ Ghi vào `{qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md` — **Nhóm 4 Integration (qua UI)**. Đây là tầng verify dòng dữ liệu API → giao diện, nên **vẫn thuộc file giao diện**: bỏ UI đi thì TC mất nghĩa.
46
+
47
+ **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review`.
@@ -17,10 +17,14 @@ Skill **tự chứa** để viết TC tích hợp qua Kafka: producer phát even
17
17
 
18
18
  ---
19
19
 
20
- ## Format file TC (bắt buộc)
21
- - Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](DOC_GAP.md)`.
22
- - **Test Data** dạng list (payload) · **Steps** `[Action]`/`[Verify]` · **Expected** 1 bullet nêu **topic + field payload / hành vi consumer**.
23
- - Cuối file: Trace matrix + bảng TC block · bỏ nội dung gạch ngang.
20
+ ## Format file TC
21
+
22
+ > **Nạp `{paths.qc_skills_dir}/qa-designer/shared/tc-metadata-format.md`** khuôn TC, luật
23
+ > ATOMIC (1 kết cục = 1 TC), cách phân nhóm, hai file `.Test.md`, Trace + `@trace.verifies`,
24
+ > `🚫 Block`, dòng `Test-ID attribute`. **Không lặp lại luật format ở đây.**
25
+ >
26
+ > Khi viết Expected Result / Test Data: nạp thêm `shared/precision-rules.md` (cấm từ mơ hồ,
27
+ > đơn vị, toán tử) + `shared/action-keywords-glossary.md` (một hành động một từ).
24
28
 
25
29
  ## Kỹ thuật áp dụng
26
30
  - **Message/event:** verify topic, key, payload schema, điều kiện phát.
@@ -37,4 +41,7 @@ Nhóm TC: phát đúng topic+payload (happy) → điều kiện không phát →
37
41
  Mỗi TC bám Format; trace BR; gap chặn → 🚫 Block.
38
42
 
39
43
  ## Output
40
- File TC trong `{paths.qc_dir}/{UC-ID}/test-cases/`. Mỗi TC ghi topic, key, payload cần verify + hành vi consumer. Bàn giao `qa-reviewer`.
44
+
45
+ Ghi vào `{qc_artifact_dir}test-cases/TC_<FEATURE>_API.Test.md` — **Nhóm 2 Integration API/DB/Kafka**. Mỗi TC ghi topic, key, payload cần verify + hành vi consumer.
46
+
47
+ **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review`.
@@ -17,10 +17,14 @@ Trọng tâm "hệ thống hoạt động TỐT thế nào". Chỉ cần load fi
17
17
 
18
18
  ---
19
19
 
20
- ## Format file TC (bắt buộc)
21
- - Metadata **list**: Title · Feature · Priority · Status(Draft) · Author(AI) · Tags · **Trace** `[BR-xx](REQUIREMENT_ANALYSIS.md#3-business-rules)` (không có → `⚠️ Chưa có Business Rule`) · **🚫 Block** `[GAP-xx](DOC_GAP.md)`.
22
- - **Test Data** dạng list · **Steps** `[Action]`/`[Verify]` · **Expected** 1 bullet có **ngưỡng đo cụ thể** (không "nhanh/ổn định").
23
- - Cuối file: Trace matrix + bảng TC block · bỏ nội dung gạch ngang.
20
+ ## Format file TC
21
+
22
+ > **Nạp `{paths.qc_skills_dir}/qa-designer/shared/tc-metadata-format.md`** khuôn TC, luật
23
+ > ATOMIC (1 kết cục = 1 TC), cách phân nhóm, hai file `.Test.md`, Trace + `@trace.verifies`,
24
+ > `🚫 Block`, dòng `Test-ID attribute`. **Không lặp lại luật format ở đây.**
25
+ >
26
+ > Khi viết Expected Result / Test Data: nạp thêm `shared/precision-rules.md` (cấm từ mơ hồ,
27
+ > đơn vị, toán tử) + `shared/action-keywords-glossary.md` (một hành động một từ).
24
28
 
25
29
  ## Kỹ thuật / loại
26
30
  - **Performance:** response time dưới tải mục tiêu; danh sách lớn (max data); pagination; concurrency.
@@ -37,4 +41,7 @@ Mỗi TC bám Format; **Expected có ngưỡng pass + công cụ đo**; đánh d
37
41
  Trace BR; gap chặn → 🚫 Block.
38
42
 
39
43
  ## Output
40
- File TC non-functional trong `{paths.qc_dir}/{UC-ID}/test-cases/`. Mỗi TC ghi tiêu chí đo + ngưỡng + công cụ. Bàn giao `qa-reviewer`.
44
+
45
+ Ghi vào file theo cùng câu hỏi phân file *"verify được mà không cần UI?"*: a11y · responsive · touch-target → `{qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md` **Nhóm 5 NFR**; tải/hiệu năng/bảo mật ở tầng API → `{qc_artifact_dir}test-cases/TC_<FEATURE>_API.Test.md`. Mỗi TC ghi tiêu chí đo + ngưỡng + công cụ, đơn vị theo `../shared/precision-rules.md` §3.
46
+
47
+ **Dạng danh sách, KHÔNG bảng** — file TC không được có ký tự `|` (`shared/tc-metadata-format.md` §Nguyên tắc format file). Cuối file: Trace matrix + danh sách TC bị block, cũng dạng danh sách. Bàn giao `/qc-review`.
@@ -0,0 +1,91 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-04
4
+ ported_from: ui-automation-testing
5
+ upstream_path: skills/qa-tc-designer/shared/action-keywords-glossary.md
6
+ upstream_sha: df56df91eea42342537ccf67b5946df32d98dbf4
7
+ ---
8
+ # Action Keywords Glossary — Từ Điển Chuẩn
9
+
10
+ > **Quy tắc:** Mỗi hành động chỉ dùng **1 từ duy nhất** trong toàn bộ tài liệu TC. Không dùng Enter/Type/Input xen kẽ. Không dùng Verify/Assert/Check lẫn lộn.
11
+
12
+ ---
13
+
14
+ ## Nhóm 1 — UI Actions (Web & Mobile)
15
+
16
+ | Từ chuẩn | Dùng khi nào | Không dùng thay thế |
17
+ |---|---|---|
18
+ | **Click** | Nhấn vào element trên Web (button, link, checkbox, radio) | Press, Hit, Select (cho button) |
19
+ | **Tap** | Nhấn vào element trên Mobile | Click (cho mobile) |
20
+ | **Enter** | Nhập văn bản vào input field / textarea | Type, Input, Fill, Write |
21
+ | **Select** | Chọn option trong dropdown / listbox | Choose, Pick |
22
+ | **Check** | Tick vào checkbox | Enable, Mark |
23
+ | **Uncheck** | Bỏ tick checkbox | Disable, Unmark |
24
+ | **Scroll** | Cuộn trang/container theo chiều dọc | Swipe (cho web) |
25
+ | **Swipe** | Vuốt màn hình trên Mobile | Scroll (cho mobile) |
26
+ | **Hover** | Di chuột vào element (hiện tooltip/dropdown) | Mouse over |
27
+ | **Clear** | Xóa nội dung field | Delete, Empty |
28
+ | **Upload** | Tải file lên qua input file | Attach, Import |
29
+ | **Download** | Tải file về | Save, Export |
30
+ | **Navigate to** | Mở URL / chuyển trang | Go to, Open URL |
31
+ | **Refresh** | Tải lại trang | Reload |
32
+ | **Wait for** | Chờ element/condition xuất hiện | Sleep, Pause |
33
+
34
+ ---
35
+
36
+ ## Nhóm 2 — Verification Actions
37
+
38
+ | Từ chuẩn | Dùng khi nào | Không dùng thay thế |
39
+ |---|---|---|
40
+ | **Verify** | Kiểm tra trong test steps — kết quả trung gian | Assert, Check, Confirm |
41
+ | **Assert** | Kết quả cuối (Expected Result) — điều kiện pass/fail | Verify (ở Expected), Check |
42
+ | **Observe** | Ghi nhận trạng thái hiện tại (không pass/fail) | See, Notice |
43
+
44
+ > **Phân biệt Verify vs Assert:**
45
+ > - Trong **Test Steps**: dùng `[Verify]` → "Verify: Error message 'Email không hợp lệ' hiển thị dưới field"
46
+ > - Trong **Expected Result**: dùng `Assert` → "Assert: HTTP 201, body.id tồn tại, body.email = email đã gửi"
47
+
48
+ ---
49
+
50
+ ## Nhóm 3 — API Actions
51
+
52
+ | Từ chuẩn | Dùng khi nào | Không dùng thay thế |
53
+ |---|---|---|
54
+ | **Send** | Gửi HTTP request | Call, Hit, Invoke |
55
+ | **GET** | HTTP GET request | Fetch, Read |
56
+ | **POST** | HTTP POST request | Create, Submit |
57
+ | **PUT** | HTTP PUT request | Update (toàn bộ) |
58
+ | **PATCH** | HTTP PATCH request | Update (một phần) |
59
+ | **DELETE** | HTTP DELETE request | Remove |
60
+ | **Receive** | Nhận response từ server | Get response |
61
+ | **Authenticate** | Thực hiện xác thực (login/token) | Login (trong API context) |
62
+
63
+ ---
64
+
65
+ ## Nhóm 4 — Test Setup / Teardown
66
+
67
+ | Từ chuẩn | Dùng khi nào |
68
+ |---|---|
69
+ | **Setup** | Chuẩn bị dữ liệu / trạng thái trước test |
70
+ | **Teardown** | Dọn dẹp sau test (xóa dữ liệu, reset state) |
71
+ | **Login as** | Đăng nhập với role cụ thể: "Login as Teacher" |
72
+ | **Logout** | Đăng xuất |
73
+ | **Reset** | Đưa hệ thống về trạng thái ban đầu |
74
+ | **Seed** | Tạo dữ liệu test (fixtures) trước khi chạy TC |
75
+
76
+ ---
77
+
78
+ ## Nhóm 5 — Trạng thái kỳ vọng (Expected keywords)
79
+
80
+ | Từ chuẩn | Dùng khi nào | Không dùng |
81
+ |---|---|---|
82
+ | **displays** | UI hiển thị element/text | shows, appears, renders |
83
+ | **is visible** | Element có thể nhìn thấy | is shown, is displayed |
84
+ | **is enabled** | Element có thể tương tác | is active, is available |
85
+ | **is disabled** | Element không thể tương tác | is inactive, is grayed out |
86
+ | **is empty** | Field không có giá trị | is blank, is clear |
87
+ | **contains** | Text/list chứa giá trị cụ thể | has, includes |
88
+ | **equals** | Giá trị bằng chính xác | is, matches (cho exact match) |
89
+ | **returns** | API trả về response | gives, sends back |
90
+ | **persists** | Dữ liệu được lưu vào DB | saves, stores |
91
+ | **navigates to** | Trình duyệt chuyển sang URL/màn mới | redirects to, goes to |
@@ -0,0 +1,105 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-04
4
+ ported_from: ui-automation-testing
5
+ upstream_path: skills/qa-tc-designer/shared/duplicate-check-procedure.md
6
+ upstream_sha: c59357a56b289bb9fb7fae8490db37109209cb3a
7
+ ---
8
+ # Duplicate Check Procedure
9
+
10
+ > **Bắt buộc thực hiện** trước khi viết TC mới. TC trùng lặp làm tăng thời gian chạy, gây nhầm lẫn kết quả, và không tăng coverage.
11
+
12
+ ---
13
+
14
+ ## Định nghĩa TC trùng lặp
15
+
16
+ Hai TC là **trùng** khi **cả 3** điều kiện sau đều giống nhau:
17
+ 1. **Điều kiện kiểm tra** (condition) — cùng scenario
18
+ 2. **Preconditions** — cùng trạng thái đầu vào
19
+ 3. **Test Data** — cùng partition/boundary value
20
+
21
+ > Nếu chỉ khác tên/title nhưng nội dung giống → **trùng**.
22
+ > Nếu cùng scenario nhưng khác role/data partition → **không trùng** (là 2 TC hợp lệ).
23
+
24
+ ---
25
+
26
+ ## Quy trình kiểm tra (3 bước)
27
+
28
+ ### Bước 1 — Grep title keywords trong file TC hiện tại
29
+
30
+ Trước khi viết TC mới, tìm kiếm title keywords trong toàn bộ file:
31
+
32
+ ```bash
33
+ # Tìm TC có chứa từ khóa scenario sắp viết
34
+ grep -i "<từ_khóa_scenario>" {qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md
35
+ ```
36
+
37
+ Ví dụ: Sắp viết TC "Nhập email không hợp lệ":
38
+ ```bash
39
+ grep -i "email\|invalid\|không hợp lệ" {qc_artifact_dir}test-cases/TC_LOGIN.Test.md
40
+ ```
41
+
42
+ ### Bước 2 — So sánh preconditions + test data
43
+
44
+ Nếu grep tìm thấy TC tương tự, so sánh:
45
+
46
+ | Yếu tố | TC hiện có | TC sắp viết | Kết luận |
47
+ |---|---|---|---|
48
+ | Condition | Nhập email sai format | Nhập email sai format | Giống |
49
+ | Precondition | Chưa login | Chưa login | Giống |
50
+ | Test Data | `abc@` | `abc@` | Giống → **TRÙNG** |
51
+ | Test Data | `abc@` | `abc` (không có @) | Khác partition → **KHÔNG TRÙNG** |
52
+
53
+ ### Bước 3 — Quyết định
54
+
55
+ | Kết quả so sánh | Hành động |
56
+ |---|---|
57
+ | Trùng hoàn toàn (cả 3 yếu tố) | Không viết TC mới — sử dụng TC cũ |
58
+ | Cùng condition, khác data/partition | Viết TC mới (hợp lệ) — thêm vào nhóm TC đó |
59
+ | Cùng condition, khác platform (Web/App) | **KHÔNG trùng** — mỗi nền một thư mục (`{qc_dir}/{TICKET-ID}/web/` vs `/app/`) và mỗi nền phải tự đạt full coverage. Trùng logic giữa hai nền là **chủ đích** |
60
+ | Không tìm thấy tương tự | Viết TC mới bình thường |
61
+
62
+ ---
63
+
64
+ ## Trường hợp đặc biệt
65
+
66
+ ### TC "uniqueness check" (kiểm tra trùng lặp dữ liệu)
67
+ - **Chỉ viết** khi spec có ràng buộc uniqueness rõ ràng (vd: "email phải là duy nhất", "tên lớp không được trùng trong cùng giáo viên").
68
+ - **Không viết** dựa trên suy đoán — cần có AC hoặc BR tường minh trong `{paths.specs_dir}`.
69
+
70
+ ### TC kế thừa logic từ UC khác
71
+ - Nếu scenario giống UC khác đã có TC → **không viết lại**, ghi trace reference về UC nguồn.
72
+ - Ví dụ: "Validation SĐT ở UC3 kế thừa logic UC2" → Trace: `BR-UC2-BR15`, ghi note "logic tương tự UC2".
73
+
74
+ ---
75
+
76
+ ## Áp dụng theo file — grep ở đâu
77
+
78
+ Chỉ có **hai** file TC cho mỗi (tính năng × nền), chia theo *"verify được mà không cần UI?"*:
79
+
80
+ | File | Chứa nhóm | Phạm vi grep khi kiểm trùng |
81
+ |---|---|---|
82
+ | `TC_<FEATURE>.Test.md` | GUI · Validation · Functional · Integration-qua-UI · NFR · E2E | **Toàn file** — trùng hay xảy ra giữa nhóm GUI và nhóm Functional |
83
+ | `TC_<FEATURE>_API.Test.md` | Endpoint · Integration API/DB/Kafka | Toàn file — so cả **endpoint + method + phân vùng dữ liệu** |
84
+
85
+ **Grep CẢ HAI file khi chưa chắc**, vì cùng một hành vi có thể đã được viết ở tầng khác: một
86
+ TC "email đã tồn tại" có thể nằm ở nhóm Validation (qua UI) **hoặc** ở file API (409 Conflict).
87
+ Hai cái đó **không trùng** — chúng test hai tầng khác nhau — nhưng phải biết cả hai tồn tại để
88
+ không viết cái thứ ba.
89
+
90
+ ## Trùng chéo UC — chỗ mới xuất hiện
91
+
92
+ Trước đây mỗi UC một thư mục riêng, nên TC của UC1 và UC2 không bao giờ gặp nhau. Giờ
93
+ **mọi UC của một PRD nằm chung một thư mục `test-cases/`** — nên trùng chéo UC vừa **nhìn thấy
94
+ được**, vừa **thực sự xảy ra**.
95
+
96
+ Hai UC của cùng một PRD rất hay dùng lại một luật nghiệp vụ (validate số điện thoại, quyền
97
+ truy cập, trạng thái hết hạn). Khi gặp:
98
+
99
+ - **KHÔNG viết lại TC.** Ghi `Trace` trỏ về `BR-xx` của UC nguồn + một dòng ghi chú
100
+ *"logic tương tự {UC-ID}, đã phủ ở TC_<FEATURE>_NNN"*.
101
+ - Chỉ viết TC mới khi **phân vùng dữ liệu hoặc tiền đề khác** — lúc đó không phải trùng.
102
+
103
+ > **Vì sao gạch này quan trọng hơn sau khi bật chế độ tách tối đa.** Tách tối đa nhân số TC lên
104
+ > (ví dụ thật: 82 → 130). Nhân một TC trùng lên 5 mảnh thì thành 5 TC trùng — và không ai đếm
105
+ > được nữa. Kiểm trùng phải chạy **trước** khi tách, không phải sau.
@@ -0,0 +1,22 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-04
4
+ ported_from: ui-automation-testing
5
+ upstream_path: skills/qa-tc-designer/shared/implicit-scenarios.md
6
+ upstream_sha: 6eb801a137ef4dfda97870c1eb36db62f3c782bc
7
+ ---
8
+ # Implicit Scenarios (Bắt buộc nghĩ tới)
9
+
10
+ **Với mọi TC ở mọi lane, luôn xét thêm các tình huống sau:**
11
+
12
+ | Tình huống | Gợi ý kỹ thuật |
13
+ |---|---|
14
+ | Rate limiting / spam click | EP: vượt ngưỡng → block/error |
15
+ | Concurrent / race condition | 2 request song song cùng resource |
16
+ | Session / auth timeout | Hết hạn giữa chừng → redirect login |
17
+ | Empty state | List rỗng, 0 kết quả, chưa có dữ liệu |
18
+ | Max data | Trường đạt giới hạn ký tự/số lượng tối đa |
19
+ | Ký tự đặc biệt | Emoji · Unicode · tiếng Việt có dấu · SQL injection attempt |
20
+ | Audit / log | Hành động quan trọng có ghi log đúng không |
21
+
22
+ > Không cần tạo TC riêng cho tất cả — đánh giá mức độ rủi ro: P0/P1 → viết TC, P2/P3 → ghi chú trong Test Data.
@@ -0,0 +1,198 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-04
4
+ ported_from: ui-automation-testing
5
+ upstream_path: skills/qa-tc-designer/shared/precision-rules.md
6
+ upstream_sha: 1c2005b55bd94c3e8fa25dfa12a29c8b23f7c01e
7
+ ---
8
+ # Precision Rules — Quy Tắc Độ Chính Xác
9
+
10
+ ---
11
+
12
+ ## 1. Cấm từ mơ hồ — Bắt buộc lượng hóa
13
+
14
+ | ❌ Mơ hồ — KHÔNG viết | ✅ Chuẩn — Thay bằng |
15
+ |---|---|
16
+ | "hiển thị nhanh" | "response time < 2 giây (đo P95)" |
17
+ | "giao diện đẹp" | Không test (không đo được — bỏ qua) |
18
+ | "phù hợp" | Chỉ rõ phù hợp với điều gì: "khớp với AC-03 của BR-12" |
19
+ | "hiển thị đúng" | "displays text 'Tên lớp: Toán 6A'" |
20
+ | "hoạt động bình thường" | Liệt kê hành vi cụ thể: "button enabled, click được, navigates to /dashboard" |
21
+ | "không lỗi" | "HTTP 200, không có error message, field is empty" |
22
+ | "dữ liệu chính xác" | "body.name = 'Toán 6A', body.teacher_id = 42" |
23
+ | "validate thành công" | "Error message không hiển thị, form submits successfully" |
24
+ | "load được" | "Page displays within 3 seconds, no console error" |
25
+
26
+ ---
27
+
28
+ ## 2. Assertion Granularity — Mỗi assertion 1 điều kiện
29
+
30
+ **Nguyên tắc (ATOMIC — QC chốt 2026-07-09):** Mỗi TC có **đúng 1** `#### Expected Result` với **ĐÚNG 1 bullet** (1 outcome; bullet có thể compound `A AND B` trên cùng 1 outcome). **Nhiều bullet / điểm-kiểm → TÁCH thành nhiều TC ĐỘC LẬP, mỗi TC 1 bullet** (không còn gộp checkpoint). Test Steps chỉ `[Action]`/`[Verify]`, **không** gắn `→ [Expected]` ở bước (chi tiết tách + renumber đồng bộ: `tc-metadata-format.md §"1 bullet Expected = 1 TC ĐỘC LẬP"`).
31
+
32
+ ```
33
+ ✅ ĐÚNG — 1 outcome, nhiều assertion liên quan:
34
+ Assert: HTTP 201 AND body.id exists AND body.name = "Toán 6A" AND body.teacher_id = 42
35
+
36
+ ✅ ĐÚNG — 1 assertion đơn lẻ:
37
+ Assert: Error message "Email không hợp lệ" displays below email field
38
+
39
+ ❌ SAI — 2 outcome khác nhau gom chung:
40
+ Assert: HTTP 201 AND trên UI hiển thị lớp mới trong danh sách
41
+ → Tách thành 2 TC riêng: TC API (HTTP 201) + TC UI (danh sách cập nhật)
42
+ ```
43
+
44
+ ### 2.1 Chế độ ATOMIC TỐI ĐA (QC chốt 2026-07-14 — khi user yêu cầu "tách tới mức nhỏ nhất")
45
+
46
+ Mặc định trên vẫn cho compound `A AND B` **cùng 1 outcome**. Nhưng khi chủ dự án YÊU CẦU THẲNG tách nhỏ nhất, áp **atomic tối đa — mỗi assertion độc-lập-fail = 1 TC**, gồm **nổ completeness list theo từng thành phần**:
47
+ - Thẻ/card "hiển thị **đủ** [A, B, C, D, E]" → **mỗi thành phần 1 TC** (vd thẻ khung giờ: ảnh GV / ngày·giờ / tên GV / tên bài / ô chọn = 5 TC; info card 4 mục = 4 TC; hero: tiêu đề / khẩu hiệu / linh vật = 3 TC).
48
+ - Đa-outcome BẮT BUỘC tách kể cả khi liên quan: popup + data-state · silent-handoff (điều hướng + không-popup) · mỗi con (`profile_id` A / B) · mỗi element/breakpoint responsive · mỗi touch-target · include vs exclude của cùng 1 filter.
49
+
50
+ **⛔ RANH GIỚI — GIỮ 1 TC (đừng over-split vô nghĩa) kể cả ở chế độ tối đa:**
51
+ - *Predicate đa-điều-kiện định-nghĩa-1-khái-niệm*: "chưa bắt đầu **và** còn ≥10' = slot-hợp-lệ" → 1 TC.
52
+ - *Ngưỡng*: "≥44pt/48dp", "WCAG AA ≥4.5:1" → 1 TC (không tách iOS/Android, không tách chữ-thường/chữ-lớn).
53
+ - *Exclusivity* chọn-một; *qualifier* ("không chỉ bằng màu").
54
+ - Bỏ vế TRÙNG nghĩa với TC khác (vd a11y "nút mở sau chọn" trùng TC chọn-1-khung → cắt, không nhân bản).
55
+
56
+ **Thủ tục bắt buộc trước khi thực thi (chênh quy mô lớn — FEAT-01-4: 82→WEB 132/APP 130):**
57
+ 1. **HỎI 1 câu chốt ranh giới completeness** (giữ-1-completeness ~95 TC vs nổ-từng-thành-phần ~130 TC) — quy mô rất khác, phải để user quyết.
58
+ 2. Dựng **bản đồ tách** (số mảnh mỗi TC cha) trước, KHÔNG để agent con tự suy diễn → giảm sai + giảm cắt cụt.
59
+ 3. Ưu tiên (P0/P1) TC con **kế thừa** từ cha; renumber tuần tự + đồng bộ Mục lục/Tổng hợp(đếm lại P0/P1 từ tag)/Trace Matrix(expand cha→con).
60
+ 4. **Làm CẢ 2 nền WEB+APP** (nhóm NFR khác nền: web a11y/responsive vs app safe-area/touch/back-gesture → tổng có thể lệch, granularity atomic tương đương).
61
+ 5. **Verify bằng DIFF, không tin lời đếm của agent**: ID tuần tự · `###`=`#### Expected` · mỗi Expected 1 bullet · 0 bảng `|` · Trace Matrix không ID chết · P0/P1 khớp tag (bug renumber KHÔNG throw — xem `qa-agents-large-write-unreliable`).
62
+
63
+ ---
64
+
65
+ ## 3. Đơn vị chuẩn theo domain
66
+
67
+ | Domain | Đơn vị bắt buộc | Ví dụ |
68
+ |---|---|---|
69
+ | Thời gian phản hồi | `ms` hoặc `giây` + percentile | "< 500ms (P95)" |
70
+ | Throughput | `req/s` hoặc `req/phút` | "≥ 100 req/s" |
71
+ | Tải concurrent | `users` | "50 concurrent users" |
72
+ | Dung lượng file | `KB` hoặc `MB` | "< 5MB" |
73
+ | Ký tự | `ký tự` | "≤ 100 ký tự" |
74
+ | Accessibility | WCAG level + version | "WCAG 2.1 AA" |
75
+ | HTTP status | Mã số đầy đủ | "HTTP 201", "HTTP 400" (không "success") |
76
+ | DB record | Bảng + cột + giá trị | "users.email = 'test@gmail.com'" |
77
+ | Error message | Chuỗi chính xác in nghiêng | `"Email không hợp lệ"` |
78
+
79
+ ---
80
+
81
+ ## 4. Toán tử so sánh — Dùng thống nhất
82
+
83
+ | Ý nghĩa | Ký hiệu | Ví dụ |
84
+ |---|---|---|
85
+ | Bằng chính xác | `=` | `body.status = "active"` |
86
+ | Nhỏ hơn | `<` | `response time < 2s` |
87
+ | Nhỏ hơn hoặc bằng | `≤` | `file size ≤ 5MB` |
88
+ | Lớn hơn | `>` | `list.count > 0` |
89
+ | Lớn hơn hoặc bằng | `≥` | `throughput ≥ 100 req/s` |
90
+ | Tồn tại | `exists` | `body.id exists` |
91
+ | Không tồn tại | `not exists` | `error_message not exists` |
92
+ | Chứa chuỗi | `contains` | `body.message contains "thành công"` |
93
+
94
+ ---
95
+
96
+ ## 5. Test Data sourcing — Dữ liệu test từ đâu
97
+
98
+ **Quy tắc:**
99
+ - **Không hardcode** giá trị nhạy cảm (password, token, production data) vào TC.
100
+ - **Dùng placeholder** rõ nghĩa: `<valid_email>`, `<teacher_password>`, `<existing_class_id>`.
101
+ - **Ghi nguồn dữ liệu** khi cần setup: "Seed: tạo 1 lớp học với teacher_id = fixture.teacher.id".
102
+ - **Biên dữ liệu** (BVA) phải ghi rõ giá trị cụ thể: "10 ký tự (biên trên của maxlength=10)".
103
+
104
+ **Baseline cho NFR:**
105
+ - Lấy từ **SLA document** trong `{paths.specs_dir}` (nếu có).
106
+ - Lấy từ **AC** trong PRD (vd "AC-05: response < 3s").
107
+ - Nếu không có document → ghi rõ `[Cần xác nhận baseline với PO]` trong Test Data.
108
+
109
+ ---
110
+
111
+ ## 6. Format Expected Result chuẩn theo lane
112
+
113
+ **UI:**
114
+ ```
115
+ Assert: <element> <trạng thái> — ví dụ: "Error message 'Email không hợp lệ' is visible below field"
116
+ ```
117
+
118
+ **API:**
119
+ ```
120
+ Assert: HTTP <code> AND body.<field> <toán tử> <giá trị> — ví dụ: "HTTP 201 AND body.id exists AND body.name = 'Toán 6A'"
121
+ ```
122
+
123
+ **E2E:**
124
+ ```
125
+ Assert: <chuỗi verify point> — ví dụ: "Class 'Toán 6A' displays in list AND teacher dashboard shows 1 new class"
126
+ ```
127
+
128
+ **NFR:**
129
+ ```
130
+ Assert: <metric> <toán tử> <ngưỡng> (<đơn vị>) — ví dụ: "P95 response time < 500ms at 50 concurrent users"
131
+ ```
132
+
133
+ **Integration:**
134
+ ```
135
+ Assert: <Module A state> AND <Module B state> — ví dụ: "HTTP 201 AND DB: classes.id = new_id AND Kafka: event 'class.created' published"
136
+ ```
137
+
138
+ ---
139
+
140
+ ## 7. Decision Table — Quy tắc coverage
141
+
142
+ **Standard coverage (ISTQB CTFL v4.0):** mỗi rule (cột) = 1 TC tối thiểu.
143
+
144
+ | Điều kiện | Rule 1 | Rule 2 | Rule 3 | Rule 4 |
145
+ |---|---|---|---|---|
146
+ | user.role = admin | T | T | F | F |
147
+ | resource.owner = self | T | F | T | F |
148
+ | **Action** | 200 OK | 403 | 200 OK | 403 |
149
+
150
+ → 4 rules = 4 TC (1 happy + 3 negative/edge).
151
+
152
+ **BVA — 3 giá trị hay 4 giá trị?**
153
+
154
+ | Spec | Giá trị phải test |
155
+ |---|---|
156
+ | Range 2 biên (`min ≤ x ≤ max`) | **4 giá trị:** min−1, min, max, max+1 |
157
+ | Biên trên chỉ (`x ≤ max`) | **3 giá trị:** max−1, max, max+1 |
158
+ | Biên dưới chỉ (`x ≥ min`) | **3 giá trị:** min−1, min, min+1 |
159
+ | Đúng 1 giá trị hợp lệ | **3 giá trị:** value−1, value, value+1 |
160
+
161
+ **Don't-care conditions:** condition không ảnh hưởng action → gộp rule, ghi `DC` (don't care) trong bảng. Ví dụ: `resource.owner` không quan trọng khi `user.role = superadmin` → gộp 2 rules thành 1 TC.
162
+
163
+ **Đếm TC từ Decision Table:** N unique rules sau gộp don't-care = N TC tối thiểu. Nếu spec không có Decision Table sẵn → tự xây bảng trong Phase Clarify trước khi viết TC.
164
+
165
+ **Phủ ĐỦ mọi ô — kể cả ô "không hành động".** Mỗi tổ hợp điều kiện phải có TC, kể cả ô mà kết quả là "không làm gì / không hiển thị" (vd: cả 2 trục cùng đủ rõ → KHÔNG hỏi câu phụ; cả 2 cùng chưa rõ → KHÔNG hỏi). Không được bỏ ô vì "không có hành động".
166
+
167
+ **Kết hợp Decision Table + BVA, không trộn lẫn:**
168
+ - Giá trị trong TC Decision Table nên **cách biệt rõ** so với ngưỡng (vd chênh lệch 25 so với ngưỡng 20) để cô lập đúng rule.
169
+ - Điểm **sát biên** (ngưỡng−1 / = ngưỡng / ngưỡng+1) tách thành TC **BVA riêng**, không nhét vào TC Decision Table.
170
+
171
+ **Báo coverage bằng TC ID cụ thể.** Khi tổng kết độ phủ cho logic điều kiện/ngưỡng: lập bảng ánh xạ từng rule/điểm biên → TC ID, đánh dấu rõ ô nào đủ/thiếu. Không kết luận "phủ gián tiếp" chung chung.
172
+
173
+ ---
174
+
175
+ ## 8. Teardown Data Strategy
176
+
177
+ ### 3 mức cleanup:
178
+
179
+ | Mức | Khi nào | Cách thực hiện |
180
+ |---|---|---|
181
+ | **Inline** | TC tạo 1 bản ghi độc lập | Bước cuối Steps: `[Teardown] DELETE /api/v1/resource/{created_id}` |
182
+ | **Fixture** | Nhiều TC dùng chung 1 tập data | Preconditions: `Fixture: seed_class()` — teardown trong `conftest.py` scope=function |
183
+ | **Reset env** | TC thay đổi trạng thái hệ thống (email sent, payment, notification) | Ghi vào TC: `⚠️ Manual teardown: [bước cụ thể]` |
184
+
185
+ ### Format Teardown trong TC:
186
+
187
+ ```markdown
188
+ #### Teardown
189
+ - DELETE /api/v1/classes/{created_id} — xóa lớp đã tạo trong Steps
190
+ - Hoặc: [Reset: fixture scope=function tự cleanup sau mỗi test]
191
+ ```
192
+
193
+ ### Quy tắc:
194
+ - TC tạo bản ghi DB hoặc state THẬT (ghi vào tài khoản test) → **bắt buộc** ghi Teardown (API DELETE hoặc fixture rollback / reset tài khoản).
195
+ - TC chỉ đọc (GET) hoặc chỉ verify UI tĩnh → không cần Teardown.
196
+ - **TC chỉ cấu hình mock / route intercept / network monitoring → KHÔNG cần Teardown.** Reset mock về default là trách nhiệm của fixture `conftest.py` (scope=function tự teardown). Ghi "Reset mock về default" trong từng TC là **thừa** — không thêm. (Lane test qua mock hoàn toàn, vd UI/E2E khi API SKIP, hầu hết TC KHÔNG có Teardown.)
197
+ - TC mobile/E2E tạo account → ghi `[Teardown: deactivate user via admin API]`.
198
+ - TC không cleanup được → đánh dấu `⚠️ Manual teardown required` + ghi hướng dẫn chi tiết.
@@ -0,0 +1,25 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-04
4
+ ported_from: ui-automation-testing
5
+ upstream_path: skills/qa-tc-designer/shared/read-doc-gap-inputs.md
6
+ upstream_sha: a7e113b19f35aa47acf91e55cdfb3f630539806c
7
+ ---
8
+ # Thủ tục: Nạp TOÀN BỘ tài liệu input từ DOC_GAP (BẮT BUỘC trước khi thiết kế/review TC)
9
+
10
+ > Mục tiêu: designer/reviewer phải đọc **đúng bộ tài liệu nguồn mà qa-tc-analyst đã dùng** để dựng TEST_PLAN + DOC_GAP — không chỉ file domain. Tránh thiết kế/review TC trên ngữ cảnh thiếu, dẫn tới bỏ sót nghiệp vụ hoặc hiểu sai contract.
11
+
12
+ ## Các bước
13
+
14
+ 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` (xem `/qc-analyze`). Không có → chạy `/qc-analyze {TICKET-ID} {platform}` trước; **đừng thiết kế TC trên ngữ cảnh thiếu**.
15
+ 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.
16
+ 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ú, không tự bịa.
17
+ 4. **Đối chiếu chéo:** nếu ngoài bảng DOC_GAP còn `## Coverage Attestation` / dòng "Tài liệu nguồn (spec chính)" ở header → xác nhận đã phủ hết; file nào có mặt ở header mà thiếu trong bảng → vẫn đọc.
18
+ 5. Chỉ sau khi đã nạp xong toàn bộ input + file domain (`business-dictionary.md`, `product-definition/`) mới bắt đầu viết/soát TC.
19
+
20
+ ## Nguyên tắc
21
+
22
+ - **Không tự suy diễn ngoài tài liệu.** Chỉ dùng nội dung thực có trong các file đã đọc.
23
+ - **Không đọc thiếu:** nếu DOC_GAP nói "Tổng: N tài liệu" thì phải mở đủ N (trừ file domain đã nạp riêng — vẫn nằm trong N).
24
+ - **Bỏ qua** phần Change log / Appendix / "Giả định AI" khi trích evidence (giống ràng buộc nguồn của analyst), nhưng vẫn được đọc để hiểu ngữ cảnh.
25
+ - Lane API: nếu DOC_GAP ghi SKIP (không có `openapi.yaml`/`.dbml`/`tdd/`) → không bịa endpoint.