テスト
ユニットテストとフィーチャテスト
Laravelでは2つのテストがサポートされている。
- ユニットテスト:メソッドを検証する。
- フィーチャテスト(WebAPIテスト):API機能を検証する。
ユニットテスト
ユニットテストでは、テストクラスはTests\TestCaseを継承して実装する。
Tests\TestCaseはPHPUnitのPHPUnit\Framework\TestCaseを継承していて、PHPUnitの機能に加えてLaravel独自の機能が追加されている。
※ Laravel6からはTests\TestCaseではなく、直接PHPUnit\Framework\TestCaseを継承するようになった。
ユニットテストの手順
1. php artisan make:test HogeClientServiceTest --unit
tests/Unitにクラスが生成される。
2. testXxxメソッドまたは@testアノテーションを付けたメソッドを実装する。
public function testRun()
{
$service = app(HogeClientService::class);
$result = strpos($service->run('https://google.com/'), '<html') !== false;
$this->assertTrue($result);
}
3. ./vendor/bin/phpunit tests/Unit/HogeClientServiceTest.phpでテスト実行。
※ 引数なしで./vendor/bin/phpunitとすると全てのテストが実行される。
データプロバイダ
テストコードに渡すパラメータをまとめて定義することができる。
2次元配列を返すメソッドを定義し、テストメソッドに@dataProviderアノテーションで指定する。
/**
* @dataProvider dataProviderForHogeClientService
*/
public function testRun($url, $expected)
{
$service = app(HogeClientService::class);
$result = strpos($service->run($url), $expected) !== false;
$this->assertTrue($result);
}
public function dataProviderForHogeClientService(): array
{
return [
'Googleテスト' => ['https://google.com/', '<html'],
'Yahooテスト' => ['https://yahoo.co.jp/', '<html'],
];
}
例外のテスト
3つの方法がある。
- try/catchを使い例外をcatchして、assertInstanceOfメソッドで判定する。
- expectExceptionメソッドで期待する例外を指定してから対象コードを実行する。
- @expectedExceptionアノテーションで期待する例外を指定する。
1, 2はテストメソッド内にコードを追加する必要があるため、著者は3をオススメしている。
@expectedExceptionアノテーションを使うと、テストメソッド内は対象コードの実行のみになるので可読性が上がるため。
/**
* @expectedException HogeException
* @expectedExceptionMessage urlが不正
*/
public function testRun($url, $expected)
{
$service = app(HogeClientService::class);
$result = strpos($service->run($url), $expected) !== false;
$this->assertTrue($result);
}
前処理と後処理
setUpメソッドに前処理、tearDownメソッドに後処理を記述する。
テストメソッドごとではなく、テストクラスごとの前処理はsetUpBeforeClassメソッド、後処理はtearDownAfterClassメソッドに記述する。
テストクラスがTests\TestCaseを継承している場合は、parent::setUp();
など親クラスのメソッドもコールしなければならない。
PHPUnit\Framework\TestCaseを直接継承している場合は不要。
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
echo __METHOD__, PHP_EOL;
}
protected function setUp()
{
parent::setUp();
echo __METHOD__, PHP_EOL;
}
/**
* @test
*/
public function テストメソッド1()
{
echo __METHOD__, PHP_EOL;
$this->assertTrue(true);
}
データベーステスト
- テスト用データベースを生成
mysqladmin create app_test - phpunit.xmlに
<env name="DB_DATABASE" value="app_test">
を追記。
※ phpunit.xmlはアプリケーションディレクトリ直下に用意されている。 - テストクラスに
use RefreshDatabase
を追記。
テスト実行時にマイグレーションも実行される。 - テストメソッドやsetUpメソッドで、対象コードの実行前にFactoryを使ってデータを登録し、対象コードの実行後にassertDatabaseHasメソッドやassertDatabaseMissingメソッドで判定する。
factory(User::class)->create([
'id' => 1,
'name' => 'hoge',
]);
// 対象コードをここで実行
$this->assertDatabaseHas('users', [
'id' => 2,
'name' => 'hogehoge',
]);
フィーチャテスト
- php artisan make:test HogeTest
tests/Featureにクラスが生成される。 - 継承したメソッドを使ってリクエストを送信する。
get, post, getJson, postJson, putなど。$response = $this->get('https://www.sony.co.jp/');
※ 戻り値はTestResponse型 - TestResponseのアサーションメソッドを使って判定する。
assertStatus, assertSuccessful, assertRedirect, assertHeader, assertHeaderMissing, assertJsonなど。$response->assertSuccessful();
$response->assertSee('<html');
ログ
ログ出力メソッド
以下の3つからログ出力メソッドをコールすることができる。
- \Logファサード
- サービスコンテナで’log’を解決する
- loggerヘルパ関数
通常は\Logファサードを使う。\Log::debug('test');
第2引数に配列で情報を渡すことができる。 \Log::info('hoge', ['id' => 33]);
ログ出力設定
Laravel5.5まではconfig/app.phpだったが、5.6からはconfig/logging.phpに変わった。
デフォルトでは以下の設定なのでstorage/log/laravel.logに出力される。
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
// 以下省略
'channels' => ['daily'],
とすると、日毎にファイルを分けてログを出力してくれる。
テスト駆動開発
テスト駆動開発の手順
- テストを作成する。
- テストが失敗することを確認する。
- 最低限の実装を行い、テストが成功することを確認する。
- テストが失敗しないことを確認しながらリファクタリングする。
実装例
「api/hogeへGETでアクセスできるAPI」の場合。
1. テストクラスの作成。
php artisan make:test ApiHogeTest
2. テストメソッドの実装。
public function testHoge()
{
$response = $this->get('/api/hoge');
$response->assertStatus(200);
}
3. テストの実行。
./vendor/bin/phpunit tests/Feature/ApiHogeTest.php
テストが失敗することを確認する。
4. 実装の追加。
4-1. route/api.phpにルートを追加。
Route::get('/hoge', 'Api\HogeController@index');
4-2. コントローラの作成。
php artisan make:controller Api/HogeController
4-3. indexメソッドの実装。
public function index()
{
echo 'OK';
}
5. テストの実行。
./vendor/bin/phpunit tests/Feature/ApiHogeTest.php
テストが成功することを確認する。