From c29bfb9c31ad78edab0639253fb1b74031b17a54 Mon Sep 17 00:00:00 2001 From: thienpt Date: Tue, 8 Sep 2026 11:06:23 +0700 Subject: [PATCH] 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 --- .claude/skills/laravel-unit-test/skill.md | 64 +++++++------- README.md | 68 ++++++++++----- ...10-sonarqube-100-percent-coverage-guide.md | 87 +++++++++++++++++++ 3 files changed, 167 insertions(+), 52 deletions(-) create mode 100644 docs/10-sonarqube-100-percent-coverage-guide.md diff --git a/.claude/skills/laravel-unit-test/skill.md b/.claude/skills/laravel-unit-test/skill.md index 1acde5b..7dd0ab0 100644 --- a/.claude/skills/laravel-unit-test/skill.md +++ b/.claude/skills/laravel-unit-test/skill.md @@ -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 ``` diff --git a/README.md b/README.md index 971cbd5..81973a9 100644 --- a/README.md +++ b/README.md @@ -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=` để 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//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).* diff --git a/docs/10-sonarqube-100-percent-coverage-guide.md b/docs/10-sonarqube-100-percent-coverage-guide.md new file mode 100644 index 0000000..d271d5f --- /dev/null +++ b/docs/10-sonarqube-100-percent-coverage-guide.md @@ -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 + + + + + + +``` + +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.