2012-02-19 7 views
11

別のAPIからデータを取得してXMLに変換するAPIを作成しました。出力が期待されるXMLであり、有効であることをphpunitを使ってテストするにはどうすればよいですか?phpunit testing xml出力

すべてのノードを含むサンプルxmlを作成し、その出力をチェックする必要がありますか?

答えて

4

があり、通常は二つのアプローチです:文字列変数として

  1. 打ち期待XMLSテストクラス内と実際の結果と比較することでこれらの文字列を使用しています。
  2. 予想されるXMLを通常のファイルシステムファイルとして作成しますが、コードベースに属しています(resourcesとして扱います)。テストでは、予想されるファイルを読み込み、再び結果と比較します。

これらのオプションはどちらも実行可能ですが、XMLが大規模な場合は最初のアプローチ(ハードコードされた文字列変数としてのXML)がぎこちなくなる可能性があります。

8

これは、生成されたXMLフィーダ関数/クラスのテストについてこの問題を遭遇するすべての人にとって、これが承認される可能性があると思った検索結果として出てきました。

xml出力が正しいことをテストする方法はたくさんありますが、他の方法よりも簡単です。

私は最近OPがこの時点で尋ねていたのと同じスクリプトを完成させました。あなたが関数から、次の部分のXML出力を持っていた場合

(のは呼ぶことにしましょう、それ$ person->出力()):

<person> 
    <eyes>blue</eyes> 
    <hair> 
     <style>curly</style> 
    </hair> 
</person> 

あなたは、XMLを生成する必要が最初に考えたのは、コードを使用することです

function testWholeOutput() { 

    $person = new person(); 
    $person->setEyes("blue"); 
    $person->setHairStyle("curly"); 

    $this-assertEquals(file_get_contents("data\pregenerated_xml.xml"), $person->output()); 
} 

テストはしかし、これはの拡張を許可しない、誰もが満足している...渡しますと、このような何か、XMLが変更されていないことを確認するためにテストするためのテストケースにそれを置きますxml。もう1つの問題は、文字通り最初に出力しているものをテストしていることです。これにより、さらに問題が発生する可能性があります。

ヘアカラーの知識が必要な新しい機能を追加するとどうなりますか?テストは中断され、XML出力がまだ正しく動作していることを確認するために、スクリプトから別のXML出力を行う必要があります。

さらに、テストが壊れた場合、新しい文字列が古い文字列と異なることがわかります。

ソリューション: PHPUnitは、XMLを通過しますと、タグが存在する場合に主張することができ、コンテンツが何であるか、それは正しくセットアップであることを確認したassertTag()を呼び出し(およびassertNotTag())する機能を有しています。次のようなものより多くの項目がXML出力に追加された場合は中断されません。

function testOutputPersonHasEyes() { 

    $person = new person(); 
    $person->setEyes("blue"); 
    $person->setHairStyle("curly"); 

    $this->assertTag(
     array('tag' => 'person', 
     'child' => array('tag' => 'eyes') 
      ), 
      $person->output()); 
    } 

assertTagここでは、子タグの目」を持っている「人」タグのためにチェックしています。今、あなたはこのような何かに、XML出力の周りに入れ替える場合:これはまだ、このXMLを消費している任意のスクリプトの有効なXML、まだ有効な出力であるため、

<person> 
    <hair> 
      <style>curly</style> 
    </hair> 
    <eyes>blue</eyes> 
</person> 

あなたはまだ、上記のテストを通過します。

明らかに、コンテンツが期待どおりであり、他の項目が正しいことを確認するためにテストを書く必要がありますが、構造は長い時間がかかりますが、開発時。 PHPUnitの単位テストXML生成に追加の機能について

Tobias Schlitt wrote a great articleは、またいいと同様に、DOMオブジェクトを作成し、それをテストケースクラスのラッパーを使用してPHPのXPathを使用してテストすることによってこれに対する別の代替手段を提供しますそれについての賛否両論の説明。

+2

assertTag()とassetNotTagは()あなたのどちらかが、PHPUnitの 'assertTagを()'使用する代わりに解決策を持っているか、バージョン4.2 –

+0

@ChrisK、@DougAmosのよう推奨されていませんか? – Jodes

3

これは、コンポーザを使用してインストールできるthis phpunit component, phpunit-dom-assertionsを使用して行うことができます。

phpunitassertTag()の代わりにassertSelectEquals()(現在は償却)を使用して、タグの内容をテストします。これを行う

$this->assertTag(
    array('tag' => 'person', 
    'child' => array('tag' => 'eyes') 
     ), 
     $person->output()); 
} 

ので、代わりに、personeyesタグをチェックするために

$this->assertSelectCount(
     'person > eyes', 
     true, 
     $person->output() 
    ); 

をそして茶色の目のために特別に見えるように、次の操作を行います。

$this->assertSelectEquals(
     'person > eyes', 
     'brown', 
     true, 
     $person->output() 
    ); 
4

私はこれを行います。 1)クラスで使用する必要があります:myClass PHPUnit_Framework_TestCase、 を継承します。2)すべてのテストは[test] Functionで開始する必要があります。このような何か:

function testFunction() 
{ 
    $testXml = '<xml><message>Hi there PHP</message></xml>'; 
    $xml = simplexml_load_string($testXml, 'SimpleXMLElement', LIBXML_NOCDATA); 

    if ($xml !== false && isset($xml->message)) { 

     //either this 
     var_dump($xml->message); 
     $this->assertEquals('Hi there PHP', $xml->message); 

     //or this, should be stdClass 
     $xmlObj = json_decode(json_encode((array) xml), 1); 
     var_dump($xmlObj->message); 
     $this->assertEquals('Hi there PHP', $xmlObj->message); 
    } 
}