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,82 @@
|
||||
# 01. Overview & Core Principles of Laravel Unit Testing
|
||||
|
||||
Tài liệu này định nghĩa triết lý, nguyên tắc kiến trúc và tiêu chuẩn cốt lõi khi viết Unit Test cho mã nguồn Laravel.
|
||||
|
||||
---
|
||||
|
||||
## 1. Bản chất của Unit Test trong Laravel
|
||||
|
||||
### A. Định nghĩa Unit Test (Kiểm thử đơn vị)
|
||||
- **Đối tượng**: Kiểm thử một Class duy nhất, một Method duy nhất, hoặc một đoạn Business Logic độc lập.
|
||||
- **Phạm vi**: Hoàn toàn **cô lập (Isolated)**. Tất cả các thành phần ngoại vi (Database, Third-party API, File System, Queue, Mail, Event) đều phải được **giả lập (Mocked/Faked/Stubbed)**.
|
||||
- **Tốc độ**: Cực nhanh (dưới 10ms - 50ms cho mỗi test case). Toàn bộ bộ Unit Test của một hệ thống lớn phải chạy xong trong vài giây.
|
||||
|
||||
### B. Ranh giới giữa Unit Test và Feature/Integration Test
|
||||
Sự nhầm lẫn giữa Unit Test và Feature Test là nguyên nhân số 1 khiến test bị chậm và khó bảo trì:
|
||||
|
||||
| Tiêu chí | Unit Test | Feature / Integration Test |
|
||||
| :--- | :--- | :--- |
|
||||
| **Đối tượng test** | 1 Class / Method cụ thể (Service, Action, Value Object, Rule,...) | Toàn bộ luồng nghiệp vụ (Endpoint, Controller, Middleware, DB) |
|
||||
| **Kế thừa TestCase** | `PHPUnit\Framework\TestCase` (thuần) hoặc `Tests\TestCase` (tối giản) | `Tests\TestCase` (boot toàn bộ Laravel Kernel) |
|
||||
| **Database** | **KHÔNG DÙNG** Database thật (Mock repository/model) | Có dùng DB (thường dùng `RefreshDatabase` với SQLite/MySQL) |
|
||||
| **HTTP Request** | Không dispatch HTTP request thật | Dùng `$this->getJson()`, `$this->postJson()` |
|
||||
| **External Service** | Mock bằng Mockery hoặc Anonymous Stub | Fake bằng `Http::fake()`, `Event::fake()` |
|
||||
| **Thời gian chạy** | Siêu nhanh (vài milliseconds) | Chậm hơn (vài chục đến hàng trăm milliseconds) |
|
||||
|
||||
> ⚠️ **Quy tắc vàng**: Nếu một test cần chạy migration, chèn dữ liệu vào bảng, gọi HTTP endpoint qua router -> Đó là **Feature Test**, KHÔNG PHẢI Unit Test.
|
||||
|
||||
---
|
||||
|
||||
## 2. Quy chuẩn Cấu trúc: Mô hình AAA (Arrange - Act - Assert)
|
||||
|
||||
Mọi bài test đơn vị đều phải tuân thủ nghiêm ngặt 3 giai đoạn:
|
||||
|
||||
```php
|
||||
#[Test]
|
||||
public function it_calculates_total_price_with_discount_successfully(): void
|
||||
{
|
||||
// 1. ARRANGE (Chuẩn bị dữ liệu đầu vào & thiết lập Mock)
|
||||
$discountServiceMock = Mockery::mock(DiscountServiceInterface::class);
|
||||
$discountServiceMock->shouldReceive('getPercentage')
|
||||
->once()
|
||||
->with('SUMMER2026')
|
||||
->andReturn(20.0);
|
||||
|
||||
$cartService = new CartService($discountServiceMock);
|
||||
$items = [
|
||||
new CartItem(name: 'Item A', price: 100_000, quantity: 2), // 200,000
|
||||
];
|
||||
|
||||
// 2. ACT (Thực thi hành động cần test)
|
||||
$finalPrice = $cartService->calculateTotal($items, 'SUMMER2026');
|
||||
|
||||
// 3. ASSERT (Kiểm tra kết quả và xác thực side-effects)
|
||||
$this->assertSame(160_000.0, $finalPrice);
|
||||
}
|
||||
```
|
||||
|
||||
- **Arrange**: Chuẩn bị đầy đủ input, khởi tạo đối tượng cần test, thiết lập kỳ vọng cho các dependency mock.
|
||||
- **Act**: Gọi chính xác 1 method của đối tượng cần test. Không gọi lồng nhiều hành động.
|
||||
- **Assert**: So sánh kết quả trả về với kỳ vọng; xác nhận mock method được gọi đúng số lần và đúng tham số.
|
||||
|
||||
---
|
||||
|
||||
## 3. Các Nguyên tắc Cốt lõi (Core Principles)
|
||||
|
||||
### 1. Nguyên tắc Đơn nhiệm (Single Concept per Test)
|
||||
Mỗi test method chỉ kiểm tra **một khía cạnh duy nhất** của logic:
|
||||
- 1 test cho trường hợp thành công (Happy path).
|
||||
- 1 test cho trường hợp dữ liệu rỗng/null.
|
||||
- 1 test cho trường hợp văng Exception khi đầu vào sai.
|
||||
❌ Không gộp tất cả các kịch bản if/else vào chung một test method dài 100 dòng.
|
||||
|
||||
### 2. Tính Độc lập & Không Phụ thuộc Thứ tự (Independent & Isolated)
|
||||
- Test case A chạy trước hay test case B chạy trước không được làm ảnh hưởng kết quả của nhau.
|
||||
- Không chia sẻ trạng thái biến toàn cục (global state) hoặc static variable mà không dọn dẹp sau mỗi test (`tearDown()`).
|
||||
|
||||
### 3. Nguyên tắc FIRST trong Unit Testing
|
||||
- **F - Fast**: Chạy trong chớp mắt.
|
||||
- **I - Isolated / Independent**: Không phụ thuộc môi trường mạng, database bên ngoài.
|
||||
- **R - Repeatable**: Chạy 100 lần trên máy local hay CI/CD đều cho ra kết quả giống nhau.
|
||||
- **S - Self-validating**: Test tự xác nhận Pass hoặc Fail qua Assertions, không cần người đọc log để đoán.
|
||||
- **T - Thorough / Timely**: Bao phủ từ Happy Path cho đến các trường hợp biên khắc nghiệt (Edge cases).
|
||||
Reference in New Issue
Block a user