PHPUnit中两个TestCase类之间的相关测试

时间:2012-01-12 13:11:13

标签: php unit-testing phpunit

在PHPUnit中,您可以使用@depends注释使一个测试依赖于其他测试。 是否有可能使整个TestCase依赖于其他TestCase中的测试?或者至少在一个TestCase中进行单项测试依赖于其他TestCase中的测试?

我试过了:

/**
 * @depends A::testMethodName
 */

但正如我所料,它不起作用。

更新

具体情况如下:class B使用class A。所以我只想在B(或其中一个测试)的测试没有失败的情况下运行A。我怎么能这样做?

4 个答案:

答案 0 :(得分:13)

利用依赖关系非常重要!所提到的松耦合用于实际应用架构,不适用于单元测试用例。如果在功能执行中内置逻辑依赖关系,那么利用这些依赖关系总是一个好主意。

使用test doubling适用于SOA,其中依赖关系无法映射到黑盒子中的特定故障 AND 服务不可靠。这不适用于跨应用程序类。

You definitely would want to use this type of functionality如果测试类之间存在逻辑依赖关系。来自单元测试的The concept to be grasped是能够立即将缺陷隔离到特定组件。

此功能在PHPUnit v 3.7.13上可用。但是,唯一可行的方法是在包含两个TestCase类的目录上运行PHPUnit。

例如,使用此文件夹结构

- application\dep
   |- BTest.php
   |- CTest.php

班级......

class BTest extends PHPUnit_Framework_TestCase
{
    /**
     * @depends CTest::testADomino
     */
    public function testDominoDependent()
    {
        $this->assertTrue(true);
    }
}

和...

class CTest extends PHPUnit_Framework_TestCase
{
    public function testADomino()
    {
        $this->assertTrue(false);
    }
}

这是结果

C:\Users\Josh>C:\xampp\php\phpunit.bat "C:\xampp\htdocs\BeAgile\applications\sto
cklogger\tests\dep"
PHPUnit 3.7.13 by Sebastian Bergmann.

SF

Time: 0 seconds, Memory: 2.00Mb

There was 1 failure:

1) CTest::testADomino
Failed asserting that false is true.

C:\xampp\htdocs\BeAgile\applications\stocklogger\tests\dep\CTest.php:7

FAILURES!
Tests: 1, Assertions: 1, Failures: 1, Skipped: 1.

您可以将两个测试用例类放在同一个文件中,但结构很差。没有必要“确保”一个测试在另一个之前运行。

作为敏捷教练,我认为测试在大型组织中经常加倍,在这些组织中,当其他组件进行导致测试失败的更改时,专门的细分市场希望避免构建失败。这当然会破坏单元测试的整个目的,即在最终用户之前识别组件故障。

答案 1 :(得分:6)

没有内置的方法可以做到这一点,但是任何数量的测试依赖于其他一些测试传递也不难。您必须确保在ATest之前执行BTest

class ATest extends PHPUnit_Framework_TestCase {
    public static $passed = false;

    function testThatMustPass() {
        // ... the actual test ...
        // ok, test passed
        self::$passed = true;
    }
}

class BTest extends PHPUnit_Framework_TestCase {
    function testThatDependsOnA() {
        if (!ATest::$passed) {
            self::markTestSkipped('A failed');
        }
    }
}

测试依赖于整个测试用例也是可能的。

class ATest extends PHPUnit_Framework_TestCase {
    public static $passed = true;

    protected function onNotSuccessfulTest(Exception $e)
        self::$passed = false;
        parent::onNotSuccessfulTest($e);
    }
}

您可以通过跟踪失败的测试名称来改进这些,这样您就可以依赖每个案例的测试子集。

答案 2 :(得分:1)

对于仍然对这个问题感到疑惑的人,可以使用@Depends引用而不是@depends。似乎小写版本只能以跨功能的方式使用,而大写字母可以逐级使用。

/**
 * @Depends FirstTest::testMethodName
 */

确保依赖的测试类将在依赖它的实际测试类之前运行。您可以在phpunit.xml testsuite 中声明测试类的顺序。

<phpunit
        bootstrap="./vendor/autoload.php"
        colors="true"
>
    <testsuites>
        <testsuite name="App\\Tests">
            <directory>./test</directory>
        </testsuite>
        <testsuite name="sample-testsuite">
         <directory>./test/FirstTest.php</directory>
         <directory>./test/SecondTest.php</directory>
        </testsuite>
    </testsuites>

    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">src</directory>
        </whitelist>
    </filter>
</phpunit>

然后,您运行测试套件。

./vendor/bin/phpunit --testsuite sample-testsuite

我仅使用 6.1.0 + 版本进行了测试。您可以查看有关此问题here的讨论。谢谢:)

答案 3 :(得分:-1)

听起来你的测试是综合性的,而且如果不同的子集被破坏则会失败。我鼓励你查看Mocks和Stubs。只有那些是你问题的正确答案。不要因为从长远来看只会伤害你的恶意变通办法而堕落。

http://phpunit.de/manual/3.6/en/test-doubles.html