Files
agent-unit-testing/docs/10-sonarqube-100-percent-coverage-guide.md
T
Pham-Tan-Thien c29bfb9c31 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>
2026-09-08 11:06:23 +07:00

3.4 KiB

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:

# 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:

<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:

./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 (??)

// 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

// 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

// 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.