在PHPUnit中,您可以使用@depends
注释使一个测试依赖于其他测试。
是否有可能使整个TestCase依赖于其他TestCase中的测试?或者至少在一个TestCase中进行单项测试依赖于其他TestCase中的测试?
我试过了:
/**
* @depends A::testMethodName
*/
但正如我所料,它不起作用。
更新
具体情况如下:class B
使用class A
。所以我只想在B
(或其中一个测试)的测试没有失败的情况下运行A
。我怎么能这样做?
答案 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。只有那些是你问题的正确答案。不要因为从长远来看只会伤害你的恶意变通办法而堕落。