Answers:
我前段时间也遇到了同样的问题。
我考虑过使用Ecomdev PHPUnit模块,但是我发现它很难使用且文档记录不充分(但是我仍然喜欢Ivan所做的事情以及他对Magento生态系统的巨大贡献)。
因此,在Vinai的帮助下,我最终开发了以下测试框架模块:https : //github.com/digitalpianism/testframework
最初的目的是用于集成测试,但我也将其用于单元测试。您可以在此处查看它的运行情况:https : //github.com/digitalpianism/easytoplinks/blob/master/app/code/community/DigitalPianism/EasyToplinks/Test/Unit/Block/Page/Template/LinksTest.php
关于固定装置,我正在使用事务回滚以避免在数据库中创建样本数据。
由于Magento 1并没有开箱即用,因此如果您使用composer安装phpunit或仅下载phar版本,我认为这没有太大的区别。
如果您已经使用composer来管理站点中的其他第三方模块或库,那么composer可能最有意义。除非您使用PHP7,否则您将只能使用旧版本的phpunit(这就是我链接到上述4.8版本的原因)。
由于Magento 1是如此繁重的应用程序,因此将phpunit bootstrap分为一个用于集成和一个用于单元测试是有意义的。
单元测试引导程序仅需要初始化自动加载器,而集成测试引导程序则需要初始化整个应用程序环境,包括配置加载和数据库连接。
因此,Magento中的集成测试往往比单元测试要慢得多(在其他应用程序中则要慢得多)。
Magento的自动加载器不符合PSR-0,因为如果找不到类所在的文件,它将抛出异常。这会中断class_exists
phpunit中的某些用法。有几种可能的解决方法:
\Varien_Autoload::autoload()
在装饰器中,而忽略其中引发的异常,然后将包装器注册为新的自动装带器。与注册自动加载器并依赖于特定自动加载器顺序的第三方库发生冲突的可能性很小。\Varien_Autoload::autoload()
如果文件不存在,请使用include路径hack重写以不引发错误。但是,这与也覆盖相同类的几个模块冲突。我自己不使用这种方法。为了避免在测试期间启动会话时出错,只需$_SESSON = []
在引导程序中进行设置即可。
设置自定义响应对象Mage::app()->setResponse($testResponse)
,以扩展真实对象,但不发送输出或标头。
要在完全更改运行时状态的集成测试之间重新初始化Magento,请使用Mage::reset(); Mage::app()
。请注意,此后必须重新装饰错误处理程序。
对于DB固定装置,我倾向于在固定装置方法中使用常规模型来创建固定装置,例如createSimpleProduct($sku)
。就像Raphael所说的那样,使用setUp()
和tearDown()
将测试包装在一个事务中,该事务在测试之后会回滚(例如Mage::getSingleton('core/resource')->getConnection('default_setup')->beginTransaction()
)。
对于商店配置固定装置,我倾向于使用设置内存中固定装置Mage::app()->getStore()->setConfig($path, $value)
。
该EcomDev_PHPUnit
扩展还提供了使用yaml文件创建DB固定装置的选项,但是对于我自己来说,与使用模型类创建的固定装置相比,我发现这些装置更难以维护。YMMV。
注册表可以用于注入测试双打通过创建的对象Mage::getSingleton()
,Mage::getResourceSingleton()
和Mage::helper()
。
可以设置其他一些中心对象Mage::app()
(例如请求)。
要替换通过测试双打Mage::getModel()
或Mage::getResourceModel()
通过测试双打创建的类,必须使用自定义配置对象包装。请参见拉斐尔(Raphael)的测试框架中的示例,该操作如何完成。
一旦启动了Magento,几乎可以对所有内容进行很好的测试。由于核心代码使用了大量方法链接,因此请准备好创建深层模拟。
即使安装程序很笨拙,也可以正常工作,我发现测试给了我很多信心和价值,几乎可以与Symphony应用程序的测试套件相提并论。