僕はSymfony+Doctrineプロジェクトで機能テストを作る際、 LiipFunctionalTestBundle を使ってテスト環境だけSQLiteで動作するようにしているのですが、ある時から途中でDBがロックしてしまい、テストスイートがパスしなくなってしまいました。
SQLSTATE[HY000]: General error: 5 database table is locked
原因を探っていくうちに、以下のテストケースに問題がある事が分かりました。
$query = $entityRepository->createHogeQuery(); // Doctrine\ORM\Query $iterator = $query->iterate(); $iterator->rewind(); $this->assertSame($expectedEntity, $iterator->current()[0]);
実際にアプリケーションでも大量の結果セットを返す可能性のある::createHogeQuery()はiterate()して使っていたのでテストも同様にしたのですが、横着したのがいけなかったようです。
どう言う事かと言うと、iterate()を使う場合は最後の行までフェッチしないと、内部のPDOStatementがcloseCursor()されないようで、その結果次回以降のテストに影響が出ていたと言うわけです。
テストに以下を追加する事でとりあえず解決しました。
while ($iterator->next()); // cleanup
あるいは、テストデータの量はたかがしてれているのでそもそもテストではiterate()を使わなければ良いのかもしれません。
ところでこれ、普通にforeachしたとしてもbreakされたら同様の事が起きそうですよね。誰か試してみて下さい。