Movatterモバイル変換


[0]ホーム

URL:


LoginSignup
35

Go to list of users who liked

23

Share on X(Twitter)

Share on Facebook

Add to Hatena Bookmark

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Laravel】PHPUnitの実行でDBを汚染しないためにできる簡単なこと

Last updated atPosted at 2022-02-25

環境

OS: Windows 10
PHP: 8.1.2
Laravel Framework: 8.81.0
docker-compose: 1.29.2
PHPUnit: 9.5.10
MySQL: 8.0

Laravel Sailを使用して、Laravelプロジェクトを立ち上げています。
プロジェクトを立ち上げる部分は、こちらのドキュメントでご確認ください。

RefreshDatabase DBの状態に影響されずテストする

use RefreshDatabase;をしてあげると、

各テスト毎にDBをリフレッシュするため、まっさらな状態にしてくれるので、
DBの状態を確認するアサーションである

  • $this->assertDatabaseCount(...);
  • $this->assertDatabaseHas(...);
  • $this->assertDatabaseMissing(...);

あたりが扱いやすくなります。

そして、テストによって追加されてしまうデータも残らないので安心です。
では、実際に動作を見るためにテストを作成しましょう。

テストの作成

まずは、テストの作成のために以下のコマンドを叩きます。

UserTestの追加
$./vendor/bin/sail artisan make:test Model/UserTest

そして、作成されたファイルを以下のように修正します。

tests/Feature/Model/UserTest.php
<?phpnamespaceTests\Feature\Model;useApp\Models\User;useIlluminate\Foundation\Testing\RefreshDatabase;useTests\TestCase;classUserTestextendsTestCase{useRefreshDatabase;constTABLE_NAME='users';protectedfunctionsetUp():void{parent::setUp();}/**     * @return int     * @throws \Exception     */privatefunctionfactory():int{// 1~9のランダムな数値を取得$count=random_int(min:1,max:9);// $countの数だけ、新規にUserを作成するUser::factory($count)->create();return$count;}/**     * @test     * @group Model     * @group User     *     * @return void     * @throws \Exception     */publicfunction全件取得():void{$count=$this->factory();// usersテーブルに$countの数だけデータが挿入されているか$this->assertDatabaseCount(table:self::TABLE_NAME,count:$count);$result=User::all();// 全件取得できているか$this->assertCount(expectedCount:$count,haystack:$result);}}

さて、テストが作成できましたので、
これを動作させてみましょう。

テストの実行

テストの実行のためには、以下のコマンドを叩きます。

テストの実行
$./vendor/bin/sailtest--group=Model

今回のテストには$this->assertDatabaseCount(...);が含まれています。
もし、です。

試しに3回ほど実行してみましょう!

実行結果
$./vendor/bin/sailtest--group=Model   PASS  Tests\Feature\Model\UserTest  ✓ 全件取得  Tests:  1 passed  Time:   0.33s$./vendor/bin/sailtest--group=Model   PASS  Tests\Feature\Model\UserTest  ✓ 全件取得  Tests:  1 passed  Time:   0.30s$./vendor/bin/sailtest--group=Model   PASS  Tests\Feature\Model\UserTest  ✓ 全件取得  Tests:  1 passed  Time:   0.29s

問題なくPASSしていますね!

これでテストができることが分かります。

テスト後のDBの状態を確認

次にテストによって追加されてしまうデータが残っていないことを確認します。

確認方法は何でも良いのですが、今回はできる限り簡潔に画面に表示します。
以下の実装を行いましょう。

routes/web.php
<?phpuseIlluminate\Support\Facades\Route;/*|--------------------------------------------------------------------------| Web Routes|--------------------------------------------------------------------------|| Here is where you can register web routes for your application. These| routes are loaded by the RouteServiceProvider within a group which| contains the "web" middleware group. Now create something great!|*/Route::get('/',function(){$users=\App\Models\User::all();dd($users);});

あとは、http://localhost/に接続すれば・・・

image.png

出ました!!

#items: []ということは、何のデータも入っていないことなので、
これでことが分かりました。

本当に影響がないか確認

テストがデータに影響しないこともデータが残ってないことも分かりました。

では、

それを確認するためにダミーデータを入れてからテストを実行してみましょう。

ダミーデータの作成

まずは、ダミーデータを作成するためにシーダーを作成する必要がありますので、
シーダーを作成するために以下のコマンドを叩きます。

シーダーの作成
$./vendor/bin/sail artisan make:seeder UserSeeder

シーダーの作成ができたら、ダミーデータを作成するために実装しましょう。
以下の修正を加えればOKです。

database/seeders/UserSeeder.php
<?phpnamespaceDatabase\Seeders;useApp\Models\User;useIlluminate\Database\Seeder;classUserSeederextendsSeeder{/**     * Run the database seeds.     *     * @return void     */publicfunctionrun(){User::factory(10)->create();}}
database/seeders/DatabaseSeeder.php
<?phpnamespaceDatabase\Seeders;useIlluminate\Database\Seeder;classDatabaseSeederextendsSeeder{/**     * Seed the application's database.     *     * @return void     */publicfunctionrun(){$this->call([UserSeeder::class,]);}}

これでダミーデータを作成する準備が整ったので、以下のコマンドを叩きましょう。

ダミーデータの作成
$./vendor/bin/sail artisan db:seed

作成しているかどうか、http://localhost/に接続して確認してみます。

image.png

#items: array:10 [▶]となっているので作成できていますね。

結果は・・・

では、テストを実行してから確認してみましょう。

テストの実行
$./vendor/bin/sailtest--group=Model

そして、http://localhost/に接続・・・

image.png

き、消えてる・・・。

ということで、汚染しない代わりにのです。

解決方法

テスト実行の度にダミーデータを挿入するのも手間がかかりますし、
手動で追加したデータなどは消えてしまいます。
これでは、根本的な解決になりません。

根本的な解決方法を考えるなら
すればよいのです。

sqliteを使用する

設定は何もこだわらなければ、とても簡単です。

以下のように、コメントアウトを外すだけです。

phpunit.xml
<?xml version="1.0" encoding="UTF-8"?><phpunitxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"bootstrap="vendor/autoload.php"colors="true"><testsuites><testsuitename="Unit"><directorysuffix="Test.php">./tests/Unit</directory></testsuite><testsuitename="Feature"><directorysuffix="Test.php">./tests/Feature</directory></testsuite></testsuites><coverageprocessUncoveredFiles="true"><include><directorysuffix=".php">./app</directory></include></coverage><php><servername="APP_ENV"value="testing"/><servername="BCRYPT_ROUNDS"value="4"/><servername="CACHE_DRIVER"value="array"/><servername="DB_CONNECTION"value="sqlite"/><servername="DB_DATABASE"value=":memory:"/><servername="MAIL_MAILER"value="array"/><servername="QUEUE_CONNECTION"value="sync"/><servername="SESSION_DRIVER"value="array"/><servername="TELESCOPE_ENABLED"value="false"/></php></phpunit>

これで設定完了です。

テスト実行(sqlite)

先程と同じようにダミーデータの作成し、テストを実行してみます。

ダミーデータの作成
$./vendor/bin/sail artisan db:seed
テストの実行
$./vendor/bin/sailtest--group=Model

そして、http://localhost/に接続・・・

image.png

やりました!
ダミーデータが残ったままです!

テストで違うDB環境を使用する

簡単な設定でしたが、残念ながら

そんなときは、大人しく別のDBを用意する方法が良いでしょう。

.env.testing

まず、.env.testingを作成します。
一番楽なのは、.envを複製してリネームすることです。

重要なのは、
APP_KEYにキーがあることDB_HOST.envと異なることです。

今回は、DB_HOSTmysql.testとします。

.env.testing
...APP_KEY=(キーが入っている)...DB_CONNECTION=mysqlDB_HOST=mysql.testDB_PORT=(.envと一緒)DB_DATABASE=(.envと一緒)DB_USERNAME=(.envと一緒)DB_PASSWORD=(.envと一緒)...
APP_KEYにキーが入っていない

その場合は、以下のコマンドで生成しましょう。

キーの生成
$./vendor/bin/sail artisan key:generate--env=testing

docker-compose.yml

先程、.env.testingで追加したDB_HOSTを追加します。
今回はmysql.testですね。

docker-compose.yml
mysql.test:image:'mysql/mysql-server:8.0'environment:MYSQL_ROOT_PASSWORD:'${DB_PASSWORD}'MYSQL_ROOT_HOST:"%"MYSQL_DATABASE:'${DB_DATABASE}'MYSQL_USER:'${DB_USERNAME}'MYSQL_PASSWORD:'${DB_PASSWORD}'MYSQL_ALLOW_EMPTY_PASSWORD:1networks:-sail

テスト用に使用するだけなので、

追加した後は、sailを再度立ち上げましょう!

sailの立ち上げ
$./vendor/bin/sail up-d

テスト実行(別DB)

テストを実行してみます。

ダミーデータの作成
$./vendor/bin/sail artisan db:seed
テストの実行
$./vendor/bin/sailtest--group=Model

そして、http://localhost/に接続・・・

image.png

こちらでも問題なく残っていますね!

まとめ

ということで、上記の手順によりDBの汚染を防ぐことができます。

テストを記述するのはとても大切だと思っているので、
備忘録ではありますが、この記事があなたの役に立てば嬉しいです。

35

Go to list of users who liked

23
1

Go to list of comments

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35

Go to list of users who liked

23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?


[8]ページ先頭

©2009-2025 Movatter.jp