如何在 phpunit 中引用外部数据提供者?

Posted

技术标签:

【中文标题】如何在 phpunit 中引用外部数据提供者?【英文标题】:How can I reference external data providers in phpunit? 【发布时间】:2018-02-02 14:47:49 【问题描述】:

我正在尝试使用 phpUnit 中的通用数据提供程序运行一些测试。

看下面的测试:

    namespace AppBundle\Tests\Controller;

    use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
    use AppBundle\Tests\DataProvider\XmlDataProvider;

    class DefaultControllerTest extends WebTestCase
    
        /**
         * @dataProvider XmlDataProvider::xmlProvider
         * @covers ReceiveController::receiveAction()
         * @param string
         */
        public function testReceive($xml)
        
            $client = static::createClient([], ['HTTP_HOST' => 'mt.host']);
            $client->request(
                'POST',
                '/receive',
                [],
                [],
                [],
                $xml
            );

            $response = $client->getResponse();
            $this->assertEquals(200, $response->getStatusCode());
        
    

现在我想要一个外部数据提供者类:

namespace AppBundle\Tests\DataProvider;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class XmlDataProvider extends WebTestCase

    /**
     * @dataProvider
     */
    public static function xmlProvider()
    
        return array([
            'xml1' => '<?xml version="1.0" encoding="UTF-8"?><myTestableXml></myTestableXml>'
        ]);
    

但是当我运行 phpunit 时,我得到:

1) 警告 指定的数据提供者 AppBundle\Tests\Controller\DefaultControllerTest::testReceive 是 无效的。 XmlDataProvider 类不存在

2) 警告 类中未找到测试 “AppBundle\Tests\DataProvider\XmlDataProvider”。

我该怎么做?

更新

composer.json 自动加载 sn -p 供参考:

"autoload": 
    "psr-4": 
        "AppBundle\\": "src/AppBundle",
        "Tests\\": "tests"
    ,
    "classmap": [
        "app/AppKernel.php",
        "app/AppCache.php"
    ]
,
"autoload-dev": 
    "psr-4": 
        "Tests\\": "tests/"
    ,
    "files": [
        "vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
    ]
,

【问题讨论】:

【参考方案1】:

您需要使用完全限定的类名来引用数据提供者:

namespace AppBundle\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class DefaultControllerTest extends WebTestCase

    /**
     * @dataProvider \AppBundle\Tests\DataProvider\XmlDataProvider::xmlProvider
     * @covers ReceiveController::receiveAction()
     * @param string $xml
     */
    public function testReceive($xml)
    
        // ...
    

自动加载

另外,请确保调整 composer.json 中的自动加载配置,以便可以自动加载数据提供程序(可能需要根据“AppBundle\Test”命名空间映射到的目录进行调整):


    "autoload-dev": 
        "psr-4": 
            "AppBundle\\Tests\\": "tests/"
        
    

或者,既然您建议您的自动加载配置如下所示:


    "autoload-dev": 
        "psr-4": 
            "Tests\\": "tests/"
        
    

您需要将您的命名空间从AppBundle\Tests 调整为Tests\AppBundle

注意 与您的问题无关,但就我个人而言,我认为数据提供者不需要扩展 WebTestCase

例如,请参阅:

https://github.com/refinery29/test-util#example https://github.com/symfony/symfony-demo/blob/master/composer.json#L6-L16

【讨论】:

谢谢,但它仍然给我警告... :/ 1) 警告为 AppBundle\Tests\Controller\DefaultControllerTest::testReceive 指定的数据提供程序无效。类 \AppBundle\Tests\DataProvider\XmlDataProvider 不存在` 你真的在使用\AppBundle\Tests\DataProvider\XmlDataProvider::xmlProvider()吗? 是的,它提供了用于各种测试的 xml……嗯……这就是计划。还是你的意思是“使用”? 如果断言assertTrue(class_exists(\AppBundle\Tests\DataProvider\XmlProvider::class) 通过,那么你应该很高兴。否则,a) 测试命名空间中的类的自动加载配置丢失或 b) 数据提供者的类名与其在项目目录结构中的位置不匹配。 调整了我的答案以反映可能需要调整您的composer.json。顺便说一句,即使一开始可能不需要为开发资源自动加载,但最好从一开始就提供适当的autoload-dev 配置来记录它。这还有一个优点,即如果您开始提取抽象测试用例,或者 - 如您的示例 - 外部数据提供者,它可以立即工作。【参考方案2】:

PHPUnit 提供程序自动加载器

在 PHPUnit 中自动加载 CSV、JSON、PHP、XML 和 YAML 数据提供程序的魔术助手。

安装

composer require redaxmedia/phpunit-provider-autoloader

用法

为您的测试套件创建 TestCaseAbstract:

<?php
namespace ExampleProject\Tests;

use PHPUnitProviderAutoloader;

/**
 * TestCaseAbstract
 *
 * @since 2.0.0
 *
 * @package ExampleProject
 * @category Tests
 */

abstract class TestCaseAbstract extends PHPUnitProviderAutoloader\TestCaseAbstract

    /**
     * directory of the provider
     *
     * @var string
     */

    protected $_providerDirectory = 'tests' . DIRECTORY_SEPARATOR . 'provider';

    /**
     * namespace of the testing suite
     *
     * @var string
     */

    protected $_testNamespace = __NAMESPACE__;

从 TestCaseAbstract 扩展以自动加载 ExampleTest_testMethod.csv|json|php|xml|yml 文件:

<?php
namespace ExampleProject\Tests;

/**
 * ExampleTest
 *
 * @since 2.0.0
 *
 * @package ExampleProject
 * @category Tests
 */

class ExampleTest extends TestCaseAbstract

    /**
     * testMethod
     *
     * @since 2.0.0
     *
     * @param string $expect
     *
     * @dataProvider providerAutoloader
     */

    public function testMethod(string $expect = null)
    
        $this->assertEquals($expect, 'test');
    

了解详情

相关仓库:https://github.com/redaxmedia/phpunit-provider-autoloader

示例集成:PHP test 自动加载 PHP class provider 和 PHP method provider

【讨论】:

以上是关于如何在 phpunit 中引用外部数据提供者?的主要内容,如果未能解决你的问题,请参考以下文章

PhpUnit 无法访问外部 url

Laravel5、PHPUnit 和 Date Mutators:不能在数据提供者中使用 mutator

如何设置 Laravel Boilerplate phpunit 以在 Homestead 环境中提供代码覆盖

phpunit可以使用多个数据提供者吗

PHPUnit和数据提供者的问题

PHPUnit-函数依赖-数据提供-异常-忽略-自动生成