扩展PHPUnit:添加装饰器 上下文

扩展PHPUnit:添加装饰器 上下文,php,phpunit,Php,Phpunit,我最近继承了一个编程良好的PHP应用程序(sarcasm)的开发和维护工作。这个应用程序是基于一个商业软件(我不想说出它的名字),并且在它上面有一个定制层(我们的) 不幸的是,这个应用程序使用了大量的全局和单例(双关语)。我已经为我们覆盖的所有东西构建了测试用例。然而,很多事情都依赖于某些事物的全局状态,这会导致种族状况和各种奇怪的事情 随机测试 为了捕捉这些奇怪的东西(我喜欢这样称呼它们),我构建了一个PHPUnitTestDecorator,[如手册中所述][1]。这个: class PHP

我最近继承了一个编程良好的PHP应用程序(sarcasm)的开发和维护工作。这个应用程序是基于一个商业软件(我不想说出它的名字),并且在它上面有一个定制层(我们的)

不幸的是,这个应用程序使用了大量的全局和单例(双关语)。我已经为我们覆盖的所有东西构建了测试用例。然而,很多事情都依赖于某些事物的全局状态,这会导致种族状况和各种奇怪的事情

随机测试 为了捕捉这些奇怪的东西(我喜欢这样称呼它们),我构建了一个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);
    }
}
它基本上会随机化测试,以确保测试不依赖于可能正确或不正确的全局状态

问题 当测试我的定制装饰器时,问题出现了。我还没有找到任何地方的手册,谷歌,或堆栈溢出如何加载它

在分析代码时,我看到PHPUnit本身正在
TextUI\u TestRunner::doRun()
方法中实例化
RepeatedTest
decorator。我知道我可以将TestRunner子类化,重写
doRun()
,安排创建我的decorator,然后以我的decorator实例为参数调用
parent::doRun()
,重写
TextUI\u命令
,并创建一个新的CLI脚本来使用我的东西而不是内置的东西

在我(重新)发明轮子之前,我只是想知道,是否可以在不子类化TestRunner的情况下加载自定义装饰程序?


谢谢。

对于当前的PHPUnit版本,在大多数情况下插入您自己的代码并不容易。唯一提供互换性的是TestRunner,您所描述的对我来说是有意义的

我不知道有任何其他方法可以提供测试装饰器或更改phpunit使用的大多数其他类

您想要更改测试执行顺序的方式似乎是可行的,即使如此,我也不确定它将如何洗牌


实现这一点的另一种方法是创建
PHPUnit\u Framework\u TestSuite
随机
addTest
您的代码的子类


如果这不起作用,另一种选择是使用xml配置文件,从
标记构建测试套件,并在每次执行之前对这些标记进行一些代码洗牌。Afaik phpunit不会以任何方式对它们进行排序,因此执行将是随机的


您是否希望查看其上的每个测试是否都有效,并希望找到相互依赖的测试? 或者你真的想知道,当你做了很多不应该以错误的顺序改变任何事情的事情时,事情是否会发生可怕的破坏

我这样问是为了以防万一您还没有考虑到进程隔离。(我想你已经问过了,但是问不会有什么坏处,可能会帮你节省一些时间和精力:)


当您使用一组新的全局变量运行每个测试时,您至少会找到所有测试的相互依赖关系,而这只需要一个cli开关,就可以确保套件中的每个测试都能独立工作。

谢谢您的回答。是的,我考虑过进程隔离,但这是一个非常缓慢的过程。我不能每次运行测试套件都等10分钟。@netcoder我建议设置一个构建,每晚运行一次测试套件,并使用进程隔离来捕获奇怪的测试套件,并在日常使用中以正常方式使用它。我想说的是,在以太过程中,你不想为了找到随机数而洗牌,因为你不希望你的测试套件“随机”中断。我已经得到了一个测试套件,它通过进程隔离运行了一个多小时(耶!),并且每晚运行一次,这真的减轻了使用它的痛苦。好吧,既然装饰师真的将所有测试随机化(例如:顺序可以变成C::a,B::C,C::B,a::B,B::a),它并不是真的随机中断,它只是中断。至于晚上,这是个好主意,我会检查一下是否能让it部门来帮我。然而,这里的问题是真正了解是否可以在不覆盖PHPUnit的一半的情况下添加decorator。但从你的答案来看,这是做不到的,我必须说我觉得这很讽刺。是的,也许其他人有办法做到这一点,比创建TestRunner的子类更好。我只是想让你的问题以另一种方式消失/确保你知道这个选项:)我们在测试干扰方面也有问题——一个测试改变了全局状态,以至于a)中断另一个测试,或者b)隐藏另一个测试中的失败。我希望能够为每次运行洗牌测试。进程隔离不会发现第一种类型的干扰。