在单元测试课中断言进退两难

dqh*_*cks 11 php unit-testing assert

我想在我的单元测试框架中使用PHP的断言函数.它的优点是能够在错误消息中看到正在评估的表达式(包括注释).

问题是每个包含测试的方法可能有多个assert语句,我想跟踪已经运行了多少实际断言语句.assert没有给我一个方法来计算它运行了多少次,只计算它失败了多少次(在故障回调中).

我试图将assert语句抽象为一个函数,以便我可以添加一个计数机制.

private function assertTrue($expression) {
    $this->testCount++;
    assert($expression);
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为表达式中的任何变量现在都超出了范围.

$var = true;
$this->assertTrue('$var == true'); // fails
Run Code Online (Sandbox Code Playgroud)

关于如何在我的单元测试中使用断言同时能够计算实际测试数量的任何建议?

我提出的两个想法是让用户自己计算

$this->testCount++;
assert('$foo');
$this->testCount++;
assert('$bar');
Run Code Online (Sandbox Code Playgroud)

或者让用户在每个测试方法中只放置一个断言(然后我可以计算运行的方法的数量).但这些解决方案都不是非常可执行的,并且使编码更加困难.有关如何实现这一目标的任何想法?或者我应该从我的测试框架中剥离assert()?

eri*_*sco 1

您受到以下事实的限制:assert()必须在您正在测试的变量所在的同一范围内调用。据我所知,剩下的解决方案需要额外的代码,在运行时修改源代码(预处理),或者在 C 级别扩展 PHP 的解决方案。这是我提出的解决方案,涉及额外的代码。

class UnitTest {
    // controller that runs the tests
    public function runTests() {
        // the unit test is called, creating a new variable holder
        // and passing it to the unit test.
        $this->testAbc($this->newVarScope());
    }

    // keeps an active reference to the variable holder
    private $var_scope;

    // refreshes and returns the variable holder
    private function newVarScope() {
        $this->var_scope = new stdClass;
        return $this->var_scope;
    }

    // number of times $this->assert was called
    public $assert_count = 0;

    // our assert wrapper
    private function assert($__expr) {
        ++$this->assert_count;
        extract(get_object_vars($this->var_scope));
        assert($__expr);
    }

    // an example unit test
    private function testAbc($v) {
        $v->foo = true;
        $this->assert('$foo == true');
    }
}
Run Code Online (Sandbox Code Playgroud)

这种方法的缺点:单元测试中使用的所有变量都必须声明为 ,而$v->*不是$*,而在断言语句中编写的变量仍然编写为$*。其次,发出的警告assert()不会报告被$this->assert()调用的线路号。

为了获得更高的一致性,您可以将该assert()方法移至变量持有者类,这样您就可以考虑在测试台上运行的每个单元测试,而不是进行某种神奇的断言调用。