0

私は、オブジェクト指向でも多くの点で適切に記述されていないZend Framework Webアプリケーションを継承しましたが、テストはありませんでした。したがって、単体テストの価値を高く評価し、コードを追加または再記述しながらそれらを記述しますが、コードカバレッジを備えた機能テストを開始するのに最適な場所のようです。また、アプリケーションがどのように機能するかを理解するための優れた学習ツールにもなります。これはZendFramework1.11であり、Matthew Weier O'Phinneyは、Zend_Testは3.4までのPHPUnitでのみ機能すると述べています。そこで、最新の3.4.15をインストールしました。Zend_Test_PHPUnit_ControllerTestCaseを拡張して、その方法でコントローラーの単体テストを実行できることを確認しました。

Seleniumを介した機能テストでは、コードカバレッジを機能させるのに問題がありました。実際、Seleniumサーバーの動作方法を考えると、カバレッジデータを取得することが技術的に実現可能かどうかは疑問でしたが、PHPUnit_Seleniumコードカバレッジは機能しますか?PHPUnit_Seleniumコードカバレッジは機能しますか?私はついにそれを私のアプリケーションで動作させることができました。コードのどの部分がさまざまなリクエストによってヒットされているかを確認できるのは素晴らしいことです。

しかし、私が今目にしている問題は、POSTリクエストを処理するコードが報告されていないように見えることです。

たとえば、コントローラーには、次のようなコードを持つcontactActionメソッドがあります。

$this->view->form = $form;
 if ($this->getRequest()->isPost()) {
   if ($form->isValid($this->getRequest()->getPost())) {
     $values = $form->getValues();

お問い合わせフォーム用です。Seleniumテストでは、URLを開き、メッセージを入力し、送信ボタンをクリックして、ページが読み込まれるのを待ちます。テストを実行すると、ブラウザーでこれが発生し、セレンによって入力されたメッセージが記載された電子メールを受信することがわかります。したがって、フォームは有効なデータで投稿され、次の2行は実行されたと確信しています。ただし、カバレッジレポートでは、最初の2行は緑色で、次の2行はオレンジ色です。

prepend.phpスクリプトとappend.phpスクリプトの両方をインストルメント化して、次の情報をログに記録しました。

     "(File: " . __FILE__ . "): REQUEST_METHOD: " . $_SERVER['REQUEST_METHOD'] . "\n" .
     "REQUEST_URI: " . $_SERVER['REQUEST_URI'] . "\n" .
     "_COOKIE['PHPUNIT_SELENIUM_TEST_ID']: '" . print_r(isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']), 1) . "'\n" .
     "_GET['PHPUNIT_SELENIUM_TEST_ID']: '" . print_r(isset($_GET['PHPUNIT_SELENIUM_TEST_ID']), 1) . "'\n" .
     "_POST['PHPUNIT_SELENIUM_TEST_ID']: '" . print_r(isset($_POST['PHPUNIT_SELENIUM_TEST_ID']), 1) . "'\n" .

奇妙なことに、追加スクリプトではなく、追加スクリプトのみがログに記録されます。理由はわかりませんが、カバレッジデータには影響しないようです(少なくともGETリクエストの場合)。それを説明するかもしれない私が見た唯一のことは、Zend MVCアプリがexit()で終了するかどうかです。それは理にかなっていますか?

お問い合わせのやり取りでログに記録される内容は次のとおりです。

(File C:\xampp\htdocs\myapp\public\prepend.php): REQUEST_METHOD: GET
REQUEST_URI: /index/contact
_COOKIE['PHPUNIT_SELENIUM_TEST_ID']: '1'
_GET['PHPUNIT_SELENIUM_TEST_ID']: ''
_POST['PHPUNIT_SELENIUM_TEST_ID']: ''
extension_loaded('xdebug'): '1'

(File C:\xampp\htdocs\myapp\public\prepend.php): REQUEST_METHOD: GET
REQUEST_URI: /index/contact
_COOKIE['PHPUNIT_SELENIUM_TEST_ID']: '1'
_GET['PHPUNIT_SELENIUM_TEST_ID']: ''
_POST['PHPUNIT_SELENIUM_TEST_ID']: ''
extension_loaded('xdebug'): '1'

(File C:\xampp\htdocs\myapp\public\prepend.php): REQUEST_METHOD: POST
REQUEST_URI: /index/contact
_COOKIE['PHPUNIT_SELENIUM_TEST_ID']: '1'
_GET['PHPUNIT_SELENIUM_TEST_ID']: ''
_POST['PHPUNIT_SELENIUM_TEST_ID']: ''
extension_loaded('xdebug'): '1'

(File C:\xampp\htdocs\myapp\public\prepend.php): REQUEST_METHOD: GET
REQUEST_URI: /default/index/contact
_COOKIE['PHPUNIT_SELENIUM_TEST_ID']: '1'
_GET['PHPUNIT_SELENIUM_TEST_ID']: ''
_POST['PHPUNIT_SELENIUM_TEST_ID']: ''
extension_loaded('xdebug'): '1'

(File C:\xampp\htdocs\myapp\public\prepend.php): REQUEST_METHOD: GET
REQUEST_URI: /default/index/contact
_COOKIE['PHPUNIT_SELENIUM_TEST_ID']: '1'
_GET['PHPUNIT_SELENIUM_TEST_ID']: ''
_POST['PHPUNIT_SELENIUM_TEST_ID']: ''
extension_loaded('xdebug'): '1'

(File C:\xampp\htdocs\myapp\public\prepend.php): REQUEST_METHOD: GET
REQUEST_URI: /phpunit_coverage.php?PHPUNIT_SELENIUM_TEST_ID=a85030b0bcdb0460bfb17a83a373d6b5
_COOKIE['PHPUNIT_SELENIUM_TEST_ID']: ''
_GET['PHPUNIT_SELENIUM_TEST_ID']: '1'
_POST['PHPUNIT_SELENIUM_TEST_ID']: ''
extension_loaded('xdebug'): '1'

ご覧のとおり、GETリクエストは2回ログに記録され、POSTは1回だけログに記録されます。おそらくそれは、POSTSがカバーしていないのに、GETリクエストだけがカバーされているように見えるという事実に関連していますか?しかし、私はこの振る舞いをいくつかの点で本当に理解しておらず、それを理解するために何をすべきか途方に暮れています。

なぜ私がPOSTリクエストのカバレッジを取得していないのか、またはそれを追跡するための次のステップは何かについて、誰かが何かアイデアを得ましたか?

4

1 に答える 1

0

質問では、おそらく Zend Framework が exit() を呼び出していた場合、append.php スクリプトがログに記録されなかった理由を説明できるのではないかと推測しました。そこで、ZF ライブラリのソース全体で exit() の呼び出しを検索したところ、3 つしか見つかりませんでした。

library/Zend/Controller/Action/Helper/Redirector.php:        exit();
library/Zend/Oauth/Consumer.php:        exit(1);
library/Zend/OpenId.php:            exit();

このシナリオでは、Oauth または OpenId は使用されませんでした。しかし、コメントで指摘したように、POST リクエスト コードは、ログインに失敗してフォームが再表示されたときにカバレッジを示しましたが、成功してウェルカム ページへのリダイレクトが発生したときにはカバレッジを示しませんでした。したがって、リダイレクタはチェックする場所のように見えました。

リダイレクトの場合、このアプリケーションのアクション ルーチン内のコードは、次のものを一様に使用します。

$this->_redirect("some-url");

それが問題になったことは一度もないので、それがどのように機能するか、またはそのオプションを調査したことはありません。しかし、カバレッジの問題を引き起こしている可能性があるため、ドキュメントを読み、Zend のソース コードを参照しました。リダイレクトで exit() を呼び出さないようにする簡単なオプションがあることがわかりました。そこで、問題のものを次のように変更しました。

return $this->_redirect("some-url", array('exit'=>false));

そして出来上がり、POST リクエストの不足しているコード カバレッジが表示されました!

ここで、_redirect をオーバーライドして終了呼び出しを常に抑制する必要があるのか​​ 、それともテスト環境でのみ行うべきなのか疑問に思っています。リダイレクト時にスクリプトをすぐに終了すると、本番環境でいくつかのサイクルが節約される可能性があると思います。

したがって、主な問題は解決されます。しかし、append.php スクリプトに記述したロギング コードがまだ出力を生成しないという謎が残っています。prepend.php スクリプトは常にログ出力を生成しますが、append.php は生成しません。ZF 内で exit() 呼び出しの跡をたどったのは、append.php からの出力がないことでしたが、出力が生成されない理由は他にもあるようです。

そして、私はついにこれを理解しました。これは単に追加スクリプトのタイプミスでした。私はappend.phpに追加したロギングコードがprepend.phpのコードと同一であることを「知っていた」ので、それを信じることができませんでした。しかし、どうやら私はコピーの選択を太く指し、メッセージテキストの最後の行を見逃したようです. 最終的に欠落している行を見つけたとき、私の最初の反応は、「それはあり得ません。単に出力が不足しているのではなく、構文エラーが発生するはずだったのです」というものでした。私が期待したコードは次のとおりです。

$msg ="\n(File " . __FILE__ . "): REQUEST_METHOD: " . $_SERVER['REQUEST_METHOD'] . "\n" .
         "REQUEST_URI: " . $_SERVER['REQUEST_URI'] . "\n" .
         "_COOKIE['PHPUNIT_SELENIUM_TEST_ID']: '" . print_r(isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']), 1) . "'\n" .
         "_GET['PHPUNIT_SELENIUM_TEST_ID']: '" . print_r(isset($_GET['PHPUNIT_SELENIUM_TEST_ID']), 1) . "'\n" .
         "_POST['PHPUNIT_SELENIUM_TEST_ID']: '" . print_r(isset($_POST['PHPUNIT_SELENIUM_TEST_ID']), 1) . "'\n" .
         "extension_loaded('xdebug'): '". print_r(extension_loaded('xdebug'), 1) . "'\n";
file_put_contents($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] . "/msg.log", $msg, FILE_APPEND);

しかし、誤って $msg への代入の最後の行を見逃してしまいました。そのため、欠落していることに気付き、file_put_contents() の呼び出しの前の行にぶら下がっている文字列連結演算子を見たとき、最初は構文エラーが発生していないことに戸惑いました。しかしもちろん、php は $msg の古い値 (プリペンド スクリプトで割り当てられた値) を使用して file_put_contents() を呼び出し、その結果 (書き込まれたバイト数) を $msg に割り当てられた文字列 (その後、は使用されません)! コードを正確に見たときは驚くことではありませんが、正しいコードのコピーと貼り付けが間違っている可能性はないと仮定して心が曇っているときは、信じられないほど神秘的です!

于 2013-03-03T20:07:12.513 に答える