一週間前、
私はすでにCodeceptionとPHPアプリケーションのテストでの使用
について書いています。 最後の投稿の後、いくつかのバグが修正されました。 バグレポートをありがとう。 Codeceptionを試していない場合は、最後の記事を見て、受け入れテストのために試してみることをお勧めします。
今日は、CodeceptionがBDDスタイルの単体テストを実装する方法についてお話したいと思います。
ユニットをテストするためのユニットはまだ実験的です。 「不安定」という意味ではなく、「必要なすべてのニーズを満たすために拡張できる」という意味です。
ユニットのBDDテストについて説明する前に、当然のことながら、非常に論理的な質問に答えます。ヤギバヤンはどうでしょうか。 つまり、同じPHPUnitで既に正常に動作している場合、ユニットテストに何らかの迷いが必要なのはなぜですか。 なぜシナリオパラダイムでそれらを書き換えるのですか?
すべてのテストは読み取り可能でなければなりません。 特に、テストがメソッドの機能を本質的に説明する単体テスト。 しかし、彼は環境の準備、スタブとモカの作成でいっぱいです。 多くの異なる呼び出しが混在しており、時にはまったくコメントがありません。 そして、テストを破る新しい人にとって、テストされているものとその方法を理解することは困難です。
Codeceptionは、各ステップで実行されるアクションを説明するアプローチを提供します。
たとえば、次のように:
<?php class UserCest { function setNameAndSave(CodeGuy $I) { $I->wantToTest('getter and setter of User model'); $I->execute(function () { $user = new Model\User; $user->setName('davert'); $user->save(); }); $I->seeInDatabase('users',array('name' => 'davert'); } } ?>
そして、なぜこれが必要なのですか? これにより、実行可能コードとチェックが分離されます。 ただし、コードブロック内でのアサーの使用を禁止する人はいません。
<?php $I->wantToTest('getter and setter of User model'); $I->execute(function () { $user = new Model\User; $user->setName('davert'); assertEquals('davert', $user->getName()); $user->save(); }); $I->seeInDatabase('users',array('name' => 'davert');
テストが難しくなればなるほど、読みやすさを維持するためにより多くが必要になります。
Codeceptionは、ビジネスロジッククラスをテストする必要がある場合に興味深いものになります。 通常、それらは孤立して存在しませんが、他のクラスに依存し、実行の結果はゲッターほど簡単にチェックできない場合があります。
架空のMVCフレームワークからこのような単純なコントローラーを取得してみましょう。
<?php class UserController extends AbtractController { public function show($id) { $user = $this->db->find('users',$id); if (!$user) return $this->render404('User not found'); $this->render('show.html.php', array('user' => $user)); return true; } } ?>
彼がしていることは、原則として明確です。 ユーザープロファイルページを表示します。 ただし、テストする前に、コントローラーをViewおよびModelから分離する必要があるため、テストは困難です。 Codeceptionでの方法を次に示します。
<?php class UserControllerCest { public $class = 'UserController'; public function show(CodeGuy $I) { $I->haveStub($controller = Stub::makeEmptyExcept($this->class, 'show')) ->haveStub($db = Stub::make('DbConnector', array( 'find' => function($id) { return $id ? new User() : null ))) ->setProperty($controller, 'db', $db); $I->wantTo('render profile page for valid user') ->executeTestedMethodOn($controller, 1) ->seeResultEquals(true) ->seeMethodInvoked($controller, 'render'); $I->expect('it will render page 404 for unexistent user') ->executeTestedMethodOn($controller, 0) ->seeResultNotEquals(true) ->seeMethodInvoked($controller, 'render404','User not found') ->seeMethodNotInvoked($controller, 'render'); } }
PHPUnit
で私が書いたのと同じテストが
ここにあるのを見ることができ
ます 。 それは1.5倍長くなり、コードはもちろん理解できますが、PHPUnitの達人であれば。
私たちのコードの良いところ:それは明確な構造を持っています。 まず環境を作成し、次にアクションを実行して結果を確認します。 パラメーター1で 'show'メソッドを実行した
後 、コントローラーから 'render'メソッドが実行されたかどうかを確認することに注意してください。したがって、スタブの定義とアサーションを混在させません。 すべてのチェックは、テストコードの実行後に行われます。
読みやすさについて。 このコードを創造的にテキストに変換してみましょう。
この方法で、有効なユーザーのプロファイルページをレンダリングできます。
このメソッドを実行すると
結果が等しいと表示されます:true
メソッドが呼び出されます:$ controller、 'render'
存在しないユーザーに対してページ404が表示されると思います
このメソッドを実行すると
結果が等しくないことがわかります:true
メソッドが呼び出されます:$ controller、 'render404'
呼び出されないメソッドが表示されます:$ controller、 'render'
ドキュメントを取り、書いてください。 おそらくドキュメント生成はすぐに追加されますが、今のところは、テストコード自体がテストコードをどの程度明確かつ明確に記述しているかを示したいだけです。
スタブの作成方法に注意してください。 スタブは1つのチームによって行われます。 例:
<?php
これは、PHPUnitが提供するものよりも簡単です。 少なくともmockBuilderが必要とするパラメーターの数と、それらがすべて意味するものを覚えておいてください。 しかし、最も興味深いのは、StubクラスはmockBuilderの単なるラッパーです。 注、スタブのみを作成します。 水曜日 そして、それらから、同じseeMethodInvokedコマンドによって動的に、スタブをモックに変えます。
ドキュメントおよび
ユニットモジュールの詳細
冒頭で述べたように、これは実験的なものであり、議論することができます。 しかし、それは「真空中の球状のコード」のために書かれたのではなく、それ自身の本当のニーズに基づいています。 ただし、プロジェクトに挑戦することをお勧めします。 ドキュメントで不十分な点がある場合は、お問い合わせください。
PS CodeceptionとZend Frameworkの統合に関する
記事がサイトのWebサイトに掲載されました