自動テストを早くで書けるようになってきたので、コツでも紹介しようかと思います。
今回はコマンドのテストは行わず、APIを想定しています。
自動テストを書くときのコツ
まずは、自動テストをするときのコツを紹介します。
サンプルのテストはこちら
/**
* URLを作成する関数
*
* @param array $data
* @return string
*/
private function createUrl(array $data): string
{
return '/api/sample/' . '?' . http_build_query($data);
}
public $seeders = [
'UserTableSeeder',
];
/**
* サンプルテスト
*
* @test
* @dataProvider sampleDataProvider
* @return void
*/
public function サンプルテスト(Closure $init, Closure $result)
{
$request = $init();
$response = $this->get('url/test'. '?' . http_build_query($request));
$result($this, $response, $request);
}
/**
* データプロバイダー
*
* @return array
*/
public function sampleDataProvider():array
{
return [
'サンプルで発生するエラー' => [
function() {
$user = factory(User::class)->create();
return [
'id' => $user->id
];
},
function($object, $response, $params) {
$object->assertDatabaseHas('user', [
'id' => $params['id']
]);
$response->assertJson([
'data' => [
'id' => $params['id']
]
]);
},
],
];
}
URLは関数で作成する
URLですが、各テストで書いても問題はなのですが、自分はいつもcreateURLのような関数で作成するようにしています。
こんな感じで共通関数作ってもいいかもしれないですね。
public static function createURL(string $path, array $data) {
$query = '';
if (count($data) > 0) {
$query = '?' . http_build_query($data);
}
return $path . $query;
}
Closureを使う
渡す引数ですが、単に配列を渡すよりもClosureを使って渡すことをお勧めします。
テストをするってことはテストごとに条件を揃えないといけないことが多々あります。
ClosureでDBにデータを操作するなど前提条件を揃えると柔軟にテストを作ることができます。
上記の例では、テスト前にデータをいじることもできますし、レスポンスも自由にテストできます。
配列ではなく、連想配列を渡す。
テストで失敗するとエラーが表示されますが、普通に配列を渡すとどこでエラーが起きたかすぐには見つけづらいです。
しかし、連想配列でキーにテストの説明をつけると、どのテストでエラーが起きたか見つけやすいです。
テストする分類
さて、本題です。
自動テストを作る上で、テストを分類すると以下になります。
- 権限テスト
- バリデーションテスト
- 機能テスト
それぞれ説明していきます。
権限テスト
権限テストでは、それぞれの権限が対象のリソースにアクセスしたとき、許可されていなかったら弾かれているか確認するテストです。
見るのはステータスだけで、問題ないなら200や204、権限がないなら401を確認します。
ログイン、トークン生成方法は色々あるので、使っている方法で作成してください。
/**
* サンプルテスト
*
* @test
* @dataProvider sampleDataProvider
* @return void
*/
public function サンプルテスト(Closure $init, int $status)
{
$request = $init();
Login($request);
$response = $this->get('url/sample'. '?' . http_build_query($request));
$response->assertStatus($status);
}
/**
* データプロバイダー
*
* @return array
*/
public function sampleDataProvider():array
{
return [
'管理者の場合' => [
function() {
$user = factory(User::class)->create([
'admin_flg' => 1
]);
return [
'id' => $user->id
];
},
200,
],
'一般ユーザの場合' => [
function() {
$user = factory(User::class)->create([
'admin_flg' => 0
]);
return [
'id' => $user->id
];
},
401,
],
'権限がない場合' => [
function() {
return [
'id' => ''
];
},
401,
],
];
}
バリデーションテスト
バリデーションテストでは、主にデータ型や境界値テスト、異常値を確認します。
データベースに存在しないはエラーとかもリクエストでバリデーションをかけれるので、その場合はここでやります。
基本的にassertJsonでエラーメッセージが存在するか見る感じですね。
サンプルコードは以下になります。
/**
* サンプルテスト
*
* @test
* @dataProvider sampleDataProvider
* @return void
*/
public function サンプルテスト(Closure $init, int $status)
{
$request = $init();
Login($request);
$response = $this->get('url/sample'. '?' . http_build_query($request));
$response->assertStatus($status);
}
/**
* データプロバイダー
*
* @return array
*/
public function sampleDataProvider():array
{
return [
'必須確認' => [
function() {
return [
'id' => ''
];
},
[
__('required', 'テスト')
],
],
];
}
機能テスト
機能テストでは条件によって変わるレスポンスのパターンを作ったり、登録されたり変更されるデータがDBで求める状態になっているかをテストします。
サンプルのテストのように、リクエストを送る前にパターンを求めて、
0件のコメント