テストの導入 | Symfony7
対象: Symfony 7.4
参考
インストール
composer require --dev symfony/test-pack
symfony/test-pack は、phpunit/phpunit、symfony/browser-kit、symfony/css-selector をまとめて require-dev に追加するパックです。
インストールされる PHPUnit のバージョンは、パックの制約と PHP のバージョンによって決まります。実際の値は composer.json / composer.lock で確認してください。
[!NOTE]
composer.jsonの次の記述は、symfony/test-packの導入時ではなく、symfony new(またはcomposer create-project symfony/skeleton)の実行時に設定されます。"autoload-dev": { "psr-4": { "App\\Tests\\": "tests/" } }
テストの実行
vendor/bin/phpunit
設定は phpunit.dist.xml(版・レシピによっては phpunit.xml.dist)にあり、テスト実行時は APP_ENV=test が使われます。
テストの種類と親クラス
[!IMPORTANT] 親クラスはおもに以下のクラスを使用します。
- 単体テスト PHPUnit 提供クラス
PHPUnit\Framework\TestCase
class SampleTest extends \PHPUnit\Framework\TestCase { }- 結合テスト Symfony 提供クラス
Symfony\Bundle\FrameworkBundle\Test\KernelTestCase
class SampleTest extends \Symfony\Bundle\FrameworkBundle\Test\KernelTestCase { }- アプリケーションテスト(HTTP)
Symfony\Bundle\FrameworkBundle\Test\WebTestCase
以下の「サービスのテスト」は、カーネルとサービスコンテナを起動するため、単体テストではなく結合テストです。
サービスのテスト
<?php
namespace App\Service;
class Sample
{
public function echo(string $message): string
{
return $message;
}
}
<?php
namespace App\Tests\Service;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use App\Service\Sample;
// KernelTestCase を継承
class SampleServiceTest extends KernelTestCase
{
public function testSomething(): void
{
// (1) boot the Symfony kernel
self::bootKernel();
// (2) use static::getContainer() to access the service container
$container = static::getContainer();
// (3) run some service & test the result
$sample = $container->get(Sample::class);
$this->assertEquals('Hello World!', $sample->echo('Hello World!'));
}
}
private サービスの取得
static::getContainer() は「テスト用コンテナ」を返します。このコンテナから、public サービスと、削除されていない private サービスを取得できます。
サービスは既定で private です。private サービスは、他のサービスから使われていない場合、コンテナのコンパイル時に削除されます。上記の App\Service\Sample は、どこからも使われていなければ削除されるため、$container->get(Sample::class) が失敗します。
この場合に限り、services_test.yaml でテストのときだけ public にします。
# config/services_test.yaml
services:
App\Service\Sample:
public: true # テストのときだけ public にする(未使用の private サービスの削除を防ぐ)
config/services.yaml 側に public: false を書く必要はありません(既定が private です)。
[!IMPORTANT]
services_test.yamlはテスト環境のときだけ読み込まれ、次のように動作します。
services.yamlに定義されたサービスはすべて適用されるservices_test.yamlに同じサービスがある場合は、それで上書きされるservices_test.yamlに新しいサービスを追加できる