是否可以使用PHPUnit @depends而不在相关案例之间调用tearDown和setUp?

时间:2013-08-25 05:39:04

标签: php phpunit

例如,test1中的操作在外部存储数据* test2然后执行断言,但tearDown删除该数据,从而中断test2。无法从tearDown删除缓存删除,因为其他测试依赖于它。这个问题是询问是否有一种方法可以在保持@depends的功能的同时跳过依赖情况之间的setUp / tearDown(如果第一次测试失败而不是第二次测试失败,则跳过第二次测试)。

public function tearDown() {
    // delete cache
}

// verify the expected data was retrieved from an uncached source
public function test1() {
    $sut = new SystemUnderTest();
    $data = $sut->getDataAndCache();
    $this->assertEquals('expected', $data);
    return $sut;
}

// verify the expected data was cached
/** @depends test1 */
public function test2($sut) {
    $this->assertEquals('expected', $sut->getCache());
}

*我们将调用这些集成测试,因为它们与外部系统交互。

4 个答案:

答案 0 :(得分:14)

在设置方法中,您可以检查测试是否有hasDependencies(),然后跳过设置步骤:

public function setUp()
{
    if (!$this->hasDependencies()) {
        // do setup tasks 
    }
}

答案 1 :(得分:1)

有几种选择。

第一个是将这两个测试隔离成一个单独的测试类。这样你在其他课堂上的泪水就不会干涉了。

您仍然可能希望在测试后删除缓存。好吧,测试缓存删除可能是一个步骤。但PHPUnit还提供了两个静态方法,它们在测试类开始测试之前运行,并且在类中的所有测试运行之后运行:setUpBeforeClass()tearDownAfterClass()(参见http://phpunit.de/manual/3.7/en/fixtures.html)。

另一方面,最简单的方法是将两种测试方法合并为一个功能。您通过命名函数getData * AND * Cache来违反单一责任原则已经遇到了一些麻烦,因此将测试分成两个函数几乎没有什么好处。

答案 2 :(得分:0)

我的一个想法是使用is_depends之类的静态字段,test1中设置为true,test2setUp中设置为tearDown在运行之前会检查is_depends的值。 E.g。

private static is_depends;

public function setUp() {
    if (self::$is_depends) return;
    // do setup that shouldn't be done between dependencies
}

public function tearDown() {
    if (self::$is_depends) return;
    // delete cache
}

// verify the expected data was retrieved from an uncached source
public function test1() {
    $sut = new SystemUnderTest();
    $data = $sut->getDataAndCache();
    $this->assertEquals('expected', $data);
    self::$is_depends = true;
    return $sut;
}

// verify the expected data was cached
/** @depends test1 */
public function test2($sut) {
    $this->assertEquals('expected', $sut->getCache());
    self::$is_depends = false;
}

有更好的方法吗?

答案 3 :(得分:0)

另一种选择是在两个测试中执行大部分安排和行动步骤。那么就不需要在test1和test2之间维持外部状态。如果test1失败,@depends注释仍会导致跳过test2。如果排列和行为步骤更复杂,可以将它们提取到一个单独的方法,并通过两个测试调用。

以下是更新的test2方法的示例(使用原始问题中的test1):

// verify the expected data was cached
/** @depends test1 */
public function test2($sut) {
    $data = $sut->getDataAndCache();
    $this->assertEquals('expected', $sut->getCache());
}