Symfony Best Practice 訳してみた - Chapter11 -
Symfony Best Practiceの翻訳をしてます。 9日目−3です。これでBestPracticeは最終章です。
前回の記事
※多分に意訳が入っておりますので、誤訳がある場合はご指摘ください。
※読み進めていくSymfony Best Practiceは 2016/10/23時点の情報です。
※写経をする場合は、事前にPHPの実行ができる環境をご用意ください。
3行まとめ
ファンクショナルテストを飛ばすことなかれ。
簡単でもいいからファンクショナルテストを書こう。必ず将来役に立つ。
ファンクショナルテストではURLをハードコーディングしよう。
第11章 テスト
大雑把に言えば、テストには2種類あります。ユニットテストでは、ある機能の入出力をテストできます。ファンクショナルテストでは「ブラウザ」から操作(リンクのクリックやフォームへの入力とそのチェック)した結果を判定することができます。
ユニットテスト
ユニットテストは、Symfonyからは独立して存在するべき、「ビジネスロジック」をテストするものです。このため、Symfonyはユニットテストのためにどういったツールを使うかといった制約を持っていません。最もポピュラーなものは、PhpUnit*1とPhpSpec*2です。
ファンクショナルテスト
良いファンクショナルテストを書くのは大変なので、テストをしていない開発者もいます。ファンクショナルテストを飛ばしてはいけません!簡単なファンクショナルテストを書くことで、デプロイする前に致命的なエラーを発見できるのです。
- 最低でも作ったページがきちんとロードされるかを確認するファンクショナルテストを書きましょう。
ファンクショナルテストはこんなに簡単です。
// tests/AppBundle/ApplicationAvailabilityFunctionalTest.php namespace Tests\AppBundle; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; class ApplicationAvailabilityFunctionalTest extends WebTestCase { /** * @dataProvider urlProvider */ public function testPageIsSuccessful($url) { $client = self::createClient(); $client->request('GET', $url); $this->assertTrue($client->getResponse()->isSuccessful()); } public function urlProvider() { return array( array('/'), array('/posts'), array('/post/fixture-post-1'), array('/blog/category/fixture-category'), array('/archives'), // ... ); } }
このテストでは、HTTPレスポンスが200または299であることを確かめることで、URLのロードが成功したか判定しています。ここだけ見ると意味のあることには思えないかもしれませんが、テストを書くのにかかる労力に比べれば、アプリケーションにファンクショナルテストがあることには価値があります。 コンピューターソフトウェアにおいて、こうしたテストはスモークテスト*3と呼ばれ、将来のリリースに備えて、単純なミスを発見する予備的なテストで構成されます。
ファンクショナルテストにURLをハードコーディングする
先ほどのファンクショナルテストでURLジェネレーターを使わないことに疑問を持った方がいるでしょう。
- ファンクショナルテストで使うURLはURLジェネレーターを使うのではなく、ハードコーディングすべし。
テストするページのURL生成にrouterサービスを使った以下の例で考えてみましょう。
public function testBlogArchives() { $client = self::createClient(); $url = $client->getContainer()->get('router')->generate('blog_archives'); $client->request('GET', $url); // ... }
これは動きますが、1つだけとんでもない欠点があります。開発者が誤って、blog_archivesのルーティングを変えてしまったとしましょう。テストは通りますが、もともと(修正前の)のURLでは動かなくなってしまいます!そのURLに付けられたブックマークは機能しなくなり、検索エンジンのランキングも落ちてしまいます。
JavaScriptのファンクショナルテスト
標準搭載のテストクライアントは素晴らしいですが、JavaScriptの挙動をテストすることはできません。もしテストする必要があるなら、PHPUnitに搭載されているMink*4というライブラリを利用してみてはいかがでしょう。 もちろん、巨大なJavaScriptによるフロントエンドをお持ちなら、JavaScriptベースのテストツールを使った方が良いでしょう。
ファンクショナルテストについてさらに詳しく
HautelookAliceBundle*5はFaker*6とAlice*7を使って、データを作り実運用に近い状態でテストすると良いでしょう。
感想
「意味のある」ファンクショナルテストは絶対に書こう。 ルーティングと「検索エンジンのランキング」の関係は確かに盲点だった。