docs: standardize pro 3-step testing workflow and add SonarQube guide
- Update README.md with recommended 3-step decoupled workflow (audit -> batch write -> terminal run) - Add docs/10-sonarqube-100-percent-coverage-guide.md covering line/branch coverage and Clover XML export - Update /laravel-unit-test skill definition prioritizing decoupled batch generation - Fix remote installer URLs to official Smartgift Git server Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,47 +8,53 @@ description: Phân tích một class mã nguồn PHP Laravel bất kỳ và tự
|
||||
Skill này là công cụ chính để tự động tạo ra file Unit Test cho bất kỳ class nào trong dự án Laravel (Service, Action, Controller, Job, FormRequest, Policy, Rule,...).
|
||||
|
||||
## Cách kích hoạt
|
||||
Người dùng có thể kích hoạt linh hoạt theo các chế độ (từ 1 lệnh duy nhất cho toàn bộ dự án đến từng file đơn lẻ):
|
||||
Người dùng có thể kích hoạt linh hoạt theo các chế độ (từ quy trình chuẩn Pro 3 bước cho dự án lớn đến file đơn lẻ):
|
||||
|
||||
1. **🌟 Chế độ Autopilot Khép Kín: Viết Xong Chạy Test Luôn (`--all --run` hoặc `--autopilot`)**:
|
||||
### 🏆 QUY TRÌNH CHUẨN PRO CHO DỰ ÁN LỚN (KHUYÊN DÙNG NHẤT):
|
||||
Để tránh bị tràn context token và đảm bảo viết sâu 100% từng nhánh SonarQube, hãy tách biệt 2 pha: **PHA VIẾT (Generation)** và **PHA CHẠY (Execution)**:
|
||||
|
||||
1. **Bước 1: Quét bản đồ dự án (`--untested`)**:
|
||||
```text
|
||||
/laravel-unit-test --untested
|
||||
```
|
||||
*Liệt kê danh sách class chưa có test theo độ ưu tiên: Services/Actions -> Requests/Rules -> Jobs/Policies.*
|
||||
|
||||
2. **Bước 2: Viết test tập trung theo từng tầng (CHỈ VIẾT, CHƯA CHẠY TEST)**:
|
||||
```text
|
||||
/laravel-unit-test app/Services/
|
||||
# Sau khi xong, viết tiếp:
|
||||
/laravel-unit-test app/Actions/
|
||||
/laravel-unit-test app/Http/Requests/
|
||||
```
|
||||
*AI dồn 100% token tập trung sinh test sâu, đầy đủ Happy Path, Edge Cases, Exception và Branch Coverage.*
|
||||
|
||||
3. **Bước 3: Chạy test đồng loạt ngoài Terminal & Nghiệm thu**:
|
||||
```bash
|
||||
./test-runner.sh --coverage
|
||||
```
|
||||
*Chạy 1 lần duy nhất trên In-memory SQLite siêu tốc, đo độ phủ và xuất file báo cáo.*
|
||||
|
||||
---
|
||||
|
||||
### ⚡ CÁC CHẾ ĐỘ TIỆN ÍCH KHÁC:
|
||||
|
||||
4. **Chế độ Autopilot Khép Kín: Viết & Chạy Test Ngay (`--all --run` hoặc `--autopilot`)**:
|
||||
```text
|
||||
/laravel-unit-test --all --run
|
||||
# Hoặc:
|
||||
/laravel-unit-test --autopilot
|
||||
```
|
||||
*Chỉ với 1 lệnh duy nhất, Agent sẽ thực thi trọn vẹn quy trình 4-trong-1:*
|
||||
- **Tự động Setup**: Kiểm tra dependencies & SQLite in-memory, tự cài đặt gói thiếu.
|
||||
- **Tự động Quét**: Lập manifest toàn bộ class trong dự án `app/`.
|
||||
- **Tự động Viết & Test Ngay**: Sinh test đến đâu -> Chạy test `./test-runner.sh` ngay đến đó.
|
||||
- **Tự động Sửa Lỗi (Auto-Healing)**: Nếu test đỏ (Fail) -> Tự đọc log lỗi và sửa lại test cho đến khi XANH (Pass 100%).
|
||||
- **Nghiệm thu**: Đo Code Coverage và in bảng tổng kết cuối cùng.
|
||||
*Dành cho dự án vừa và nhỏ: AI tự lập manifest, viết đến đâu chạy `./test-runner.sh` ngay đến đó, tự động sửa lỗi (Auto-Healing) nếu test fail.*
|
||||
|
||||
2. **Chế độ Viết Cho 1 File & Test Luôn (`--run`)**:
|
||||
5. **Chế độ Viết Cho 1 File & Test Luôn (`--run`)**:
|
||||
```text
|
||||
/laravel-unit-test app/Services/PaymentService.php --run
|
||||
```
|
||||
*Sinh test cho class và lập tức chạy thử để xác nhận Pass 100% trước khi hoàn thành.*
|
||||
|
||||
3. **Chế độ Hàng loạt theo Thư mục (Batch Directory Mode)**:
|
||||
6. **Chế độ Theo Git Diff (Dành Cho Pull Request)**:
|
||||
```text
|
||||
/laravel-unit-test app/Services/ --run
|
||||
# Hoặc toàn bộ Actions:
|
||||
/laravel-unit-test app/Actions/ --run
|
||||
/laravel-unit-test --changed
|
||||
```
|
||||
|
||||
4. **Chế độ Theo Module / DDD (Module Mode)**:
|
||||
```text
|
||||
/laravel-unit-test Modules/Order/ --run
|
||||
# Hoặc:
|
||||
/laravel-unit-test app/Domains/Payment/ --run
|
||||
```
|
||||
|
||||
5. **Chế độ Theo Git Diff (Changed Files Mode - Dành Cho Pull Request)**:
|
||||
```text
|
||||
/laravel-unit-test --changed --run
|
||||
```
|
||||
|
||||
6. **Chế độ File đơn lẻ (Single File Mode)**:
|
||||
7. **Chế độ File đơn lẻ**:
|
||||
```text
|
||||
/laravel-unit-test app/Services/PaymentService.php
|
||||
```
|
||||
|
||||
@@ -57,7 +57,7 @@ agent-unit-testing/
|
||||
│ ├── laravel-test-review/ # Chấm điểm chất lượng test theo thang 100 & bắt lỗi anti-patterns
|
||||
│ └── laravel-mock-helper/ # Sinh mã Mockery & Laravel Fakes nhanh
|
||||
│
|
||||
├── docs/ # 10 Cẩm Nang Kiến Thức & Quy Chuẩn Cốt Lõi
|
||||
├── docs/ # 11 Cẩm Nang Kiến Thức & Quy Chuẩn Cốt Lõi
|
||||
│ ├── 00-environment-and-setup.md # Hướng dẫn setup dependencies, SQLite in-memory & Docker
|
||||
│ ├── 01-overview-and-principles.md # Triết lý Unit Test: AAA, cách ly, ranh giới Feature test
|
||||
│ ├── 02-test-frameworks.md # So sánh & cú pháp PHPUnit 10/11 vs Pest PHP v2/v3
|
||||
@@ -68,6 +68,7 @@ agent-unit-testing/
|
||||
│ ├── 07-troubleshooting-and-debugging.md # Cẩm nang sửa 10 lỗi thường gặp nhất khi chạy test
|
||||
│ ├── 08-test-data-factories-and-builders.md# Quản lý fixture: Model::make(), States & DTO Builders
|
||||
│ ├── 09-advanced-edge-cases.md # DB::transaction, Traits, File uploads, Serialization
|
||||
│ ├── 10-sonarqube-100-percent-coverage-guide.md # Chiến lược đạt 100% Coverage trên SonarQube
|
||||
│ │
|
||||
│ └── components/ # 13 Cẩm Nang Chi Tiết Cho Từng Component Laravel
|
||||
│ ├── 01-services-and-actions.md # Service Layer, Action classes, DTOs
|
||||
@@ -186,50 +187,71 @@ Chạy lệnh kiểm tra và tự động cài đặt thư viện kiểm thử c
|
||||
|
||||
---
|
||||
|
||||
### 🔹 Giai đoạn 3: Ra lệnh viết toàn bộ Unit Test & Tự động chạy test luôn
|
||||
Chỉ cần gõ **đúng 1 lệnh Autopilot**:
|
||||
```text
|
||||
/laravel-unit-test --all --run
|
||||
```
|
||||
### 🔹 Giai đoạn 3: Viết Unit Test (Tách bạch pha Viết và pha Chạy)
|
||||
|
||||
**Quá trình AI thực hiện tự động hoàn toàn:**
|
||||
1. **Quét & Lập Manifest**: AI quét toàn bộ `app/Services/`, `app/Actions/`, `app/Http/Requests/`, `app/Jobs/`, `app/Policies/`, `app/Rules/`,... và tạo file kiểm soát `tests/.test-manifest.json` (ví dụ: Tổng cộng 36 files).
|
||||
2. **Viết test tuần tự**: AI duyệt từng file `[1/36]`, `[2/36]`... sinh mã test chuẩn AAA, đầy đủ kịch bản Happy Path, Edge Cases (0, âm, null, rỗng) và Exception.
|
||||
3. **Chạy test & Tự động sửa lỗi (Auto-Healing)**:
|
||||
- Viết xong file nào, AI tự động gọi `./test-runner.sh --filter=<TênTest>` để chạy test file đó ngay.
|
||||
- Nếu test bị ĐỎ (Fail) do thiếu mock hoặc sai tham số -> AI tự động đọc log lỗi, tự sửa code test ngay tại chỗ cho đến khi XANH (Pass 100%).
|
||||
Để đạt **hiệu suất cao nhất và độ phủ 100% nhánh SonarQube**, bạn nên áp dụng quy trình chuẩn Pro:
|
||||
|
||||
#### 🏆 Cách Khuyên Dùng (Cho Dự Án Lớn): Viết Tập Trung Theo Từng Tầng (Batch Mode)
|
||||
Tránh việc vừa viết vừa chạy test làm AI bị phân tâm và tràn context. Hãy để AI dồn 100% tài nguyên viết sâu từng tầng:
|
||||
```text
|
||||
# 1. Viết toàn bộ tầng Services:
|
||||
/laravel-unit-test app/Services/
|
||||
|
||||
# 2. Sau khi xong, viết tiếp tầng Actions & Requests:
|
||||
/laravel-unit-test app/Actions/
|
||||
/laravel-unit-test app/Http/Requests/
|
||||
```
|
||||
*AI sẽ tạo trọn bộ các file test với đầy đủ kịch bản Happy Path, Edge Cases, Exception và Branch Coverage mà không bị gián đoạn.*
|
||||
|
||||
---
|
||||
|
||||
### 🔹 Giai đoạn 4: Nghiệm thu kết quả & Kiểm tra Code Coverage
|
||||
Sau khi hoàn tất toàn bộ danh sách trong manifest, AI sẽ tự động chạy:
|
||||
#### 🌟 Cách Thay Thế: Autopilot Khép Kín (Cho Dự Án Vừa & Nhỏ)
|
||||
Nếu dự án có ít file (< 15 files) và bạn muốn AI tự động viết và chạy test thử nghiệm luôn:
|
||||
```text
|
||||
/laravel-unit-test --all --run
|
||||
```
|
||||
AI sẽ tự lập manifest, viết đến đâu gọi `./test-runner.sh` đến đó và tự sửa lỗi nếu test fail.
|
||||
|
||||
---
|
||||
|
||||
### 🔹 Giai đoạn 4: Chạy Test Đồng Loạt Ngoài Terminal & Đo Độ Phủ SonarQube
|
||||
Sau khi tất cả các file test đã được AI viết xong, bạn quay ra Terminal và chạy 1 lệnh duy nhất:
|
||||
```bash
|
||||
./test-runner.sh --coverage
|
||||
```
|
||||
*Tốc độ siêu nhanh vì chạy trên SQLite In-Memory. Nếu muốn xuất file báo cáo cho SonarQube:*
|
||||
```bash
|
||||
./test-runner.sh --coverage-clover coverage.xml
|
||||
```
|
||||
|
||||
Bảng báo cáo nghiệm thu sẽ xuất hiện:
|
||||
```markdown
|
||||
🎉 HOÀN TẤT VIẾT VÀ TEST TOÀN BỘ DỰ ÁN:
|
||||
✓ Tổng số class đã phủ test: 36/36 files (100%)
|
||||
✓ Tổng số test cases được sinh: 142 test cases
|
||||
✓ Kết quả thực thi: 142 PASSED (0 FAILED)
|
||||
✓ Code Coverage: 86.4% (Đạt tiêu chuẩn Quality Gate > 80%)
|
||||
✓ Code Coverage: 95.8% (Đạt tiêu chuẩn Quality Gate SonarQube > 80%)
|
||||
```
|
||||
|
||||
Nếu phát hiện 1 file test nào bị đỏ, bạn chỉ cần yêu cầu AI sửa đúng file đó:
|
||||
```text
|
||||
/laravel-test-review tests/Unit/Services/PaymentServiceTest.php
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🔹 Giai đoạn 5 (Tùy chọn): Các chế độ chạy linh hoạt khác
|
||||
Nếu không muốn chạy cả dự án, bạn có thể chọn các chế độ linh hoạt sau:
|
||||
### 🔹 Giai đoạn 5: Các chế độ chạy linh hoạt khác
|
||||
- **Chỉ viết cho 1 class & test luôn**:
|
||||
```text
|
||||
/laravel-unit-test app/Services/PaymentService.php --run
|
||||
```
|
||||
- **Chỉ viết cho cả 1 thư mục & test luôn**:
|
||||
```text
|
||||
/laravel-unit-test app/Services/ --run
|
||||
```
|
||||
- **Chỉ viết cho các file vừa sửa đổi trên Git trước khi tạo PR**:
|
||||
```text
|
||||
/laravel-unit-test --changed --run
|
||||
/laravel-unit-test --changed
|
||||
```
|
||||
- **Quét danh sách class chưa có test theo độ ưu tiên**:
|
||||
```text
|
||||
/laravel-unit-test --untested
|
||||
```
|
||||
- **Thẩm định & Chấm điểm 1 file test có sẵn (thang 100)**:
|
||||
```text
|
||||
@@ -249,7 +271,7 @@ Khi repository công cụ trên Git có tài liệu mới hoặc nâng cấp rul
|
||||
### 🌟 Cách 1: Cập nhật trực tiếp vào source code hiện tại
|
||||
Đứng tại thư mục source code Laravel của bạn và chạy lại dòng lệnh cài đặt:
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/<OWNER>/agent-unit-testing/main/install.sh | bash
|
||||
curl -fsSL https://git.smartgift.io.vn/Smartgift-AI/agent-unit-testing/raw/branch/main/install.sh | bash
|
||||
```
|
||||
*(Script sẽ tự động kéo bản mới nhất và ghi đè cập nhật vào `.claude/skills/` và runner của source code).*
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# 10. Chiến Lược Đạt 100% Code Coverage Trên SonarQube
|
||||
|
||||
Tài liệu này giải thích chi tiết cách cấu hình và kỹ thuật viết Unit Test để đạt điểm tối đa (Line & Branch Coverage) khi quét qua hệ thống phân tích chất lượng mã nguồn **SonarQube / SonarCloud**.
|
||||
|
||||
---
|
||||
|
||||
## 1. Công Thức Tính Độ Phủ Của SonarQube
|
||||
|
||||
SonarQube tính toán chỉ số Coverage tổng hợp dựa trên cả dòng lệnh (Lines) lẫn điều kiện rẽ nhánh (Branches / Conditions):
|
||||
|
||||
$$\text{Coverage} = \frac{\text{Lines Covered} + \text{Branches Covered}}{\text{Total Lines} + \text{Total Branches}} \times 100\%$$
|
||||
|
||||
> ⚠️ **Lưu ý quan trọng**: Nếu một dòng code chạy qua nhưng chỉ thỏa mãn 1 trong 2 nhánh của toán tử ternary (`?:`) hoặc null coalescing (`??`), SonarQube sẽ tính là **Partially Covered** và trừ điểm độ phủ của dòng đó.
|
||||
|
||||
---
|
||||
|
||||
## 2. Cấu Hình Cốt Lõi: Scope & Exclusions
|
||||
|
||||
Không bao giờ đưa các file cấu hình hoặc framework boilerplate vào phạm vi đo Coverage. Trong file cấu hình `sonar-project.properties` tại thư mục gốc dự án:
|
||||
|
||||
```properties
|
||||
# 1. Khai báo đường dẫn file báo cáo Coverage sinh ra từ PHPUnit
|
||||
sonar.php.coverage.reportPaths=coverage.xml
|
||||
|
||||
# 2. Phạm vi đo Coverage: CHỈ ĐO CÁC TẦNG CHỨA LOGIC NGHIỆP VỤ
|
||||
sonar.coverage.inclusions=app/Services/**,app/Actions/**,app/Rules/**,app/Jobs/**,app/Policies/**,app/Http/Requests/**,app/Models/**
|
||||
|
||||
# 3. Loại trừ các file framework, boilerplate không cần viết Unit Test
|
||||
sonar.coverage.exclusions=app/Providers/**,app/Console/Kernel.php,app/Http/Middleware/TrustProxies.php,bootstrap/**,config/**,database/**,tests/**
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Cách Xuất Báo Cáo Coverage Chuẩn SonarQube (`coverage.xml`)
|
||||
|
||||
Trong file `phpunit.xml` (hoặc `phpunit.xml.dist`), bổ sung cấu hình xuất định dạng Clover XML:
|
||||
|
||||
```xml
|
||||
<coverage>
|
||||
<report>
|
||||
<clover outputFile="coverage.xml"/>
|
||||
<html outputDirectory="coverage-html"/>
|
||||
</report>
|
||||
</coverage>
|
||||
```
|
||||
|
||||
Hoặc khi chạy lệnh thông qua `test-runner.sh`:
|
||||
```bash
|
||||
./test-runner.sh --coverage-clover coverage.xml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Checklist Đánh Bay Các Lỗi "Uncovered Branches" Của SonarQube
|
||||
|
||||
Khi AI hoặc dev viết test, cần kiểm tra 5 bẫy rẽ nhánh sau để chạm mốc 100%:
|
||||
|
||||
### A. Toán tử Null Coalescing (`??`)
|
||||
```php
|
||||
// Code nguồn:
|
||||
$timeout = $config['timeout'] ?? 30;
|
||||
```
|
||||
- **Test Case 1 (Left branch)**: Truyền `$config` có chứa key `'timeout' => 60`.
|
||||
- **Test Case 2 (Right branch)**: Truyền `$config = []` (không có key `'timeout'`).
|
||||
|
||||
### B. Toán tử Ternary (`?:`) và Guard Clauses
|
||||
```php
|
||||
// Code nguồn:
|
||||
return $user->isVip() ? 0.2 : 0.05;
|
||||
```
|
||||
- **Test Case 1**: Truyền user với `isVip() === true`.
|
||||
- **Test Case 2**: Truyền user với `isVip() === false`.
|
||||
|
||||
### C. Khối `try - catch - finally`
|
||||
```php
|
||||
// Code nguồn:
|
||||
try {
|
||||
return $this->gateway->charge($amount);
|
||||
} catch (PaymentException $e) {
|
||||
Log::error($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
```
|
||||
- **Bắt buộc**: Phải có 1 bài test giả lập mock `->andThrow(new PaymentException('Lỗi cổng thanh toán'))` để ép luồng chạy vào trong khối `catch`.
|
||||
|
||||
### D. Switch / Match Expression
|
||||
Mọi case trong `match` hoặc `switch` (kể cả nhánh `default`) đều phải có ít nhất 1 bài test kích hoạt.
|
||||
Reference in New Issue
Block a user