Обзор тестирования — IO7 Framework
Внимание
Данная статья документации написана нейросетью. Возможны некоторые расхождения и неточность информации!
Обзор
IO7 поддерживает тестирование на основе PHPUnit 11. Фреймворк предоставляет базовый класс Tests\TestCase и структуру каталогов для unit и feature тестов.
Требования: PHP ^8.2, Illuminate (Laravel 13), PHPUnit 11
Конфигурация
phpunit.xml
<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>
</phpunit>
composer.json
{
"scripts": {
"test": "phpunit",
"test:unit": "phpunit --testsuite Unit",
"test:feature": "phpunit --testsuite Feature"
}
}
Структура тестов
tests/
├── TestCase.php # Базовый класс
├── Unit/
│ ├── Auth/
│ │ └── TokenManagerTest.php
│ ├── Database/
│ │ ├── DatabaseManagerTest.php
│ │ ├── ConnectionManagerTest.php
│ │ └── SqlConnectionTest.php
│ ├── Console/
│ │ └── CommandTest.php
│ ├── Profile/
│ │ └── PinbaManagerTest.php
│ ├── EventTest.php
│ ├── FormBuilderTest.php
│ └── ContainerTest.php
└── Feature/
└── ...
Быстрый старт
Запуск тестов
# Все тесты
php vendor/bin/phpunit
# Только unit тесты
php vendor/bin/phpunit --testsuite Unit
# Только feature тесты
php vendor/bin/phpunit --testsuite Feature
# Через composer
composer test
composer test:unit
composer test:feature
Пример теста
<?php
namespace Tests\Unit;
use Tests\TestCase;
use PHPUnit\Framework\Attributes\Test;
class TokenManagerTest extends TestCase
{
#[Test]
public function testCreateAccessToken(): void
{
$manager = \IO\Auth\TokenManager::init([
'secret_key' => 'test_secret_key',
'access_ttl' => 3600,
]);
$token = $manager->createAccessToken('user_123', ['read', 'write']);
$this->assertIsString($token);
$this->assertNotEmpty($token);
}
#[Test]
public function testValidateAccessToken(): void
{
$manager = \IO\Auth\TokenManager::init([
'secret_key' => 'test_secret_key',
]);
$token = $manager->createAccessToken('user_123', ['read']);
$payload = $manager->validateAccessToken($token);
$this->assertIsArray($payload);
$this->assertEquals('user_123', $payload['sub']);
}
}
Базовый класс TestCase
Tests\TestCase наследует PHPUnit\Framework\TestCase и предоставляет:
abstract class TestCase extends BaseTestCase
{
protected function setUp(): void
{
parent::setUp();
}
protected function tearDown(): void
{
parent::tearDown();
}
}
Полезные методы PHPUnit
// Assertions
$this->assertEquals($expected, $actual);
$this->assertNotEquals($expected, $actual);
$this->assertTrue($condition);
$this->assertFalse($condition);
$this->assertNull($value);
$this->assertNotNull($value);
$this->assertIsString($value);
$this->assertIsArray($value);
$this->assertIsInt($value);
$this->assertIsBool($value);
$this->assertEmpty($value);
$this->assertNotEmpty($value);
$this->assertInstanceOf(Class::class, $object);
$this->assertArrayHasKey('key', $array);
$this->assertCount(3, $array);
$this->assertStringContainsString('needle', $haystack);
// Expecting exceptions (PHPUnit 11 — PHP 8 Attributes)
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid');
// Mocking
$mock = $this->createMock(SomeClass::class);
$mock->method('someMethod')->willReturn('value');
PHPUnit 11: Атрибуты вместо аннотаций
PHPUnit 11 использует PHP 8 атрибуты (#[Test], #[DataProvider('...')], #[Depends('...')]) вместо PHPDoc аннотаций (@test, @dataProvider, @depends):
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Depends;
use PHPUnit\Framework\Attributes\CoversClass;
#[CoversClass(\IO\Auth\TokenManager::class)]
class TokenManagerTest extends TestCase
{
#[Test]
public function testCreateToken(): void { /* ... */ }
#[Test]
#[DataProvider('tokenProvider')]
public function testValidateToken(string $token): void { /* ... */ }
public static function tokenProvider(): array
{
return [
['valid-token'],
['another-token'],
];
}
#[Test]
#[Depends('testCreateToken')]
public function testUseToken(): void { /* ... */ }
}