Files
agent-unit-testing/docs/cakephp/01-cakephp-testing-guide.md
T
Pham-Tan-Thien da1bd48444 feat: decouple Laravel and CakePHP installers, remove SonarQube artifacts, and enforce complete unit testing standards
- 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
2026-09-17 14:25:02 +07:00

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

  1. 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.
  2. 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.
  3. 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

  1. Chạy qua Smart Test Runner:
    ./test-runner.sh
    # Chạy 1 file test cụ thể:
    ./test-runner.sh --filter=ArticlesControllerTest
    
  2. Chạy qua CakePHP CLI:
    bin/cake test app tests/TestCase/Model/Table/ArticlesTableTest.php
    
  3. Chạy qua PHPUnit trực tiếp:
    vendor/bin/phpunit --filter=ArticlesTableTest
    
  4. Đo Code Coverage:
    ./test-runner.sh --coverage