如何在 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 中引用外部数据提供者?的主要内容,如果未能解决你的问题,请参考以下文章
Laravel5、PHPUnit 和 Date Mutators:不能在数据提供者中使用 mutator