PHP + BDD = Behat、たたは奇跡の図曞通の物語

Ruby開発に真剣に取り組んでいる人なら誰でも、すばらしいCucumber gemを知っおいたす。 芁するに、BDDで匷化された自動テスト甚のラむブラリです。 詳现に぀いおは、 dapi habrayuzerの トピックをご芧ください 。たたは、Rain Batesのポッドキャストをご芧ください。 「キュりリ」の䞻な魅力は、人が理解できる蚀語でテストを曞くこずができ、必ずしも英語である必芁がないこずです。 次のようになりたす。



機胜远加 
  愚かな間違いを避けるために 
  数孊バカずしお 
   2぀の数字の合蚈を教えおもらいたい 

  シナリオ2぀の数字を远加する 
    電卓に50を入力したずしたす
      そしお、私は電卓に70を入力したした
     远加を抌すず
     その埌、結果はスクリヌで120になるはずです


Cucumberのおかげで、レヌル䞊のBDDに倢䞭になりたした。 しかし、ほずんどの時間で䜜業しなければならないPHPでは、BDDずの関係はどういうわけかうたくいきたせんでした。 そしおたず第䞀に、きちんずしたツヌルがないためです。 しかし、ある日、運呜は私をBehatラむブラリペヌゞ ちなみに、everzet habrayuzerが曞いた に連れお行っおくれたした。 そしお、私に幞せが降りかかった...



むンストヌルずプリセット



実際、Behatは「PHPの䞖界からきゅうり」です。 同じ構文 ガヌキン蚀語を䜿甚、同じファむル構造、ステップを決定するためのほが同䞀の方法。 著者は、圌が隠しおいない図曞通の「兄」に觊発されたこずがわかりたす。 すべおが矎しく芋えたすが、私たちはそれを芋たせんでした。 動䜜䞭の補品を詊す時間です。



すぐに予玄したす-Behatの䜜業にはPHP 5.3.1が必芁です。 したがっお、ただ入手しおいない堎合は、それを行う時間です。



サむトの䜜成者は、Behatをむンストヌルするいく぀かの方法を提䟛しおいたす。 䞀番最初で最も簡単なものを遞択したす-Pearを通じお

$ pear channel-discover pear.everzet.com

$ pear install everzet/behat-beta







タダム 私たちはBehatの幞運な所有者です:)原則ずしお、テスト枈みプロゞェクトのあるフォルダヌに移動しおスクリプトの䜜成を開始するこずもできたすが、ラむブラリを少し「調敎」するこずを奜みたす。 それでは、たず、プロゞェクトフォルダヌにBehatのネむティブハビタットを䜜成したしょう。 既に述べたように、Cucumberから借甚されおおり、次の圢匏を持っおいたす。



 |-機胜
    `-ステップ
    |  `-* _steps.php
    `-サポヌト
        `-env.php




私たちが持っおいるものの詳现



env.phpファむルは最初は空です。 私たちにずっおの䞻な重芁性は、次のスクリプトの実行前に毎回実行されるこずです。 そしお、ここに必芁なすべおのラむブラリずプロゞェクトファむルを接続するず䟿利です。 たた、テストに必芁な倉数ず関数を定矩するこずも䟿利です。 ちなみに、それらのストレヌゞには、$ world倉数を䜿甚するのが非垞に䟿利です。これは、入力するたびに、新しいたびに提䟛されたす。 抂しお、基本的な機胜を䜿甚するために、䜕も蚭定する必芁はありたせん。BehatずPHP自䜓が提䟛しおくれれば十分です。 しかし、私はただPHPUnitの怜蚌関数を䜿甚したいので、蚱可を埗おそれらを接続したす。



PHPUnitがむンストヌルされおいない堎合、同じPearを介しお非垞に簡単にむンストヌルされたす。

$ pear channel-discover pear.phpunit.de

$ pear channel-discover components.ez.no

$ pear channel-discover pear.symfony-project.com

$ pear install phpunit/PHPUnit







完了、env.phpに登録するだけです

 <php
 require_once 'PHPUnit / Autoload.php';
 require_once 'PHPUnit / Framework / Assert / Functions.php';
 >


たた、プロゞェクトのクラスず関数を䜿甚できるようにするには、適切なファむルを環境に接続する必芁がありたす。 環境の初期化に䜙分なむンクルヌドを散らかしたくないので、それらを1぀のファむル-includes.phpに結合し、すでに環境に接続したす。 その結果、env.phpファむルの圢匏は次のずおりです。



 <php
 require_once 'PHPUnit / Autoload.php';
 require_once 'PHPUnit / Framework / Assert / Functions.php';
 include 'includes.php';
 >


機胜に぀いお説明し、最初のリリヌスを行いたす



さお、これでテストの準備ができたした。機胜の説明を始めるこずができたす。 䟋ずしお、2぀の数字を远加するなど、実装ずテストが難しいものを採甚するこずにしたした。 したがっお、 機胜フォルダヌにcalc.featureファむルを䜜成し、 次のように蚘述したす。



機胜远加
    愚かな間違いを避けるために 
    数孊バカずしお 
     2぀の数字の合蚈を教えおもらいたい

    シナリオ
       電卓があるず
        最初の番号ずしお30を入力したずき
         そしお、2番目の番号ずしお20を入力したした
         そしお、「远加」を抌したす
        その埌、結果は50になりたす




コマンドを保存しおコン゜ヌルに入力したす

$ behat features







出力は次のずおりです。

 1぀のシナリオ1぀の未定矩
 5ステップ5未定矩
 0.091秒

次のスニペットを䜿甚しお、未定矩のステップのステップ定矩を実装できたす。

 $ steps->䞎えられた '/ ^私は電卓を持っおいたす$ /'、function$ world{
     new \ Everzet \ Behat \ Exception \ Pending;
 };

 $ steps-> When '/ ^ I are\ d +as first number $ /'、function$ world、$ arg1{
     new \ Everzet \ Behat \ Exception \ Pending;
 };

 $ steps-> And '/ ^ I are\ d +as second number $ /'、function$ world、$ arg1{
     new \ Everzet \ Behat \ Exception \ Pending;
 };

 $ steps-> And '/ ^ I press \'[^ \ '] *\' $ / '、function$ world、$ arg1{
     new \ Everzet \ Behat \ Exception \ Pending;
 };

 $ steps-> Then '/ ^結果は\ d +$ /'、function$ world、$ arg1{
     new \ Everzet \ Behat \ Exception \ Pending;
 };


これは、シナリオの「ステップ」を定矩しおいないこずを瀺しおいたす。 しかし、私たちはさらに倚くを知っおいたす-蚈算機クラスはありたせん。 問題ではなく、曞いおください。



クラスCalc {
    保護された$ first = 0;
    保護された$秒= 0;
    保護された$ result = 0;

    パブリック関数setFirst$ num{$ this-> first = $ num;  }
    パブリック関数setSecond$ num{$ this-> second = $ num;  }
     public function add{$ this-> result = $ this-> first + $ this-> second;  }
     public function getResult{return $ this-> result;  }
 }


手順を説明し、テストを成功させたす。



それでは、ステップの説明に移りたす。 はい、ちなみに、ファむル機胜/サポヌト/includes.phpの蚈算機のクラスにファむルを含めるこずを忘れないでください。 ご芧のずおり、Behatは芪切に手順を定矩するためのパタヌンを提䟛しおくれたした。 それらをコピヌしお少し調敎し、 features / steps / calc_steps.phpファむルに保存したす 。 次のようなものが埗られるはずです。

 <php
 $ steps->䞎えられた '/ ^私は電卓を持っおいたす$ /'、function$ world{
     $ world-> calc = new Calc;
 };
 $ steps-> when '/ ^ Iが最初の数字$ /'ずしお\ d +を入力した堎合、function$ world、$ num{
     $ world-> calc-> setFirst$ num;
 };
 $ steps-> When '/ ^ Iが2番目の数倀$ /'ずしお\ d +を入力した堎合、function$ world、$ num{
     $ world-> calc-> setSecond$ num;
 };
 $ steps-> When '/ ^ I press \' Add \ '$ /'、function$ world{
     $ world-> calc-> add;
 };
 $ steps-> Then '/ ^結果は\ d +$ /'、function$ world、$ res{
     assertEquals$ res、$ world-> calc-> getResult;
 };
 >


テストを再開したす-出来䞊がりです テストに合栌したした:)



機胜远加
  愚かな間違いを避けるために
  数孊バカずしお
   2぀の数字の合蚈を教えおもらいたい

  シナリオfeatures / calc.feature6
    蚈算機features / steps / calc_steps.phpがある堎合5
    最初の番号ずしお30を入力した堎合features / steps / calc_steps.php9
    そしお、2番目の番号ずしお20を入力したしたfeatures / steps / calc_steps.php13
    そしお、「远加」を抌したすfeatures / steps / calc_steps.php17
    その埌、結果は50features / steps / calc_steps.phpになるはずです21

 1シナリオ1合栌
 5ステップ5合栌
 0.114秒


ペヌゞをテストしようずしおいたす。



もちろん、クラスの動䜜をテストするこずはプロゞェクトの重芁な郚分です。 しかし、顧客は、い぀ものように、私たちからの䜜業クラスではなく、正しく機胜する圌の意芋ではアプリケヌションを望んでいたす。 簡単に蚀えば-圌はむンタヌフェむスの正しい操䜜が必芁です。 珟圚の動䜜の怜蚌。 Ruby on Railsは埓来、cucumer + webrat + nokogiriを䜿甚しおペヌゞをテストしたす。 PHPの䞖界では、すべおが少し耇雑であるこずが刀明したした...そのペヌゞにある゚バヌれット自䜓は、このためにSymfony 2に基づいたGoutteラむブラリを䜿甚するこずを瀺唆しおいたす。 、登録解陀しおください。 Goutteのむンストヌルは非垞に簡単です。pharアヌカむブをダりンロヌドしおenv.phpに接続したす。



テストの䟋ずしお、簡単なペヌゞをスケッチしたした。

 <DOCTYPE html>
 <html>
     <head>
     </ head>
     <本䜓>
         <div> <
             if$ _GET ["submit"]{
                 echo "Text ="。  $ _GET ['textfield']。  "<br />";
                 echo "Checkbox ="。  $ _GET ['チェックボックス']。  "<br />";
                 echo "Radio ="。  $ _GET ['radio']。  "<br />";
                 echo "Select ="。  $ _GET ['selectbox']。  "<br />";
             }
         > </ div>
         <form method = "get" action = "behat.php">
             <div>
                 <input type = "text" name = "textfield" value = "">
             </ div>
             <div>
                 <入力タむプ=「チェックボックス」名前=「チェックボックス」倀=「チェックボックス」>
             </ div>
             <div>
                 <入力タむプ= "ラゞオ"名前= "ラゞオ"倀= "ラゞオ1"チェック= "チェック">
                 <入力タむプ= "radio" name = "radio" value = "radio2">
                 <入力タむプ= "radio" name = "radio" value = "radio3">
             </ div>
             <div>
                 <select name = "selectbox">
                     <option value = "option1" selected = "selected"> option1 </ option>
                     <option value = "option2"> option2 </ option>
                     <option value = "option3"> option3 </ option>
                 </ select>
             </ div>
             <div>
                 <入力タむプ=「送信」名前=「送信」倀=「送信」>
             </ div>
             <div id = "linkdiv">
                 <a href="behat.php?textfield=text&checkbox=checkbox&radio=radio3&selectbox=option2&submit=Submit">クリック</a>
             </ div>
         </ form>
     </ body>
 </ html>


タスクそのフォヌムの動䜜を確認したす。 はい、タスクは非垞に合成的ですが、これは単なる䟋です:)それで、テストのリストをカバヌしたす

機胜テスト
    フォヌムを送信した埌、フィヌルドのすべおの倀
    ペヌゞの䞊郚に衚瀺する必芁がありたす

    シナリオフィヌルドを埋める
        私がテストペヌゞにいるず仮定しお
          「送信」フォヌムで「テキストフィヌルド」に「テキスト」を入力するず
          そしお、フォヌム 'Submit'を送信したす
         次に、「テキスト=テキスト」が衚瀺されたす

    シナリオチェックボックスをオンにする
        私がテストペヌゞにいるず仮定しお
         フォヌム「送信」のチェックボックス「チェックボックス」にチェックマヌクを付けるず
          そしお、フォヌム 'Submit'を送信したす
         次に、「チェックボックス=チェックボックス」が衚瀺されたす

    シナリオラゞオの遞択
        私がテストペヌゞにいるず仮定しお
          「Submit」フォヌムの「radio」ラゞオで「radio2」を遞択するず
          そしお、フォヌム 'Submit'を送信したす
         次に、「Radio = radio2」が衚瀺されたす
         その埌、「Radio = radio1」が衚瀺されないはずです

    シナリオ遞択ボックスでオプションを遞択する
        私がテストペヌゞにいるず仮定しお
         フォヌム「送信」の遞択ボックス「selectbox」で「option3」を遞択するず
          そしお、フォヌム 'Submit'を送信したす
         次に、「Select = option3」が衚瀺されたす
         その埌、「Select = option1」が衚瀺されないはずです

    シナリオいく぀かのフィヌルドを埋める
        私がテストペヌゞにいるず仮定しお
         フォヌム「Submit」に以䞋を入力するず
             | テキストフィヌルド| テキスト|
             | チェックボックス| 真|
             | ラゞオ|  radio3 |
             | セレクトボックス| オプション2 |
          そしお、フォヌム 'Submit'を送信したす
         次に、「テキスト=テキスト」が衚瀺されたす
          そしお、私は「チェックボックス=チェックボックス」が衚瀺されるはずです
          そしお、「Radio = radio3」が衚瀺されるはずです。
          そしお、「div」内に「Select = option2」が衚瀺されるはずです。

    シナリオリンクをクリックする
        私がテストペヌゞにいるず仮定しお
          「#linkdiv」内の「Click me」リンクをクリックするず
         次に、「テキスト=テキスト」が衚瀺されたす
          そしお、私は「チェックボックス=チェックボックス」が衚瀺されるはずです
          そしお、「Radio = radio3」が衚瀺されるはずです。
          そしお、「div」内に「Select = option2」が衚瀺されるはずです。
          そしお、「Submit」フォヌムの「textfield」フィヌルドは空癜にする必芁がありたす




テストのフォヌムが「送信」ず呌ばれる理由の簡単な説明。 Goutteでは、フォヌムは送信ボタンで遞択されたす。 ボタン自䜓はIDたたは倀で怜玢されたす。 そしお、テストペヌゞのボタンは誇らしげにSubmitずいう名前になっおいるため、この蚀葉遣いです。



倚くの手順があり、手順は異なり、誰もがGoutteでの䜜業に関䞎しおいたす。 幞いなこずに、これらのすべおの手順はすでに説明されおおり、ファむルにたずめられおいたす。 gitリポゞトリgit//github.com/DarthSim/behat_websteps.gitから目的のものをプルできたす。 リポゞトリには次のものがありたす。



階局を保持したたた、プロゞェクトず共にフォルダヌにファむルをコピヌし、テストを実行したす。 そしお、゚ラヌが発生したす...



Unknown path 'test page'. You can define it in [features_folder]/support/paths.php







゚ラヌはそれ自䜓を物語っおいたす-テストは、どの皮類の「テストペヌゞ」をチェックしたいかを知りたせん。 最も簡単な修正方法は、 features / support / paths.phpファむルで 「テストペヌゞ」ペヌゞのパスを蚭定するこずです 。 テストペヌゞがtests.dev/behat.phpにあるずしたす 。そのため、パスファむルに次のように蚘述する必芁がありたす。



$world->paths['test page'] = "http://tests.dev/behat.php";







テストを実行したす-玠晎らしい、テストに合栌したした 残りのステップの分析は、webratの類䌌物に䌌おいるため、読者に任せたす。 もちろん、結果の機胜はwebratよりもはるかに劣っおいたすが、これはほんの始たりに過ぎないず思いたす。



結論を導き、リンクを提䟛する



したがっお、BehatはPHPの䞖界でCucumberの埌継にふさわしいず蚀っおも過蚀ではありたせん。 ラむブラリはただバヌゞョン1.0に成長しおいたせんが、すでに高品質の完成品を衚しおいたす。 私たちは、開発者が圌の発案の開発に成功するこずを望み、圌に良い光線を送りたす。 以䞋は䟿利なリンクです。



githubのBehatリポゞトリ

Behat WIKI

Behat API

Goutteリポゞトリ

Symfony 2 API Goutteに圹立ちたす



All Articles