2012-02-19 16 views
11

मैंने एक एपीआई लिखा है जो किसी अन्य एपीआई से डेटा प्राप्त करता है और इसे एक्सएमएल में परिवर्तित करता है। मैं परीक्षण करने के लिए phpunit का उपयोग कैसे करूं कि आउटपुट अपेक्षित एक्सएमएल है और मान्य है?phpunit परीक्षण xml आउटपुट

क्या मुझे सभी नोड्स के साथ नमूना एक्सएमएल बनाना चाहिए और उसके बाद आउटपुट की जांच करनी चाहिए?

उत्तर

4

आमतौर पर दो दृष्टिकोण हैं: अपने परीक्षण कक्षा में स्ट्रिंग चर के रूप में

  1. Hardcode उम्मीद XMLs और वास्तविक परिणाम के साथ तुलना करने के लिए उन लोगों के तार का उपयोग करें।
  2. अपेक्षित एक्सएमएल नियमित फ़ाइल सिस्टम फ़ाइलों के रूप में बनाएं, फिर भी आपके कोडबेस से संबंधित (आप उन्हें resources के रूप में देखते हैं)। परीक्षण में आप अपेक्षित फ़ाइल लोड करते हैं, और एक बार फिर परिणाम के साथ तुलना करते हैं।

उन दोनों विकल्पों में व्यवहार्य हैं, हालांकि पहले दृष्टिकोण (हार्डकोडेड स्ट्रिंग वेरिएबल के रूप में एक्सएमएल) एक्सएमएल बड़े होने पर थोड़ा बेकार हो सकता है - शायद उन्हें अलग फ़ाइल में ले जाने के लिए बेहतर है।

8

यह एक खोज परिणाम के रूप में आया, मैंने सोचा कि इसे किसी भी व्यक्ति के लिए अनुमोदित किया जा सकता है, जो उत्पन्न जेएमएल फीडर फ़ंक्शन/कक्षा का परीक्षण करने के इस मुद्दे पर आता है।

एक्सएमएल आउटपुट का परीक्षण करने के कई तरीके सही हैं, कुछ दूसरों की तुलना में आसान है।

मैंने हाल ही में एक समान लिपि पूरी की है जिसे ओपी इस समय के बारे में पूछ रहा था।

आप एक समारोह से निम्न आंशिक एक्सएमएल उत्पादन था (के कॉल यह $ व्यक्ति> निर्गम()):

<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()); 
} 

टेस्ट गुजरता है, हर कोई कर रहा है एक्सएमएल। एक अतिरिक्त मुद्दा यह है कि आप सचमुच परीक्षण कर रहे हैं कि आप पहले स्थान पर क्या उत्पादन कर रहे हैं, इससे लाइन के नीचे कुछ मुद्दों का कारण बन सकता है।

क्या होता है यदि एक नई सुविधा डाली जाती है जिसमें बालों के रंग के ज्ञान की आवश्यकता होती है? परीक्षण टूट जाएगा और एक्सएमएल आउटपुट की पुष्टि करने के लिए आपको स्क्रिप्ट से एक और एक्सएमएल आउटपुट करने की आवश्यकता होगी ताकि अभी भी सही तरीके से काम कर रहा हो।

इसके अतिरिक्त यदि परीक्षण तोड़ता है तो हमें पता नहीं है कि यह कहां टूट गया है, बस नई स्ट्रिंग पुरानी स्ट्रिंग से अलग है।

समाधान: PHPUnit (और assertNotTag()) assertTag() कॉल करने के लिए एक समारोह है जो एक्सएमएल के माध्यम से जाना होगा और यदि किसी टैग मौजूद है पर जोर, क्या सामग्री है और इसे सही ढंग सेटअप है इस बात की पुष्टि कर सकते हैं। निम्नलिखित की तरह कुछ को तोड़ने नहीं होगा और अधिक आइटम एक्सएमएल उत्पादन के लिए जोड़ रहे हैं:

function testOutputPersonHasEyes() { 

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

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

assertTag यहाँ एक 'व्यक्ति' टैग है, जो एक बच्चे को टैग 'आंखें' है के लिए जाँच कर रहा है।अब आप कुछ इस तरह करने के लिए एक्सएमएल उत्पादन चारों ओर स्वैप करता है, तो:

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

आप अभी भी ऊपर परीक्षा उत्तीर्ण जाएगा, क्योंकि यह अभी भी मान्य XML, और किसी भी स्क्रिप्ट जो इस एक्सएमएल उपभोग कर रहे हैं के लिए अभी भी मान्य उत्पादन होता है।

स्पष्ट रूप से आपको यह सुनिश्चित करने के लिए परीक्षण लिखने की आवश्यकता होगी कि सामग्री की अपेक्षा की जा रही है और अन्य आइटम सही हैं लेकिन संरचना कम झूठी नकारात्मक परीक्षणों और लंबे समय तक कम काम करने की अनुमति देती है, हालांकि कुछ और समय के नुकसान के बावजूद विकास करते समय।

अतिरिक्त कार्यक्षमता के लिए, Tobias Schlitt wrote a great article phpUnit में यूनिट परीक्षण xml पीढ़ी पर, और यह एक अन्य ऑब्जेक्ट भी प्रदान करता है और इसे टेस्टकेस क्लास के चारों ओर एक रैपर का उपयोग करके और php xPath का उपयोग करके परीक्षण करता है, साथ ही साथ अच्छा ऐसा करने पर पेशेवरों/विपक्ष पर स्पष्टीकरण।

+2

assertTag() और assetNotTag() संस्करण के रूप में अनुचित हैं 4.2 –

+0

@ChrisK, @DougAmos, आप दोनों में से किसी का उपयोग कर के लिए एक विकल्प समाधान है PHPUnit के 'assertTag()'? – Jodes

3

यह this phpunit component, phpunit-dom-assertions का उपयोग करके किया जा सकता है, जिसे संगीतकार का उपयोग करके स्थापित किया जा सकता है।

फिर टैग की सामग्री के परीक्षण के लिए phpunit के assertTag() (अब अवमूल्यित) के बजाय assertSelectEquals() का उपयोग करें।

तो, बजाय एक person के भीतर एक eyes टैग के लिए जाँच करने के लिए,:

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

यह करें:

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

और भूरी आँखें के लिए विशेष रूप देखने के लिए, ऐसा करते हैं:

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

मैं यह करूँगा। 1) आपकी कक्षा का उपयोग करना चाहिए: myClass PHPUnit_Framework_TestCase, 2) बढ़ाता है, तो सभी परीक्षणों को [test] फ़ंक्शन के साथ प्रारंभ करना चाहिए, उदा। कुछ इस तरह:

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); 
    } 
}