- การตรวจสอบคุณภาพโค้ดด้วย SonarQube: ตัวอย่าง Express และ Laravel
- ส่วนที่ 1: วิเคราะห์โครงการ Express.js
- ส่วนที่ 2: วิเคราะห์โครงการ Laravel
- 9. โครงสร้างที่เกี่ยวข้องใน Laravel
- 10. เตรียม PHPUnit Coverage
- 11. ตั้งค่า phpunit.xml
- 12. ตั้งค่า sonar-project.properties สำหรับ Laravel
- 13. รัน SonarScanner สำหรับ Laravel
- 14. ตัวอย่าง GitHub Actions สำหรับ Express
- 15. ตัวอย่าง GitHub Actions สำหรับ Laravel
- 16. ตัวอย่าง Quality Gate สำหรับทีมพัฒนา
- 17. วิธีอ่านผลบน Dashboard
- 18. ปัญหาที่พบบ่อย
- 19. แนวปฏิบัติที่แนะนำ
- 20. Checklist สำหรับนำไปใช้จริง
- สรุป
- เอกสารอ้างอิง
#การตรวจสอบคุณภาพโค้ดด้วย SonarQube: ตัวอย่าง Express และ Laravel
การตรวจสอบคุณภาพโค้ดไม่ควรเกิดขึ้นเฉพาะตอนใกล้นำระบบขึ้น Production เพราะปัญหาอย่างโค้ดซ้ำ เงื่อนไขที่ซับซ้อน ช่องโหว่ และ Technical Debt จะสะสมจนแก้ไขยากขึ้นเรื่อย ๆ
SonarQube เป็นแพลตฟอร์ม Static Code Analysis ที่ช่วยวิเคราะห์ซอร์สโค้ดโดยอัตโนมัติ พร้อมแสดงผลด้าน Reliability, Security และ Maintainability รวมถึง Code Duplication, Test Coverage และ Security Hotspots ผ่าน Dashboard และ Quality Gate
บทความนี้สาธิตการใช้งานกับ 2 โครงการที่พบได้บ่อย ได้แก่
- Express.js ใช้ Jest สร้างรายงาน Coverage รูปแบบ LCOV
- Laravel ใช้ PHPUnit สร้างรายงาน Coverage รูปแบบ Clover XML
SonarQube ไม่ได้รัน Unit Test และไม่ได้สร้าง Coverage Report ให้เรา หน้าที่นี้เป็นของ Jest, PHPUnit หรือเครื่องมือทดสอบอื่น จากนั้น SonarScanner จึงอ่านรายงานและส่งผลไปยัง SonarQube
#1. ภาพรวมกระบวนการทำงาน
flowchart LR
A[Developer Commit Code] --> B[Run Unit Tests]
B --> C[Generate Coverage Report]
C --> D[Run SonarScanner]
D --> E[SonarQube Analysis]
E --> F{Quality Gate}
F -->|Passed| G[Build / Deploy ต่อ]
F -->|Failed| H[แก้ Bug, Vulnerability, Code Smell]
กระบวนการมาตรฐานควรเป็นดังนี้
- นักพัฒนาส่งโค้ดขึ้น Repository
- CI ติดตั้ง Dependency
- CI รัน Unit Test และสร้าง Coverage Report
- SonarScanner วิเคราะห์ซอร์สโค้ดและนำเข้า Coverage Report
- SonarQube ประเมินผลตาม Quality Profile
- Quality Gate ตัดสินว่าโครงการผ่านเกณฑ์หรือไม่
- Pipeline หยุดทันทีเมื่อคุณภาพไม่ผ่านเกณฑ์ที่ทีมกำหนด
#2. SonarQube ตรวจสอบอะไรบ้าง
#2.1 Reliability
ค้นหาปัญหาที่อาจทำให้โปรแกรมทำงานผิดพลาด เช่น
- Null หรือ Undefined ที่ไม่ได้ตรวจสอบ
- เงื่อนไขที่ไม่มีทางเกิดขึ้น
- Resource ที่ไม่ได้ปิด
- การจัดการ Exception ไม่เหมาะสม
- Logic ที่อาจให้ผลลัพธ์ผิด
#2.2 Security
ตรวจหาช่องโหว่หรือรูปแบบโค้ดที่เสี่ยง เช่น
- SQL Injection
- Path Traversal
- Hard-coded Credentials
- Weak Cryptography
- การรับข้อมูลจากผู้ใช้โดยไม่ Validate
- การตั้งค่า CORS หรือ Cookie ที่ไม่ปลอดภัย
#2.3 Maintainability
ตรวจสอบ Code Smell ที่ทำให้โค้ดดูแลยาก เช่น
- Method ยาวเกินไป
- Cyclomatic Complexity สูง
- Nested Condition หลายชั้น
- ชื่อตัวแปรไม่สื่อความหมาย
- Dead Code
- Duplicate Code
#2.4 Test Coverage
SonarQube นำเข้ารายงาน Coverage จากเครื่องมือทดสอบ เพื่อแสดงว่าโค้ดส่วนใดถูกทดสอบแล้ว แต่ Coverage สูงไม่ได้รับประกันว่า Test มีคุณภาพ จึงควรประเมินร่วมกับ Assertion, Test Scenario และ Mutation Testing
#2.5 Security Hotspots
Security Hotspot คือโค้ดที่ต้องให้ผู้พัฒนาหรือผู้ตรวจสอบพิจารณาว่าใช้งานอย่างปลอดภัยหรือไม่ เช่น การสร้าง Token, การตั้งค่า Cookie, การเข้ารหัส หรือการเปิดใช้ CORS
#3. ติดตั้ง SonarQube ด้วย Docker Compose
ตัวอย่างนี้ใช้ SonarQube Community Build และ PostgreSQL โดย Pin เวอร์ชัน SonarQube เพื่อให้ผลการติดตั้งทำซ้ำได้
สร้างไฟล์ compose.yaml
services:
postgres:
image: postgres:17-alpine
container_name: sonar-postgres
restart: unless-stopped
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar_password
POSTGRES_DB: sonarqube
volumes:
- sonar_postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U sonar -d sonarqube"]
interval: 10s
timeout: 5s
retries: 10
networks:
- sonar-network
sonarqube:
image: sonarqube:26.7.0.124771-community
container_name: sonarqube
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
SONAR_JDBC_URL: jdbc:postgresql://postgres:5432/sonarqube
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar_password
ports:
- "9000:9000"
volumes:
- sonar_data:/opt/sonarqube/data
- sonar_logs:/opt/sonarqube/logs
- sonar_extensions:/opt/sonarqube/extensions
networks:
- sonar-network
networks:
sonar-network:
name: sonar-network
volumes:
sonar_postgres_data:
sonar_data:
sonar_logs:
sonar_extensions:
เริ่มระบบ
docker compose up -d
ตรวจสอบสถานะ
docker compose ps
docker compose logs -f sonarqube
เปิดหน้าเว็บ
http://localhost:9000
บัญชีเริ่มต้นสำหรับการติดตั้งใหม่โดยทั่วไปคือ
Username: admin
Password: admin
ระบบจะบังคับให้เปลี่ยนรหัสผ่านหลังเข้าสู่ระบบครั้งแรก
สำหรับระบบจริง ควรเปลี่ยน Password ใน Compose ไปใช้ Docker Secrets หรือ Secret Manager และไม่ควร Commit Secret ลง Git
#การตั้งค่า Linux Host
SonarQube ใช้ Elasticsearch ภายใน จึงอาจต้องตั้งค่า Kernel และ File Descriptor บน Linux
sudo sysctl -w vm.max_map_count=524288
sudo sysctl -w fs.file-max=131072
ulimit -n 131072
ulimit -u 8192
เมื่อต้องการให้คงอยู่หลัง Restart ให้เพิ่มค่า Kernel ลงใน /etc/sysctl.conf หรือไฟล์ภายใต้ /etc/sysctl.d/
#4. สร้าง Project และ Token ใน SonarQube
- เข้าสู่ระบบ SonarQube
- เลือก Create Project
- เลือกสร้างโครงการแบบ Local
- กำหนด Project Key เช่น
express-apiหรือlaravel-api - สร้าง Analysis Token
- บันทึก Token ไว้ใน Environment Variable
ตัวอย่างบน Linux หรือ macOS
export SONAR_TOKEN="ค่าของ-token"
PowerShell
$env:SONAR_TOKEN="ค่าของ-token"
ไม่ควรใส่ Token ลงใน sonar-project.properties หรือ Commit ลง Repository
#ส่วนที่ 1: วิเคราะห์โครงการ Express.js
#5. โครงสร้างตัวอย่าง Express
express-api/
├── src/
│ ├── app.js
│ └── services/
│ └── user-service.js
├── tests/
│ └── app.test.js
├── coverage/
├── jest.config.js
├── package.json
└── sonar-project.properties
#6. ติดตั้ง Jest และ Supertest
npm install --save-dev jest supertest
ปรับ package.json
{
"scripts": {
"start": "node src/app.js",
"test": "jest",
"test:coverage": "jest --coverage"
}
}
สร้าง jest.config.js
/** @type {import('jest').Config} */
module.exports = {
testEnvironment: 'node',
testMatch: ['**/tests/**/*.test.js'],
collectCoverageFrom: [
'src/**/*.js',
'!src/**/*.config.js'
],
coverageDirectory: 'coverage',
coverageReporters: ['text', 'lcov'],
};
เมื่อรันคำสั่งต่อไปนี้ Jest จะสร้างไฟล์ coverage/lcov.info
npm run test:coverage
#7. ตั้งค่า sonar-project.properties สำหรับ Express
สร้างไฟล์ sonar-project.properties ที่ Root ของโครงการ
sonar.projectKey=express-api
sonar.projectName=Express API
sonar.projectVersion=1.0.0
sonar.sources=src
sonar.tests=tests
sonar.test.inclusions=tests/**/*.test.js
sonar.exclusions=node_modules/**,coverage/**,dist/**
sonar.coverage.exclusions=src/**/*.config.js,src/server.js
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.sourceEncoding=UTF-8
#ความหมายของค่าหลัก
| Property | หน้าที่ |
|---|---|
sonar.projectKey |
รหัสโครงการ ต้องตรงกับที่สร้างใน SonarQube |
sonar.sources |
ตำแหน่ง Source Code |
sonar.tests |
ตำแหน่ง Test Code |
sonar.test.inclusions |
Pattern สำหรับระบุไฟล์ Test |
sonar.exclusions |
ไฟล์ที่ไม่ต้องการวิเคราะห์ |
sonar.coverage.exclusions |
ไฟล์ที่วิเคราะห์ได้ แต่ไม่ต้องนำมาคำนวณ Coverage |
sonar.javascript.lcov.reportPaths |
ตำแหน่งรายงาน LCOV |
#8. รัน SonarScanner สำหรับ Express
#วิธีที่ 1: ใช้ SonarScanner CLI ที่ติดตั้งในเครื่อง
npm ci
npm run test:coverage
sonar-scanner \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token="$SONAR_TOKEN"
#วิธีที่ 2: ใช้ SonarScanner Docker Image
ให้รัน Unit Test บนเครื่องก่อน เพื่อสร้าง coverage/lcov.info
npm ci
npm run test:coverage
จากนั้นรัน Scanner ภายใน Network เดียวกับ SonarQube
docker run --rm \
--network sonar-network \
-e SONAR_HOST_URL="http://sonarqube:9000" \
-e SONAR_TOKEN="$SONAR_TOKEN" \
-v "$PWD:/usr/src" \
sonarsource/sonar-scanner-cli
สำหรับ PowerShell
docker run --rm `
--network sonar-network `
-e SONAR_HOST_URL="http://sonarqube:9000" `
-e SONAR_TOKEN="$env:SONAR_TOKEN" `
-v "${PWD}:/usr/src" `
sonarsource/sonar-scanner-cli
#ส่วนที่ 2: วิเคราะห์โครงการ Laravel
#9. โครงสร้างที่เกี่ยวข้องใน Laravel
laravel-api/
├── app/
├── config/
├── database/
├── routes/
├── tests/
│ ├── Feature/
│ └── Unit/
├── build/
│ └── logs/
├── phpunit.xml
└── sonar-project.properties
#10. เตรียม PHPUnit Coverage
PHPUnit ต้องใช้ Coverage Driver เช่น Xdebug หรือ PCOV
ตรวจสอบ Xdebug
php -m | grep xdebug
ตัวอย่างติดตั้ง Xdebug บน Ubuntu
sudo apt update
sudo apt install php-xdebug
ตรวจสอบ PHPUnit
php artisan test
สร้าง Coverage Report รูปแบบ Clover XML
mkdir -p build/logs
XDEBUG_MODE=coverage vendor/bin/phpunit \
--coverage-text \
--coverage-clover=build/logs/clover.xml
กรณีรัน Laravel ผ่าน Docker Compose
docker compose exec -e XDEBUG_MODE=coverage app \
vendor/bin/phpunit \
--coverage-text \
--coverage-clover=build/logs/clover.xml
ตรวจสอบว่าไฟล์ถูกสร้างแล้ว
ls -lh build/logs/clover.xml
#11. ตั้งค่า phpunit.xml
ตัวอย่างส่วนสำคัญใน phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true">
<testsuites>
<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory>tests/Feature</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">app</directory>
</include>
</source>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_STORE" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
</php>
</phpunit>
#12. ตั้งค่า sonar-project.properties สำหรับ Laravel
sonar.projectKey=laravel-api
sonar.projectName=Laravel API
sonar.projectVersion=1.0.0
sonar.sources=app,routes,config,database
sonar.tests=tests
sonar.test.inclusions=tests/**/*.php
sonar.exclusions=vendor/**,storage/**,bootstrap/cache/**,public/build/**,node_modules/**
sonar.coverage.exclusions=app/Providers/**,app/Console/**,database/migrations/**,routes/**,config/**
sonar.php.coverage.reportPaths=build/logs/clover.xml
sonar.sourceEncoding=UTF-8
#ควร Exclude อะไรบ้าง
ไม่ควร Exclude มากเกินไป เพราะจะทำให้ค่าคุณภาพดูดีเกินจริง โดยทั่วไปอาจ Exclude
vendor/**- Generated Files
- Cache และ Log
- Frontend Build Output
- Migration ที่ไม่ต้องการวัด Coverage
- Service Provider ที่มีเพียง Wiring Code
ไม่ควร Exclude Controller, Service, Repository หรือ Domain Logic เพียงเพราะเขียน Test ยาก
#13. รัน SonarScanner สำหรับ Laravel
สร้าง Coverage ก่อน
composer install --no-interaction --prefer-dist
mkdir -p build/logs
XDEBUG_MODE=coverage vendor/bin/phpunit \
--coverage-clover=build/logs/clover.xml
รัน Scanner
sonar-scanner \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token="$SONAR_TOKEN"
หรือใช้ Docker
docker run --rm \
--network sonar-network \
-e SONAR_HOST_URL="http://sonarqube:9000" \
-e SONAR_TOKEN="$SONAR_TOKEN" \
-v "$PWD:/usr/src" \
sonarsource/sonar-scanner-cli
#14. ตัวอย่าง GitHub Actions สำหรับ Express
สร้าง .github/workflows/sonarqube-express.yml
name: Express Quality Check
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
test-and-analyze:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
- name: Install dependencies
run: npm ci
- name: Run tests with coverage
run: npm run test:coverage
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v8.1.0
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
ตั้งค่าใน GitHub Repository
- Secret:
SONAR_TOKEN - Variable:
SONAR_HOST_URL
SonarQube แบบ Self-hosted ต้องเข้าถึงได้จาก GitHub-hosted Runner หาก Server อยู่ในเครือข่ายภายใน ให้ใช้ Self-hosted Runner, VPN หรือ Network Architecture ที่เหมาะสม
#15. ตัวอย่าง GitHub Actions สำหรับ Laravel
สร้าง .github/workflows/sonarqube-laravel.yml
name: Laravel Quality Check
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
test-and-analyze:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
coverage: xdebug
tools: composer:v2
- name: Install dependencies
run: composer install --no-interaction --prefer-dist --no-progress
- name: Prepare environment
run: |
cp .env.example .env
php artisan key:generate
mkdir -p build/logs
- name: Run tests with coverage
env:
XDEBUG_MODE: coverage
run: vendor/bin/phpunit --coverage-clover=build/logs/clover.xml
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v8.1.0
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
ในโครงการจริง อาจต้องเพิ่ม Service Container สำหรับ PostgreSQL, MySQL หรือ Redis ตาม Dependency ของ Test Suite
#16. ตัวอย่าง Quality Gate สำหรับทีมพัฒนา
Quality Gate คือชุดเงื่อนไขที่ใช้ตัดสินว่าผลวิเคราะห์ผ่านหรือไม่ ควรเน้น New Code เพื่อป้องกันไม่ให้ทีมสร้าง Technical Debt เพิ่ม
ตัวอย่างเกณฑ์เริ่มต้น
| Metric บน New Code | เกณฑ์แนะนำ |
|---|---|
| Reliability Rating | A |
| Security Rating | A |
| Maintainability Rating | A |
| Coverage | อย่างน้อย 80% |
| Duplicated Lines | ไม่เกิน 3% |
| Security Hotspots Reviewed | 100% |
| Blocker/Critical Issues | 0 |
ค่าดังกล่าวเป็นตัวอย่างนโยบายของทีม ไม่จำเป็นต้องเหมือนกันทุกโครงการ ระบบ Legacy อาจเริ่มจากเกณฑ์ที่ทำได้จริง แล้วเพิ่มความเข้มงวดเฉพาะ New Code
#17. วิธีอ่านผลบน Dashboard
#Overview
ใช้ดูภาพรวมของโครงการ เช่น Quality Gate, Issue Count, Coverage และ Duplication
#Issues
กรองตาม
- Severity
- Issue Type
- Rule
- File
- Assignee
- Status
ควรอ่านคำอธิบายของ Rule และแก้ Root Cause แทนการกด False Positive โดยไม่มีเหตุผล
#Measures
ใช้วิเคราะห์ Metric เชิงลึก เช่น
- Cognitive Complexity
- Cyclomatic Complexity
- Duplicated Blocks
- Lines to Cover
- Uncovered Lines
- Technical Debt
#Security Hotspots
ต้องมีผู้รับผิดชอบ Review และกำหนดสถานะว่า Safe หรือ Fixed พร้อมเหตุผลที่ตรวจสอบได้
#18. ปัญหาที่พบบ่อย
#18.1 Coverage เป็น 0%
ตรวจสอบตามลำดับ
# Express
ls -lh coverage/lcov.info
# Laravel
ls -lh build/logs/clover.xml
สาเหตุที่พบบ่อย
- ยังไม่ได้รัน Test ก่อน Scanner
- Report Path ไม่ตรง
- Coverage Report ไม่ได้ถูก Mount เข้า Scanner Container
- Path ภายใน Report ไม่ตรงกับ Working Directory
- Xdebug หรือ PCOV ไม่ทำงาน
#18.2 Scanner เชื่อมต่อ SonarQube ไม่ได้
หาก Scanner รันใน Container ห้ามใช้ localhost:9000 เพื่ออ้างถึง SonarQube Container ให้ใช้ชื่อ Service เช่น
http://sonarqube:9000
และต้องอยู่ใน Docker Network เดียวกัน
#18.3 SonarQube เริ่มระบบไม่ได้บน Linux
ตรวจสอบ
sysctl vm.max_map_count
ulimit -n
docker compose logs sonarqube
#18.4 Permission Denied บน Volume
ตรวจสอบสิทธิ์ของ Volume หรือ Bind Mount และไม่ควรแชร์ SonarQube Volume ชุดเดียวกันระหว่างหลาย Instance
#18.5 วิเคราะห์ไฟล์มากเกินไป
Exclude Dependency และ Generated Files เช่น
sonar.exclusions=node_modules/**,vendor/**,coverage/**,storage/**,public/build/**
#18.6 Quality Gate ไม่ทำให้ Pipeline ล้มเหลว
ตั้งค่าให้ Scanner รอผล Quality Gate
sonar-scanner \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token="$SONAR_TOKEN" \
-Dsonar.qualitygate.wait=true
การรอผลอาจทำให้ Pipeline ใช้เวลานานขึ้น จึงควรเลือกวิธีที่เหมาะกับ CI Platform และ Edition ที่ใช้งาน
#19. แนวปฏิบัติที่แนะนำ
- รัน Test ก่อน SonarScanner เสมอ เพื่อให้ Coverage Report พร้อมใช้งาน
- เน้นคุณภาพของ New Code มากกว่าบังคับแก้ Legacy Code ทั้งหมดทันที
- ไม่เก็บ Token ใน Repository ให้ใช้ Secret Management
- Pin Version ในระบบจริง ทั้ง SonarQube, Scanner และ GitHub Action
- ใช้
fetch-depth: 0ใน CI เพื่อให้ข้อมูล SCM และประวัติการเปลี่ยนแปลงสมบูรณ์ขึ้น - ตรวจสอบ Security Hotspots โดยมนุษย์ ไม่ใช่เพียงดูจำนวน Issue
- อย่า Exclude โค้ดธุรกิจเพื่อทำให้ Coverage สูงขึ้น
- กำหนด Owner ของ Issue และติดตาม Technical Debt ใน Sprint
- ใช้ SonarQube for IDE เพื่อพบปัญหาตั้งแต่ตอนเขียนโค้ด
- ทบทวน Quality Profile และ Quality Gate เป็นระยะ ให้สอดคล้องกับความเสี่ยงของระบบ
#20. Checklist สำหรับนำไปใช้จริง
- [ ] SonarQube และ PostgreSQL ทำงานปกติ
- [ ] เปลี่ยนรหัสผ่าน Administrator แล้ว
- [ ] สร้าง Project Key
- [ ] สร้าง Analysis Token
- [ ] เก็บ Token ใน Secret Manager
- [ ] กำหนด
sonar-project.properties - [ ] Unit Test ผ่าน
- [ ] Coverage Report ถูกสร้าง
- [ ] SonarScanner วิเคราะห์สำเร็จ
- [ ] Dashboard แสดง Coverage ถูกต้อง
- [ ] กำหนด Quality Gate
- [ ] เชื่อมต่อเข้ากับ CI/CD
- [ ] Pipeline หยุดเมื่อ Quality Gate ไม่ผ่าน
- [ ] ทีมมีขั้นตอน Review Security Hotspots
#สรุป
SonarQube ช่วยเปลี่ยนการตรวจสอบคุณภาพโค้ดจากกิจกรรมที่ทำเป็นครั้งคราวให้กลายเป็นกระบวนการอัตโนมัติใน Software Development Lifecycle
สำหรับ Express.js ให้ Jest สร้าง coverage/lcov.info แล้วกำหนด sonar.javascript.lcov.reportPaths ส่วน Laravel ให้ PHPUnit สร้าง build/logs/clover.xml แล้วกำหนด sonar.php.coverage.reportPaths
หัวใจสำคัญไม่ใช่การทำให้ Dashboard เป็นสีเขียวเพียงอย่างเดียว แต่คือการใช้ผลวิเคราะห์เพื่อป้องกัน Defect และ Technical Debt ใหม่ พร้อมสร้างมาตรฐานคุณภาพที่ทีมสามารถรักษาได้อย่างต่อเนื่อง