PHPUnitの@dataProviderはforループの40倍遅い
PHPUnitにはテストデータを駆動してテストケースを実行するData Providerという機能があるが、それは一つのテストケースでfor
ループするより40倍遅い。
テストコード
検証のために次のようなテストコードを用意した。完全版はGitHubに置いてある。
UsingDataProviderTest.php
final class UsingDataProviderTest extends TestCase
{
/**
* @dataProvider trues
*/
public function test_true(bool $value): void
{
self::assertTrue($value);
}
public function trues(): iterable
{
for ($count = 1; $count <= 1000; $count++) {
yield [true];
}
}
}
UsingLoopTest.php
final class UsingLoopTest extends TestCase
{
public function test_true(): void
{
foreach ($this->trues() as $value) {
self::assertTrue($value);
}
}
public function trues(): iterable
{
for ($count = 1; $count <= 1000; $count++) {
yield true;
}
}
}
実行結果
- UsingDataProviderTest: 474ms
- UsingLoopTest: 12ms
40倍くらい速さが違う
なぜdataProviderは遅いか?
dataProviderの遅さの原因仮説としてはこう考えられる。dataProviderはデータごとに1テストのサイクルを回す。そのサイクルの中には、テストオブジェクトの生成やsetUp
、tearDown
、レポーティングなどさまざまな処理がある。ひとつのメソッドの中でfor
ループするテストは、そういうオーバヘッドがないぶん早くなる。
forとdataProviderは置き換え可能というわけではない
dataProviderはデータごとに独立したテストになるので、ひとつ前のデータがFAILになっても次のデータのテストは実行される。一方、forでループした場合は、FAILになったデータでテストが止まる。こういう違いがあるので、両者は置き換え可能というわけでない点は注意する。
結論
- 遅いと言っても、前後のデータにテスト実行計画が依存しないdataProviderのほうが普通はいい。
- ただ、沢山のパターン(数万パターン等)を網羅してテストしたい場合は、dataProviderだと体感的につらくなるので、そういう場合はforを使ってもいいかもしれない。
Author And Source
この問題について(PHPUnitの@dataProviderはforループの40倍遅い), 我々は、より多くの情報をここで見つけました https://qiita.com/suin/items/1f8a0f8a9d58e902953f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .