phpunit测试xml输出

Jas*_*son 12 xml phpunit unit-testing

我编写了一个API,它从另一个API获取数据并将其转换为XML.如何使用phpunit测试输出是否为预期的XML并且有效?

我应该创建一个包含所有节点的样本xml,然后检查输出吗?

小智 9

这是一个我认为可以批准的搜索结果,对于遇到这个测试生成的xml馈送器功能/类的问题的人来说.

有很多方法可以测试xml输出是否正确,有些方法比其他输出更容易.

我最近完成了一个与OP此时询问的类似的脚本.

如果你有一个函数的以下部分xml输出(我们称之为$ person-> output()):

<person>
    <eyes>blue</eyes>
    <hair>
        <style>curly</style>
    </hair>
</person>
Run Code Online (Sandbox Code Playgroud)

首先想到的是使用你生成xml的代码并将其放入测试用例中进行测试,以确保xml没有改变,如下所示:

function testWholeOutput() {

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

    $this-assertEquals(file_get_contents("data\pregenerated_xml.xml"), $person->output());
}
Run Code Online (Sandbox Code Playgroud)

测试通过,每个人都很高兴...但是,这不允许扩展xml.另一个问题是,您首先要测试输出的内容,这可能会导致一些问题进一步发生.

如果放入需要了解头发颜色的新功能会发生什么?测试将中断,您需要从脚本执行另一个xml输出,以确认xml输出仍然正常工作.

此外,如果测试中断,那么我们不知道它在哪里损坏,只是新字符串与旧字符串不同.

解决方案:phpUnit有一个函数来调用assertTag()(和assertNotTag()),它将通过xml并且可以断言标记是否存在,内容是什么并确认它是否正确设置.如果将更多项添加到xml输出中,则以下内容不会中断:

function testOutputPersonHasEyes() {

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

    $this->assertTag(
        array('tag' => 'person',
        'child' => array('tag' => 'eyes')
            ), 
            $person->output());
    }
Run Code Online (Sandbox Code Playgroud)

这里的assertTag正在检查一个'person'标签,它有一个子标签'eyes'.现在,如果你将xml输出交换为这样的东西:

<person>
    <hair>
            <style>curly</style>
    </hair>
    <eyes>blue</eyes>
</person>
Run Code Online (Sandbox Code Playgroud)

您仍将通过上述测试,因为它仍然是有效的xml,并且仍然是使用此xml的任何脚本的有效输出.

显然,您需要编写测试以确保内容符合预期并且其他项目是正确的但结构允许较少的错误否定测试和较少的工作从长远来看,尽管在开发时会损害更多时间.

对于其他功能,Tobias Schlitt写了一篇关于phpUnit中单元测试xml生成的精彩文章,并通过创建一个dom对象并使用它围绕testcase类包装并使用php xPath进行测试,以及关于这样做的利弊的好解释.

  • 自版本4.2起,不推荐使用assertTag()和assetNotTag() (2认同)

k.m*_*k.m 5

通常有两种方法:

  1. 将预期的 XML 硬编码为测试类中的字符串变量,并使用这些字符串与实际结果进行比较。
  2. 创建预期的 XML 作为常规文件系统文件,但属于您的代码库(您将它们视为资源)。在测试中,您加载预期的文件,并再次将其与结果进行比较。

这两个选项都是可行的,但是当 XML 很大时,第一种方法(XML 作为硬编码字符串变量)可能会有点笨拙 - 那么最好将它们移动到单独的文件中。


Gil*_* AB 5

我会这样做。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);
   }
}
Run Code Online (Sandbox Code Playgroud)


Ráp*_*rás 5

将 XML 字符串加载到 simplexml 对象。

    $object = simplexml_load_string($xml);
Run Code Online (Sandbox Code Playgroud)

如果可以实例化,它应该是有效的对象。

    $this->assertNotFalse($object);
    $this->assertInstanceOf( \SimpleXMLElement::class, $object);
Run Code Online (Sandbox Code Playgroud)

检查输出中所需的所有 XML 节点。

    $this->assertObjectHasAttribute("vehicle", $object);
    //...
Run Code Online (Sandbox Code Playgroud)