Laravelでテストを書く方法について、記載しています。
前に作ったLaravelの掲示板にテストを入れてみました。
下記はLaravel5で確認しています。
ユニットテストを作成する
ユニットテストを作成するときは下記のコマンドを使用します。
CreateMakeBoardCaseTestがテストのクラス名になります。 –unitをつけることでユニットテストのファイルができます。
php artisan make:test CreateMakeBoardCaseTest --unit
できたファイルを確認する
tests/Unit/にファイルが作成されるので、開いてみます。
TestCaseクラスを継承した、指定した名前のクラスが作成されてテストケースがひとつだけ用意されています。
class CreateMakeBoardCaseTest extends TestCase
{
/**
* A basic unit test example.
*
* @return void
*/
public function testExample()
{
$this->assertTrue(true);
}
}
ファイルを修正する
下記のようにファイルを修正してみました。
class CreateMakeBoardCaseTest extends TestCase
{
public function testRegister()
{
Board::truncate();
$createMakeBoardCase = new CreateMakeBoardCase();
$createResult = $createMakeBoardCase->__invoke('boardTitleTest', 'boardUserNameTest', 'boardAboutTextTest', 'boardPasswordTest');
$board = Board::where('title', 'boardTitleTest')->first();
$this->assertTrue($createResult);
$this->assertEquals('boardTitleTest', $board->title);
$this->assertEquals('boardUserNameTest', $board->user_name);
$this->assertEquals('boardAboutTextTest', $board->about_text);
$this->assertEquals('boardPasswordTest', $board->password);
}
}
元々のtestExampleは削除して、testRegister(登録のテスト)メソッドを作りました。
メソッド名については「test」で始まるメソッド名でないと、テストできないようです。
内容はBoard::truncateで掲示板テーブルを空にして、
usecaseをnewして新しくテーブルにインサートしています。
インサートされた値を取り出して、取り出した値がインサート時のパラメータと同じかテストしています。
テスト用のデータベースを使うようにする
そのままテストを走らせると、アプリで使っているデータベースが更新されるので
画面から登録した値と、テストで消したり入れたりする値が混在してしまいます…
なので、別のデータベースを用意してテストするように設定します。
下記の3つの方法を試してみました。
sqliteのdatabaseを別に作ってテスト用に設定する
別のsqliteファイル(database)を作成して、テストをします。
phpunitを修正する
phpunit.xmlを下記のように修正します。
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="MAIL_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value="./database/testing.sqlite"/>
</php>
DB_CONNECTIONはsqliteにして、DB_DATABASEにファイルまでの相対パスで設定しました。
.env.testingファイルを作成する
テストする前にmigrationをしないといけないので、
test用のデータベースの設定などを書いた.env.testingファイルを作成してmigrateを実行します。
ファイルの内容は、下記以外は使っていた.envと同じようにします。
DB_CONNECTION=sqlite
DB_DATABASE=./database/testing.sqlite
テスト用のデータベースにmigrationする
設定後、envファイルを指定して、migrateを流すとテスト実行環境出来上がりです。
テストした結果はマイグレーションしたデータベースに残ります。
php artisan migrate --env=testing
sqliteのインメモリ機能を使ってテスト用に設定する
sqliteのインメモリ機能を使って、データベースを作成せずにテストをしたい場合は、それぞれのファイルを編集しテストケースも工夫する必要があります。
phpunit.xmlを編集する
phpunit.xmlを下記のように編集します。
DB_CONNECTIONのvalueの箇所をconfigに新しく追加する設定に変えます。
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="MAIL_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="DB_CONNECTION" value="sqlite_testing"/>
</php>
config/database.phpを編集する
config/database.phpのファイルを開きます。データベースの接続設定が定義されているので下記のように修正します。
sqlite_testingの項目を増やして、
driverがsqlite, databaseが:memory:, prefixなしで設定します。
'connections' => [
'sqlite_testing' => [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
],
テストケースを編集する
インメモリでテストする場合の注意点は、メモリ上にデータベースが用意されているわけではないので
テスト毎に毎回データベースをメモリ上に用意する必要があるようです。データベースが用意されている前提で動かすとエラーになります。
下記のようにuse DatabaseMigrationsトレイトを入れるようにします。
そうすると、migrate:freshが毎回呼ばれて、データベースクリアされます。
テーブルはデータベースに残りません。
class CreateMakeBoardCaseTest extends TestCase
{
use DatabaseMigrations;
public function testRegister()
{
Board::truncate();
$createMakeBoardCase = new CreateMakeBoardCase();
$createResult = $createMakeBoardCase->__invoke('boardTitleTest', 'boardUserNameTest', 'boardAboutTextTest', 'boardPasswordTest');
$board = Board::where('title', 'boardTitleTest')->first();
$this->assertTrue($createResult);
$this->assertEquals('boardTitleTest', $board->title);
$this->assertEquals('boardUserNameTest', $board->user_name);
$this->assertEquals('boardAboutTextTest', $board->about_text);
$this->assertEquals('boardPasswordTest', $board->password);
}
}
mysqlのdatabaseを別に作ってテスト用に設定する
phpunit.xmlを修正する
DB_CONNECTIONの箇所をmysqlにします。
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="MAIL_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="DB_CONNECTION" value="mysql"/>
</php
.env.testingを作成する
.envをコピーして、.env.testingを作成します。 APP_ENVの設定値がtestingになっているので、.env.testingというファイル名になります。
テスト用データベースに接続するための情報を設定します。
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=sample_db
DB_USERNAME=root
DB_PASSWORD=password
テスト用のデータベースにmigrationする
設定後、envファイルを指定して、migrateを流すとテスト実行環境出来上がりです。
テストした結果はマイグレーションしたデータベースに残ります。
php artisan migrate --env=testing
作ったテストを実行する
全体のテストをする
下記のようにcomposerでインストールされた、phpunitを呼ぶとテストができます。
./vendor/bin/phpunit
ファイル単位でテストする
ファイルを指定するとファイル単位でのテストができます。
./vendor/bin/phpunit tests/Unit/CreateMakeBoardCaseTest.php
結果は下記のような感じで出力されます。
$ ./vendor/bin/phpunit
PHPUnit 7.5.9 by Sebastian Bergmann and contributors.
.. 2 / 2 (100%)
Time: 374 ms, Memory: 18.00 MB
OK (2 tests, 6 assertions)
コメント