[記事]
CircleCIのconfig.ymlの書き方
生成コマンド
$ php artisan make:test --unit Models/UserProfileTest
実行コマンド
$ ./vendor/bin/phpunit --testdox --testsuite=Unit $ ./vendor/bin/phpunit --testdox --testsuite=Feature
Tests\TestCase クラスを継承することで
Laravel の内部の機能にアクセスできるようになる。
Tests\TestCase を継承しているのは
Feature のほうだけで、
Unit にあるほうは
PHPUnit が提供している基底クラスを継承している。
これは、ユニットテストはフレームワークの機能に依存しない形で書くことが望ましい、 という考え方に基づいている。
これはあくまで原則であって、
フレームワークの機能(たとえば Facade など)を
利用したユニットテストを書きたい場合は、
継承元のクラスを Tests\TestCase に変更すること。
tests/Unit/ExampleTest.php
<?php namespace Tests\Unit; use PHPUnit\Framework\TestCase; class ExampleTest extends TestCase
tests/Feature/ExampleTest.php
<?php namespace Tests\Feature; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; class ExampleTest extends TestCase
Laravel によって追加されたアサーションメソッド
HTTPレスポンスのテスト (feature test)
[*] get()メソッド
Tests\TestCaseにはget()メソッドが含まれる。
働きは、アプリケーションに対して、GETリクエストを作成。
戻り値は、HTTPレスポンス。
getメソッドは
アプリケーションに対して、GETリクエストを作成します。
(1) assertStatus
$response = $this->get('/'); $response->assertStatus(200);
assertStatusメソッドは
返されたレスポンスが
指定したHTTPステータスコードを持っていることをアサートします。
このシンプルな例に加え、
レスポンスヘッダ、コンテンツ、JSON構造などを
検査するさまざまなアサートをLaravelは用意しています。
featureテストの概要 [Controller単位]
フィーチャーテストでは、
複数のクラスが連動するような処理の実行後の状態を確認する。
ウェブサービスでは、一般的に、
Controller を対象とし、
HTTP リクエストを入力値、
レスポンスを出力値として検査する。
Unitテストの概要 [Function単位]
ユニットテストでは、
単一あるいは少数の小さなクラスの集まりが提供する機能(関数)の動作を確認する。
原則的には、
フレームワークやアプリケーション以外の要素(データベースや外部 APIなど)に
依存しないようにテスト対象を組み立てるが、
そうした要素を切り離すことでかえって設計が複雑になるようであれば、
それらを含めた上でユニットテストを書くこともある。
データプロバイダ @dataProvider
PHPUnit ではデータプロバイダという仕組みを使って、
テストパターンを配列で定義し、
テストメソッドに順に渡してテストを行うことができる。
以下のように @dataProvider メソッド名 の形式で、
テストメソッドの DocComment 内に書く。
リフレクションクラスの使用法, invokeの第2引数
/** * @test * * invoke()メソッドの第1引数には、 * メソッドが属するクラスのインスタンスを指定します。 * 第2引数以降には引数を指定します。 * https://blog.asial.co.jp/751 * */ public function changeUSDIntoJPY() { $reflection = new \ReflectionClass($this->object); $method = $reflection->getMethod('changeUSDIntoJPY'); $method->setAccessible(true); $res = $method->invoke($this->object, '3,100'); $expectedValue = 3100 * 121; $this->assertSame($expectedValue, $res); }
RefreshDatabase
TestCaseクラスを継承したクラスでRefreshDatabaseトレイトを使用すると、
データベースをリセットします。
なお、トレイトは継承と似たPHPの機能で、
汎用性の高いメソッドなどをトレイトとしてまとめておき、
他の複数のクラスで共通して使う、といった使い方をします。
リセットするとはどういうことかというと、
データベースの全テーブルを削除(DROP)した上で、
マイグレーションを実施し全テーブルを作成します。
なお、RefreshDatabaseトレイトを使用すると、
上記に加えて、テスト中にデータベースに
実行したトランザクション(レコードの新規作成・更新・削除など)は、
テスト終了後に無かったことになります。
リレーションのテスト
- BelongsTo
- hasMany
- hasOne
/** * @test */ public function BelongsToUser() { /** * Relationのテストの仕方 * [参照] * https://medium.com/@tonyfrenzy/part-2-testing-model-relationships-in-laravel-basic-8b606dd36c02 */ $user = factory(User::class)->create(); $phone = factory(Tweet::class)->create(['user_id' => $user->id]); $this->assertInstanceOf(User::class, $phone->user); }