Code Day's Night

ichikawayのブログ

Laravelのアプリのテストが3倍速くなった話

Larvelに限らずCakePHPや他のフレームワーク/言語でも関係ある話かもしれません。

結論から書くと、テストデータの投入時にUserテーブルのパスワードカラムがあるとパスワードの値をハッシュ化してデータが入る箇所があり、そのハッシュの処理によってテストが遅くなっていました。

テストに3分ほどかかるPHPUnitのテストがあったのですが、このハッシュの処理の負荷を減らすだけで1分でテストが完了するようになりました!

(テストデータはuserテーブルのレコードが16件でこれが208回テスト時に実行されてるので、3300レコードとなり3300回のハッシュ化する関数が呼ばれていました)


対策方法

Laravel6以降であれば

 <server name="BCRYPT_ROUNDS" value="4"> 

とphpunit.xmlに記載するだけです。

https://github.com/laravel/laravel/blob/13e5d272aec03a60f237bed51407514c41aec4ac/phpunit.xml#L22

Laravel6以降から始めた人は最初からこれが入っていると思いますが、Laravel5以前からの人は指定していないかもしれません。

このパラメータが使えない場合は、例えばDBのSeederで User::create()としてるような箇所を、次のようにInsert文に変えていけば良いかと思います。(パスワードハッシュが不要な場合のみ有効な手段)

DB::insert('insert into users (id, name) values (?, ?)', [1, 'foo']);

 

PHPUnitでテストを走らせると、普通は1コアしか使われずテストデータのリセットの度にハッシュ処理がCPUを利用していてテストの実行時間をかなり消費していました。

半年前にDBデータのリストアが遅そうだからと頑張って4分のテストを3分にしたりしましたが、まさかこんなところに巨大なボトルネックがあるとは、という感じです。