在编写模块时,我试图为它们提供应用程序最关键部分的单元测试。但是,目前(Magento 2.1.3)有几种编写单元测试的方法:
不同的测试方式
- 与它集成
bin/magento dev:tests:run unit
并在与Magento捆绑在一起的默认phpunit设置之上运行它。 - 分别编写它们,与它们一起运行
vendor/bin/phpunit app/code/Vendor/Module/Test/Unit
并模拟Magento的所有内容。 - 分别编写它们,模拟所有内容,并使用系统全局版本的PHPUnit。
- 单独编写它们,然后使用运行它们
vendor/bin/phpunit
,但仍然使用\Magento\Framework\TestFramework\Unit\Helper\ObjectManager
。
Magento 2和PHPUnit
除此之外,Magento 2捆绑了与PHP7不兼容的PHPUnit 4.1.0。提示类型的本机(如string
和int)并在签名中声明返回类型将引发错误。例如,具有方法签名的接口/类如下:
public function foo(string $bar) : bool;
...将无法被PHPUnit 4.1.0模拟。:-(
我目前的情况
因此,我现在主要以第三种方式(通过调用系统全局PHPUnit版本)编写单元测试。
在我的设置中,我全局安装了PHPUnit 5.6,因此我可以解决编写正确的PHP7代码的问题,但是我必须做一些调整。例如:
phpunit.xml
必须看起来像这样,所以我可以使用composer autoloader:
<?xml version="1.0"?>
<phpunit bootstrap="../../../../../../vendor/autoload.php"
colors="true">
<testsuites>
<testsuite name="Testsuite">
<directory>.</directory>
</testsuite>
</testsuites>
</phpunit>
...以及我所有的setUp()
方法中,都有以下检查,以便可以编写具有前向兼容性的测试:
// Only allow PHPUnit 5.x:
if (version_compare(\PHPUnit_Runner_Version::id(), '5', '<')) {
$this->markTestSkipped();
}
这样,当我的测试由Magentos的内置PHPUnit运行时,它不会引发错误。
我的问题
所以这是我的问题:这是编写单元测试的“健康”方式吗?因为在我看来Magento捆绑了一大堆工具来辅助测试,这在我看来并不对,我无法使用它们,因为我正在使用PHP7。我知道GitHub上有解决此问题的票证,但我想知道社区当前是如何编写测试的。
有没有一种方法可以在Magento 2中编写单元测试,所以我不必“降级”我的代码,仍然可以使用Magentos的内置帮助器来模拟对象管理器接触的所有内容?还是即使在单元测试中也使用对象管理器甚至是不好的做法?
我缺少有关如何对自己的自定义模块进行单元测试的正确方法的大量指南/示例。