Hướng Dẫn Kiểm Thử
Tài liệu kiểm thử toàn diện cho Jankx Theme.
Bắt Đầu
Cài Đặt
# Cài PHPUnit và dependencies
composer install --dev
# Xác minh cài đặt
./vendor/bin/phpunit --version
Cấu Hình
phpunit.xml:
<phpunit bootstrap="tests/bootstrap.php"
colors="true"
verbose="true">
<testsuites>
<testsuite name="Admin">
<directory>tests/Admin</directory>
</testsuite>
<testsuite name="Extensions">
<directory>tests/Extensions</directory>
</testsuite>
<testsuite name="Layouts">
<directory>tests/Layouts</directory>
</testsuite>
<testsuite name="Services">
<directory>tests/Services</directory>
</testsuite>
</testsuites>
</phpunit>
Cấu Trúc Tests
tests/
├── Admin/
│ └── Handlers/
│ └── FormHandlerTest.php
├── Extensions/
│ └── ExtensionManagerTest.php
├── Layouts/
│ └── DynamicDataLayout/
│ └── LayoutRegistryTest.php
├── Services/
│ ├── Fonts/
│ │ └── FontsRepositoryTest.php
│ └── GutenbergServiceTest.php
├── Helpers/
│ └── TestCase.php
├── bootstrap.php
└── phpunit.xml
Chạy Tests
Chạy Tất Cả
./vendor/bin/phpunit
Chạy Test Suite Cụ Thể
# Chỉ Admin tests
./vendor/bin/phpunit --testsuite="Admin"
# Chỉ Extension tests
./vendor/bin/phpunit --testsuite="Extensions"
# Chỉ Layout tests
./vendor/bin/phpunit --testsuite="Layouts"
Chạy Với Coverage
# Báo cáo HTML
./vendor/bin/phpunit --coverage-html coverage/
# Báo cáo text
./vendor/bin/phpunit --coverage-text
Viết Tests
Class Test Cơ Bản
<?php
namespace Tests\Admin\Handlers;
use Jankx\Admin\Handlers\FormHandler;
use Jankx\Foundation\Application;
use Tests\Helpers\TestCase;
class FormHandlerTest extends TestCase
{
protected $formHandler;
protected $app;
protected function setUp(): void
{
parent::setUp();
$this->app = new Application();
$this->formHandler = new FormHandler($this->app);
}
public function testConstructor()
{
$this->assertInstanceOf(FormHandler::class, $this->formHandler);
}
public function testHandleRequestsProcessesValidNonce()
{
// Mock WordPress nonce verification
$GLOBALS['mock_wp_verify_nonce'] = true;
$_POST = [
'jankx_action' => 'save_settings',
'jankx_nonce' => 'valid_nonce',
];
$result = $this->formHandler->handleRequests();
$this->assertTrue($result);
}
}
Dùng Mockery
use Mockery;
public function testExtensionActivation()
{
// Tạo mock extension
$mockExtension = Mockery::mock('Jankx\Extensions\AbstractExtension');
$mockExtension->shouldReceive('activate')->once();
$mockExtension->shouldReceive('getId')->andReturn('test-extension');
// Đăng ký và kích hoạt
$manager = new ExtensionManager($this->app);
$manager->add_extension('test', $mockExtension);
$manager->activate_extension('test');
$this->assertTrue($manager->is_extension_active('test'));
}
Test Với Facades
use Jankx\Facades\Config;
public function testConfigFacade()
{
// Setup facade application
Config::setFacadeApplication($this->app);
// Mock config value
$this->app->shouldReceive('get')
->with('config.framework')
->andReturn('jankx');
$this->assertEquals('jankx', Config::get('framework'));
}
Code Coverage
| Component | Tests | Coverage |
|---|---|---|
| Admin/Handlers | 15 | Cao |
| Extensions | 12 | Trung bình |
| Layouts | 14 | Cao |
| Services/Fonts | 15 | Trung bình |
| Services/Gutenberg | 11 | Trung bình |
| Tổng | 266 | Tốt |
Tạo Báo Cáo
# Tạo báo cáo coverage HTML
./vendor/bin/phpunit --coverage-html coverage/
# Mở trong trình duyệt
open coverage/index.html
Các Nguyên Tắc Tốt
- Đặt Tên Test - Dùng tên mô tả như
testHandleRequestsReturnsFalseForInvalidNonce - Cấu Trúc Test (AAA) - Arrange, Act, Assert
- Một Khái Niệm Mỗi Test - Tách các mối quan tâm thành test riêng
- Dùng Assertions Mô Tả - Chọn assertion phù hợp
- Dọn Dẹp Resources - Reset state trong
tearDown()
Xử Lý Lỗi
Lỗi: A facade root has not been set
// Giải pháp: Setup facade application trong setUp()
\Jankx\Facades\App::setFacadeApplication($this->app);
Lỗi: Call to undefined function
// Giải pháp: Thêm mock vào bootstrap.php
if (!function_exists('my_wp_function')) {
function my_wp_function() {
return $GLOBALS['mock_my_wp_function'] ?? null;
}
}
Lỗi: InvalidCountException với Mockery
// Giải pháp: Đóng Mockery đúng cách
tearDown() {
Mockery::close();
parent::tearDown();
}