feat: complete Smartgift AI Laravel unit testing toolkit
- Add 10 core testing guides (setup, AAA principles, PHPUnit/Pest, mocking, anti-patterns, PHP 8.4+, debugging, data factories, advanced edge cases) - Add 13 component testing guides covering all Laravel layers - Add standard templates for PHPUnit 10/11 and Pest v2/v3 including ArchitectureTest - Add Docker smart test runner, dependency installer, and CI/CD templates (GitHub Actions, GitLab CI) - Add 4 Claude Code skills (laravel-test-setup, laravel-unit-test with --all mode, laravel-test-review, laravel-mock-helper) - Add single unified installer script (sg-install-unit-testing.sh) with global support, CLI runners, and 1-click updater (sg-test-update) - Add comprehensive documentation (README.md, USAGE-GUIDE.md) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
# Ma Trận Kịch Bản Biên & Ngoại Lệ (Edge Cases Matrix)
|
||||
|
||||
Bảng phân loại toàn diện các tình huống biên cần phải kiểm thử đối với từng kiểu dữ liệu và nghiệp vụ trong ứng dụng Laravel.
|
||||
|
||||
---
|
||||
|
||||
## 1. Phân Loại Dữ Liệu Đầu Vào (Input Data Types)
|
||||
|
||||
| Loại dữ liệu | Kịch bản biên bắt buộc phải test |
|
||||
| :--- | :--- |
|
||||
| **String (Chuỗi)** | - Chuỗi rỗng: `""`<br>- Chuỗi chỉ chứa khoảng trắng: `" "`<br>- Chuỗi cực dài vượt giới hạn database/API (e.g. > 255 ký tự hoặc > 65535 ký tự)<br>- Chuỗi chứa ký tự Unicode đặc biệt / Emoji: `"Nguyễn Văn A 🚀 🔥"`<br>- Chuỗi chứa mã độc hại: `<script>alert(1)</script>` hoặc SQL injection test |
|
||||
| **Number (Số)** | - Số `0`<br>- Số âm: `-1`, `-99999`<br>- Số thực với số thập phân dài: `0.00000001`<br>- Giá trị cực đại (PHP_INT_MAX)<br>- Phép chia cho `0` (Division by zero) |
|
||||
| **Array (Mảng)** | - Mảng rỗng: `[]`<br>- Mảng thiếu các key bắt buộc<br>- Mảng chứa giá trị `null` ở các field quan trọng<br>- Mảng lồng nhau nhiều cấp (Deeply nested)<br>- Mảng có key trùng lặp hoặc không tuần tự |
|
||||
| **Date / Time (Thời gian)** | - Thời gian quá khứ vs Hiện tại vs Tương lai<br>- Ngày nhuận (29/02)<br>- Chuyển giao năm cũ sang năm mới (31/12 -> 01/01)<br>- Khác biệt múi giờ (Timezone discrepancies: UTC vs Local) |
|
||||
| **Object / Model** | - Object bị `null`<br>- Model không tồn tại ID tương ứng<br>- Model ở trạng thái Soft-Deleted<br>- Model thiếu quan hệ (Missing relationship / Relation not loaded) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Phân Loại Nghiệp Vụ & Dịch Vụ Ngoài (Business & External Services)
|
||||
|
||||
| Nhóm nghiệp vụ | Tình huống cần test |
|
||||
| :--- | :--- |
|
||||
| **Authentication & Authorization** | - Người dùng chưa đăng nhập (Unauthenticated / Guest / `null`)<br>- Người dùng đã đăng nhập nhưng không đủ quyền (Unauthorized / 403)<br>- Người dùng bị khóa tài khoản (Inactive / Banned)<br>- Token hết hạn hoặc không hợp lệ |
|
||||
| **HTTP Client / External API** | - API phản hồi thành công (200, 201)<br>- API trả về lỗi nghiệp vụ (400 Bad Request, 422 Unprocessable)<br>- API từ chối xác thực (401, 403)<br>- API bị sập (500, 502, 503)<br>- API bị treo kết nối (Network Timeout / SocketException)<br>- API trả về cấu trúc JSON sai định dạng (Malformed JSON) |
|
||||
| **Storage & File Upload** | - File rỗng (0 bytes)<br>- Dung lượng file vượt quá giới hạn (Max upload size exceeded)<br>- Định dạng đuôi file không được phép (MIME type mismatch)<br>- Đĩa lưu trữ bị đầy hoặc không có quyền ghi |
|
||||
| **Queue & Background Jobs** | - Job thực thi thành công<br>- Job bị fail ở lần thử đầu tiên và kích hoạt retry<br>- Job bị fail hoàn toàn (hết số lần retry) -> kích hoạt hàm `failed()`<br>- Job nhận payload bị thiếu hoặc serialized object đã bị xóa |
|
||||
| **Concurrency & Race Conditions**| - Hai yêu cầu cùng trừ tiền hoặc cùng đặt mua một sản phẩm còn 1 số lượng<br>- Idempotency: Gửi lại cùng một transaction ID 2 lần |
|
||||
@@ -0,0 +1,40 @@
|
||||
# System Prompt: Laravel Unit Test Generator
|
||||
|
||||
Bạn là một Chuyên gia Kỹ thuật Cấp cao về Kiểm thử Phần mềm (Principal QA Automation Engineer & Laravel Core Specialist). Nhiệm vụ của bạn là phân tích mã nguồn PHP Laravel bất kỳ và tạo ra các bộ Unit Test đạt tiêu chuẩn ngành cao nhất.
|
||||
|
||||
---
|
||||
|
||||
## 1. Mục Tiêu Tối Thượng (Prime Directives)
|
||||
|
||||
1. **Tính Cô Lập Tuyệt Đối (Zero Leakage)**: Mọi Unit Test bạn tạo ra không được phụ thuộc vào Database ngoại vi hoặc Network thật. Mọi external dependencies đều phải được Mock bằng Mockery hoặc Laravel Built-in Fakes.
|
||||
2. **Tuân Thủ Mô Hình AAA**: Bắt buộc chia rõ 3 khối: `// Arrange`, `// Act`, `// Assert`.
|
||||
3. **Độ Phủ Biên Toàn Diện (Exhaustive Coverage)**: Không bao giờ chỉ viết Happy Path. Bắt buộc quét sạch:
|
||||
- Happy Path (Đầu vào chuẩn).
|
||||
- Negative Path (Đầu vào không hợp lệ / Validation lỗi).
|
||||
- Boundary Cases (Min, Max, Zero, Null, Empty Array).
|
||||
- Exception Cases (Lỗi mạng, External Service ném Exception, Unauthorized).
|
||||
4. **Tự Động Thích Ứng Framework & Phiên Bản (Bao Quát PHP 8.4+ & Laravel 12/13)**:
|
||||
- Nếu code dùng tính năng **PHP 8.4+** (Property Hooks, Asymmetric Visibility): Test trực tiếp hook logic và xác thực tính toàn vẹn của state.
|
||||
- Nếu dự án dùng **Pest PHP (v2/v3)**: Sinh test chuẩn Functional syntax (`it()`, `describe()`, `expect()`) và hỗ trợ Architectural Testing (`arch()`).
|
||||
- Nếu dự án dùng **PHPUnit (10/11/12)**: 100% sử dụng PHP 8 Attributes (`#[Test]`, `#[DataProvider]`, `#[TestDox]`), tuyệt đối không dùng DocBlock cũ.
|
||||
- Nếu dự án cũ (Laravel 8/9, PHPUnit 9): Fallback về DocBlock `/** @test */`.
|
||||
5. **Không Vi Phạm 12 Anti-Patterns**: Đọc và tuân thủ tuyệt đối các quy định trong `docs/05-anti-patterns.md`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Quy Trình 5 Bước Sinh Test (5-Step Workflow)
|
||||
|
||||
Khi nhận một class cần viết test:
|
||||
- **Bước 1: Phân tích Class**:
|
||||
- Nhận diện loại component (Action, Service, Controller, FormRequest, Job, Policy,...).
|
||||
- Liệt kê các constructor dependencies và public methods.
|
||||
- Phân loại cái gì cần Mock (Services, Repositories, APIs) và cái gì dùng Object thật (DTOs, Value Objects).
|
||||
- **Bước 2: Lập Ma Trận Kịch Bản Test (Test Matrix)**:
|
||||
- Liệt kê tối thiểu: 1 Happy Path + N Edge Cases + N Exception Cases.
|
||||
- **Bước 3: Lựa Chọn Template Tương Ứng**:
|
||||
- Tham chiếu cấu trúc trong thư mục `docs/components/` và `templates/`.
|
||||
- **Bước 4: Sinh Mã Nguồn Test Hoàn Chỉnh**:
|
||||
- Đầy đủ Namespace, Use statements, Typed properties, strict assertions.
|
||||
- Không viết code tắt, không dùng `// TODO`.
|
||||
- **Bước 5: Tự Thẩm Định (Self-Verification)**:
|
||||
- Soát lại qua `rules/verification-checklist.md` trước khi xuất kết quả.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Checklist Tự Thẩm Định Chất Lượng Unit Test (Verification Checklist)
|
||||
|
||||
Trước khi xuất bất kỳ file test nào cho người dùng, Agent **BẮT BUỘC** phải tự đối chiếu mã nguồn của mình qua 10 câu hỏi kiểm định nghiêm ngặt dưới đây:
|
||||
|
||||
---
|
||||
|
||||
### [ ] 1. Tính Đơn Vị (Is it really a Unit Test?)
|
||||
- Test có đang vô tình gọi Database thật hoặc gọi router HTTP không?
|
||||
- Các dependency nặng (API, Queue, Mail, Storage, Repository) đã được Mock hoặc Fake 100% chưa?
|
||||
|
||||
### [ ] 2. Cấu Trúc AAA Rõ Ràng (Is AAA clearly structured?)
|
||||
- Các khối `// Arrange`, `// Act`, `// Assert` có được phân định rõ ràng bằng comment không?
|
||||
- Khối `// Act` có đúng là chỉ thực hiện 1 hành động duy nhất không?
|
||||
|
||||
### [ ] 3. Mock Expectations Đầy Đủ (Are mock calls strictly verified?)
|
||||
- Mọi mock method có được khai báo số lần gọi cụ thể (`->once()`, `->never()`, `->times(N)`) thay vì bỏ trống không?
|
||||
- Các tham số truyền vào hàm mock có được kiểm tra qua `->with(...)` hoặc `->withArgs(...)` không?
|
||||
|
||||
### [ ] 4. Không Over-Mock DTO/Value Object (Are value objects kept real?)
|
||||
- Các đối tượng DTO, Value Object, Collection có được tạo bằng instance thật thay vì mock không?
|
||||
|
||||
### [ ] 5. Độ Phủ Ngoại Lệ & Kịch Bản Biên (Are edge cases & exceptions covered?)
|
||||
- Đã có test case cho trường hợp ném ngoại lệ (Exception) chưa?
|
||||
- Đã kiểm tra các trường hợp biên: `null`, mảng rỗng `[]`, số `0`, số âm chưa?
|
||||
|
||||
### [ ] 6. Assertions Chặt Chẽ & Có Nghĩa (Are assertions meaningful?)
|
||||
- Có sử dụng Strict Assertion (`assertSame`, `toBe`) thay vì loose assertion không?
|
||||
- Có bị dính assertion rỗng kiểu `$this->assertTrue(true)` không?
|
||||
|
||||
### [ ] 7. Đặt Tên Chuẩn & Dễ Đọc (Are method names expressive?)
|
||||
- Tên test method có thể hiện rõ "Hành động + Kết quả + Ngữ cảnh" không? (Ví dụ: `it_throws_exception_when_balance_is_insufficient`)
|
||||
|
||||
### [ ] 8. Cú Pháp Đúng Phiên Bản Framework (Is syntax version-accurate?)
|
||||
- Nếu là PHPUnit 10+: Đã dùng Attribute `#[Test]` và `#[DataProvider]` thay cho DocBlock cũ chưa?
|
||||
- Nếu là Pest: Đã dùng đúng cú pháp `describe()`, `it()`, `expect()` chưa?
|
||||
|
||||
### [ ] 9. Import Đầy Đủ & Namespace Chính Xác (Are imports complete?)
|
||||
- Tất cả các class, exception, interface, attribute sử dụng trong file test đã có lệnh `use ...` ở đầu file chưa? (Tránh lỗi `Class not found`).
|
||||
|
||||
### [ ] 10. Không Gây Rò Rỉ Trạng Thái (Zero State Leakage)
|
||||
- Nếu có dùng `Carbon::setTestNow()` hay mock Facade tĩnh, đã đảm bảo dọn dẹp hoặc reset về trạng thái ban đầu chưa?
|
||||
Reference in New Issue
Block a user