最近、テストコードを書きたいというお声をよく頂きます。
そこで今回はLaravelでテストコードの設定方法から書き方の例までご紹介します。
そもそもテストコードって何?
そもそもテストコードを知らない方もいらっしゃると思うので、簡単に説明しておくとテストコードとは「コードで実装した機能の動作テストをする」というものです。まぁそれだけだと分からないと思うので実際に見た方が早いです。
設定方法
テスト用DBの作成
それではLaravelでテストコードを実行するための準備をしていきましょう。
まず、テスト用のデータベースを用意してください。
ここではmysqlを利用していきます。
> create database test_laravel;
> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| laravel |
| mysql |
| performance_schema |
| sys |
| test_laravel |
+--------------------+
6 rows in set (0.02 sec)
.env.testingの設定
次にテスト用のenv設定をしていきます。
.env.exampleからコピーして、.env.testingを作成してください。
そこに、APP_KEYなど適切に情報を設定してください(.envから貼り付けてもOK)。
また、DB情報は先ほど作成したDBと接続されるようにしましょう。
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=test_laravel
DB_USERNAME=root
DB_PASSWORD=password
記述し終わったら、php artisan config:clear && php artisan cache:clearを確実にしておきましょう(これをしておかないとホンちゃんで使っているDBのデータが消える可能性があります)。
設定はこれだけです。
テストコードの実行
はい、それでは実際にテストコードを実行してみましょう。
Laravelのテストコードのファイルtestsディレクトリに格納します。
その中にFeatureとUnitというディレクトリが存在します。
Featureはアクション単位のテスト、Unitはメソッド単位のテストコードを格納するのが一般的です(多分)。
それぞれのディレクトリにサンプルとなるExampleTestというファイルがあり、その中に1つずつテストが書いてあります。
ひとまずこのテストを実行してみましょう。
テストの実行はターミナルで下記のコマンドを実行してください。
$ php artisan test
or
$ ./vendor/bin/phpunit --testdox
./vendor/bin/phpunitに–testdoxというオプションを付けると実行状況とassertionsの数が分かるのでオススメです。
緑色が出たらテストが通ったという意味になります。
では、エラーになるとどうなるでしょうか。わざとエラーが出るようにして実行してみます。
エラーになると上図のように赤くなります。
テストではよく「緑になる」か「赤くなる」かという表現を使います(多分)。
テストコードを書いてみよう
では、実際にテストコードを書いてみましょう。
ここでは最もよく書かれる「アクセステスト」と呼ばれるものを書いてみましょう。
アクセステストとは、URLにアクセスしてステータス200が返るかどうかのテストのことです。
ではまずテストファイルを作成しましょう。
$ php artisan make:test WelcomeTest
上記を実行すると、Featureディレクトリにファイルが作成されます。
もしもUnitに作成したい場合は-uオプションをつけてください。
作成したファイルを開いてみましょう。
・・・はい、書いてみましょうと言いましたが、実はもう既に書かれていました。
/**
* A basic feature test example.
*
* @return void
*/
public function test_example()
{
$response = $this->get('/');
$response->assertStatus(200);
}
$this->get(‘/’)がURL「/」にアクセスするという意味で、$response->assertStatus(200);でステータスが200かどうかをチェックしています。
つまり、/にアクセスしたときにステータス200が返るかどうかのテストが上記になります。
上記だけではつまらないので、表示された画面上で「Documentation」という文言が含まれているかどうかもテストしてみます。
public function test_example()
{
$response = $this->get('/');
$response->assertStatus(200);
$response->assertSee('Documentation');//Laravelの初期画面
}
assertSeeというのが画面上の文字列をチェックするテストになります。
文字列はご自身の環境のものに変えて試してみてください。
[補足]ちなみにメソッドには命名規則があり、先頭にtestと付ける必要があります。
testとつけるとテストコードとして認識されます。
メソッド名にtestをつけたくない場合は、アノテーションをつけます。
/**
* @test
*/
public function should_新しいユーザーを作成して返却する()
{
}
POSTのテスト
続いて、POST処理のテストを書いていきます。
Laravel Breezeが入っているものとして、ユーザー登録処理を書いてみましょう。
コードは下記のようになります。
/**
* ユーザー登録のテスト
*/
public function testUserRegister()
{
$data = [
'name' => 'juno',
'email' => 'juno@email.com',
'password' => 'test1234',
'password_confirmation' => 'test1234',
];
$response = $this->postJson(route('register'), $data);
$response->assertStatus(302)
->assertRedirect('/dashboard');
}
postJson()で第一引数にURI、第二引数にPOSTするフォームデータを配列で渡します。
テストは302が返るかどうか、リダイレクト先は/dashboardをテストしています。
上記だけだとデータベースに登録されているかがテストできていないので、DB登録チェックも入れてみます。
/**
* ユーザー登録のテスト
*/
public function testUserRegister()
{
$data = [
'name' => 'juno',
'email' => 'juno@email.com',
'password' => 'test1234',
'password_confirmation' => 'test1234',
];
$response = $this->postJson(route('register'), $data);
$response->assertStatus(302)
->assertRedirect('/dashboard');
$this->assertDatabaseHas('users', [
'name' => 'juno',
'email' => 'juno@email.com',
]);
}
assertDatabaseHasでDBのデータの有無をチェックできます。
ちなみにDBは最初に作成したDBが使われます。
ログインが必要なテスト
最後にログインが必要なページのテストをしていきます。
ダッシュボードのアクセステストをしてみましょう。
その前に、RefreshDatabaseをuseしておきましょう。
class WelcomeTest extends TestCase
{
use RefreshDatabase;
RefreshDatabaseを記載すると、1つ1つのテストごとにDBのデータをリセットしてくれます。
では、話を戻してテストコードを書いていきます。
/**
* ダッシュボードのアクセステスト
*/
public function testDashboard()
{
$user = User::factory()->create();
$response = $this
->actingAs($user)
->get('/dashboard');
$response->assertOk();
}
上記ではまず、Userのfactoryでログインユーザーを作成しています。
その次にactingAs()の引数にその$userを渡すことで、そのユーザーでログインしているという状態にしてくれます。
まとめ
今回はテストの基本的なものを紹介しました。
もっと紹介したいことはあるのですが、長くなりそうなので今回はこのくらいにしておきます。
興味がある方は「phpunitの@dataProvider」や「setUp()関数」なども調べてみてください。
また、Laravelでフロントのテストをする場合はLaravel Duskと呼ばれるものもあります。