我最近继承了一个程序良好的 PHP 应用程序的开发和维护(讽刺)。该应用程序基于商业软件(我不会命名),并且有一个自定义层(我们的)构建在它之上。
不幸的是,此应用程序使用大量 全局变量和单例变量(双关语)。我已经为我们覆盖的所有内容构建了测试用例。然而,很多事情都依赖于某些全局状态,这可能会导致竞争条件和各种奇怪的事情。
为了捕捉这些奇怪的东西中的大部分(我喜欢这样调用它们),我构建了一个 PHPUnit TestDecorator,[如手册][1]。这个:
class PHPUnit_Extensions_Randomizer extends PHPUnit_Extensions_TestDecorator
{
public function __construct(PHPUnit_Framework_Test $test)
{
$tests = $test->tests();
$shuffle = array();
foreach ($tests as $t) {
if ($t instanceof PHPUnit_Framework_TestSuite) {
$shuffle = array_merge($shuffle, $t->tests());
} else {
$shuffle[] = $t;
}
}
shuffle($shuffle);
$suite = new PHPUnit_Framework_TestSuite();
foreach ($shuffle as $t) $suite->addTest($t);
parent::__construct($suite);
}
}
它基本上随机化了测试顺序,以确保测试不依赖于可能正确或可能不正确的全局状态。
问题出现在测试我的自定义装饰器的时候。我没有在手册、谷歌或 Stack Overflow 的任何地方找到如何加载它。
在分析代码时,我看到PHPUnit本身在TextUI_TestRunner::doRun()方法中实例化了RepeatedTest装饰器。我知道我可以子类化 TestRunner,覆盖 doRun(),安排创建我的装饰器,然后调用 parent::doRun() 以我的装饰器实例作为参数,覆盖 TextUI_Command 并创建一个新的 CLI 脚本来使用我的东西而不是内置的东西。
在我(重新)发明轮子之前,我只是想知道,是否可以在不对 TestRunner 进行子类化的情况下加载自定义装饰器?
谢谢。
最佳答案
对于当前的 PHPUnit 版本,大部分情况下都没有简单的方法插入您自己的代码。唯一提供可互换性的是 TestRunner,您描述的内容对我来说很有意义。
我不知道有任何其他方法可以提供测试装饰器或更改 phpunit 使用的大多数其他类。
即使如此,您想要更改测试执行顺序的方式似乎也行得通,但我不确定它洗牌的效果如何。
实现此目的的另一种方法可能更简单,是创建 PHPUnit_Framework_TestSuite 的子类。随机addTest你的代码。
如果这不起作用,另一种选择是使用 xml 配置文件并从 <file> 构建测试套件。标签并在每次执行之前都有一些代码洗牌这些标签。 Afaik phpunit 不会以任何方式对它们进行排序,因此执行将是随机的
或者您是否真的想看看当您执行大量不应按错误顺序更改任何内容的操作时是否会出现严重错误?
我问你是为了防止你没有考虑过 --process-isolation然而。 (我假设你有,但问不会伤害你,可能会节省你一些时间和精力 :) )
当您使用一组新的全局变量运行每个测试时,您至少会发现所有测试的相互依赖性,而这只是一个 cli 开关,以确保您套件中的每个测试都能独立运行。
关于php - 扩展 PHPUnit : adding a decorator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8142920/
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我想这样组织C源代码:+/||___+ext||||___+native_extension||||___+lib||||||___(Sourcefilesarekeptinhere-maycontainsub-folders)||||___native_extension.c||___native_extension.h||___extconf.rb||___+lib||||___(Rubysourcecode)||___Rakefile我无法使此设置与mkmf一起正常工作。native_extension/lib中的文件(包含在native_extension.c中)将被完全忽略。
我有一个要在我的Rails3项目中使用的数组扩展方法。它应该住在哪里?我有一个应用程序/类,我最初把它放在(array_extensions.rb)中,在我的config/application.rb中我加载路径:config.autoload_paths+=%W(#{Rails.root}/应用程序/类)。但是,当我转到railsconsole时,未加载扩展。是否有一个预定义的位置可以放置我的Rails3扩展方法?或者,一种预先定义的方式来添加它们?我知道Rails有自己的数组扩展方法。我应该将我的添加到active_support/core_ext/array/conversion
我想编写一个ruby脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"
这个问题有两个部分。在RubyProgrammingLanguage一书中,有一个使用模块扩展字符串对象和类的示例(第8.1.1节)。第一个问题。为什么如果您使用新方法扩展类,然后创建该类的对象/实例,则无法访问该方法?irb(main):001:0>moduleGreeter;defciao;"Ciao!";end;end=>nilirb(main):002:0>String.extend(Greeter)=>Stringirb(main):003:0>String.ciao=>"Ciao!"irb(main):004:0>x="foobar"=>"foobar"irb(main):
假设我们有A、B、C类。Adefself.inherited(sub)#metaprogramminggoeshere#takeclassthathasjustinheritedclassA#andforfooclassesinjectprepare_foo()as#firstlineofmethodthenrunrestofthecodeenddefprepare_foo#=>prepare_foo()neededhere#somecodeendendBprepare_foo()neededhere#somecodeendend如您所见,我正在尝试将foo_prepare()调用注入
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
显然在Test::Unit中没有assert_false。您将如何通过扩展断言并添加文件config/initializers/assertions_helper.rb来添加它?这是最好的方法吗?我不想修改test/unit/assertions.rb。顺便说一句,我不认为这是多余的。我使用的是assert_equalfalse,something_to_evaluate。这种方法的问题是很容易意外使用assertfalse,something_to_evaluate。这将始终失败,不会引发错误或警告,并且会在测试中引入错误。 最佳答案
这个问题在这里已经有了答案:Unabletoinstallgem-Failedtobuildgemnativeextension-cannotloadsuchfile--mkmf(LoadError)(17个答案)关闭9年前。嘿,我正在尝试在一台新的ubuntu机器上安装rails。我安装了ruby和rvm,但出现“无法构建gemnative扩展”错误。这是什么意思?$sudogeminstallrails-v3.2.9(没有sudo表示我没有权限)然后它会输出很多“获取”命令,最终会出现这个错误:Buildingnativeextensions.Thiscouldtakeawhi
我在引擎样式插件中有一些代码,其中包含一些模型。在我的应用程序中,我想扩展其中一个模型。通过在初始值设定项中包含一个模块,我已经设法将实例和类方法添加到相关模型中。但是我似乎无法添加关联、回调等。我收到“找不到方法”错误。/libs/qwerty/core.rbmoduleQwertymoduleCoremoduleExtensionsmoduleUser#InstanceMethodsGoHere#ClassMethodsmoduleClassMethodshas_many:hits,:uniq=>true#nomethodfoundbefore_validation_on_crea