da1bd48444
- Decouple framework installation: add install-laravel.sh and install-cakephp.sh, isolate skills and docs per framework, and auto-clean leftover artifacts - Remove all SonarQube configs, templates, and references - Enforce comprehensive test completeness: 100% public methods, edge cases, full branch coverage, exception paths, and state assertions - Replace all placeholder assertions in PHPUnit and Pest templates with full realistic implementations - Rename and update 10-comprehensive-test-coverage-guide.md
4.8 KiB
4.8 KiB
🍰 CakePHP Unit & Integration Testing Guide
Cẩm nang toàn diện về quy chuẩn, kiến trúc và phương pháp kiểm thử tự động cho dự án PHP CakePHP (3.x, 4.x, 5.x+, PHP 7.4 đến 8.4+).
1. Triết Lý & Nguyên Tắc Cốt Lõi
-
Mô hình AAA (Arrange - Act - Assert):
- Mọi phương thức test bắt buộc phải có phân tách rõ ràng 3 bước:
// Arrange: Chuẩn bị payload, cấu hình session/auth, mock dependency.// Act: Thực thi phương thức (hoặc gọi HTTP endpoint, hoặc gọi console command).// Assert: So sánh kết quả, kiểm tra HTTP code, kiểm tra dữ liệu thay đổi trong DB.
- Mọi phương thức test bắt buộc phải có phân tách rõ ràng 3 bước:
-
Bảo Vệ Database Tuyệt Đối (Zero Leakage):
- Mọi test tương tác cơ sở dữ liệu PHẢI sử dụng kết nối
test(tốt nhất là SQLite in-memory:memory:). - Tuyệt đối không chạy test trên kết nối
default(tránh xóa nhầm hoặc làm bẩn dữ liệu dev/local). - Sử dụng cơ chế Transaction Strategy hoặc Fixture Strategy của CakePHP để rollback dữ liệu tự động sau mỗi test.
- Mọi test tương tác cơ sở dữ liệu PHẢI sử dụng kết nối
-
Phân Biệt Rõ Mocking vs Fixtures:
- Dùng Fixtures: Khi kiểm thử Table, Custom Finder, ORM query phức tạp.
- Dùng Mocks: Khi gọi Web service bên ngoài (Stripe, Twilio, AWS S3, External API) hoặc các Service Interface trừu tượng.
- Không Mock: Entity (dùng Entity thật), Array, DTOs, Value Objects.
2. Các Trait Kiểm Thử Quan Trọng của CakePHP
CakePHP cung cấp sẵn các Trait vô cùng mạnh mẽ trong Cake\TestSuite:
1. Cake\TestSuite\IntegrationTestTrait (Dành cho Controllers / HTTP Endpoints)
Cho phép gửi request HTTP ảo vào ứng dụng CakePHP mà không cần mở web server thật:
use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase;
class ArticlesControllerTest extends TestCase
{
use IntegrationTestTrait;
public function testIndex(): void
{
$this->get('/articles');
$this->assertResponseOk();
$this->assertResponseContains('Latest Articles');
}
public function testAddPostWithAuthAndCsrf(): void
{
// Giả lập đăng nhập
$this->session(['Auth.User.id' => 1, 'Auth.User.role' => 'admin']);
// Bật CSRF & Security token
$this->enableCsrfToken();
$this->enableSecurityToken();
$this->post('/articles/add', [
'title' => 'CakePHP Testing Pro',
'body' => 'High quality tests.',
]);
$this->assertResponseSuccess();
$this->assertRedirect(['action' => 'index']);
}
}
2. Cake\Console\TestSuite\ConsoleIntegrationTestTrait (Dành cho Commands / Shells)
Giúp test CLI Command một cách trực quan:
use Cake\Console\TestSuite\ConsoleIntegrationTestTrait;
use Cake\TestSuite\TestCase;
class SendReportCommandTest extends TestCase
{
use ConsoleIntegrationTestTrait;
public function setUp(): void
{
parent::setUp();
$this->useCommandRunner();
}
public function testExecuteSuccess(): void
{
$this->exec('send_report --daily');
$this->assertExitSuccess();
$this->assertOutputContains('Reports sent successfully');
}
}
3. Cake\TestSuite\EmailTrait (Dành cho Mailers)
Kiểm tra email được gửi đi mà không thực sự gửi qua SMTP:
use Cake\TestSuite\EmailTrait;
use Cake\TestSuite\TestCase;
class UserMailerTest extends TestCase
{
use EmailTrait;
public function testWelcomeEmail(): void
{
$mailer = new UserMailer();
$mailer->send('welcome', ['user@example.com', 'Alex']);
$this->assertMailSentTo('user@example.com');
$this->assertMailContainsText('Welcome Alex');
}
}
3. Quản Lý Test Database & Fixtures
Cấu hình SQLite In-Memory trong config/app_local.php:
'Datasources' => [
'test' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Sqlite',
'database' => ':memory:',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
],
],
Khai báo Fixtures trong Test Case:
protected array $fixtures = [
'app.Users',
'app.Articles',
];
4. Cách Chạy Test Tối Ưu
- Chạy qua Smart Test Runner:
./test-runner.sh # Chạy 1 file test cụ thể: ./test-runner.sh --filter=ArticlesControllerTest - Chạy qua CakePHP CLI:
bin/cake test app tests/TestCase/Model/Table/ArticlesTableTest.php - Chạy qua PHPUnit trực tiếp:
vendor/bin/phpunit --filter=ArticlesTableTest - Đo Code Coverage:
./test-runner.sh --coverage