我有一个PHPUnit测试用例类(由一些测试功能组成)。我想编写一个oneTimeSetUp()
针对该类中的所有测试被调用一次的函数(与标准setUp()
函数不同,该函数针对该类中的每个测试被调用一次)。换句话说,我正在寻找与JUnit@BeforeClass
注解等效的PHPUnit 。
与oneTimeTearDown()
功能相同的问题。
有可能在PHPUnit中这样做吗?
我有一个PHPUnit测试用例类(由一些测试功能组成)。我想编写一个oneTimeSetUp()
针对该类中的所有测试被调用一次的函数(与标准setUp()
函数不同,该函数针对该类中的每个测试被调用一次)。换句话说,我正在寻找与JUnit@BeforeClass
注解等效的PHPUnit 。
与oneTimeTearDown()
功能相同的问题。
有可能在PHPUnit中这样做吗?
Answers:
setUp
,使用带有标志的防护是initialized
有效的,但不能tearDown
这样做,因为您不知道哪个是最后的测试。
我以相同的问题来到此页面,但是所有课程都接受了公认的答案,对我而言,这不是正确的答案。
如果您像我一样,您的第一个“集成测试”是清除数据库,然后运行迁移。这样可以使自己处于所有测试的数据库基准。此时,我一直在不断更改迁移文件,因此设置基准确实是所有测试的一部分。
迁移需要一段时间,所以我不希望它在所有测试中都可以运行。
然后,我需要建立测试每个数据库的数据库。我需要编写一个订单测试,但是首先我需要创建一些产品并进行测试,然后再测试一个导入功能。
因此,我所做的事情超级简单,但在互联网上解释得并不好。我创建了一个简单的测试来设置数据库。然后在您的phpspec.xml文件中添加一个测试套件。
<testsuite name="Products">
<file>tests/in/SystemSetupTest.php</file>
<file>tests/in/ProductTest.php</file>
<file>tests/in/ProductImportTest.php</file>
</testsuite>
并在SystemSetupTest.php中。
class SystemSetupTest extends ApiTester
{
/** @test */
function system_init()
{
fwrite(STDOUT, __METHOD__ . "\n");
self::createEM(); //this has all the code to init the system...
}
}
然后像这样执行它:
phpunit --testsuite产品
最终,它变得容易得多。这将允许我正确地建立我的系统。
另外,我正在使用laravel5。使用时,setUpBeforeClass()
我会遇到自举问题,我确定可以解决,但是上面使用的方法很完美。
./artisan migrate --datebase CONNECTION_NAME && ./vendor/bin/phpunit
。如果您使用Shell的命令历史记录,这没什么大不了的。
setUpBeforeClass()
如果所有测试实际上都包含在一个类中,则这是执行此操作的方法。
但是,您的问题有点暗示您可能会将测试类用作多个测试类的基类。在这种情况下,setUpBeforeClass将在每个之前运行。如果只想运行一次,则可以使用静态变量来保护它:
abstract class TestBase extends TestCase {
protected static $initialized = FALSE;
public function setUp() {
if (!self::$initialized) {
// Do something once here for _all_ test subclasses.
self::$initialized = TRUE;
}
}
}
最后的选择可能是测试监听器。
parent::setUp();
为的第一行public function setUp()
。
该bootstrap
选项可以在这些情况下使用。
您可以从命令行调用它
phpunit --bootstrap myBootstrap.php
或将其放在XML文件中,如下所示:
<phpunit bootstrap="myBootstrap.php">
...
</phpunit>
vendor/autoload.php
用于加载作曲家的依赖项。由于不能存在多个引导文件,因此此解决方案不太适合
vendor/autoload.php
从引导文件中进行请求。例如require __DIR__.'/../vendor/autoload.php';
扩展接受的答案:
的无setUpBeforeClass()
,tearDownAfterClass()
,@beforeClass
,@afterClass
在对象上下文(静态方法)运行。您可以通过@before
使用静态属性来保护任何代码来解决该限制,如下所示:
class MyTest extends PHPUnit\Framework\TestCase
{
private static $ready = false;
/**
* @before
*/
protected function firstSetUp()
{
if (static::$ready))
return;
/* your one time setUp here */
static::$ready = true;
}
}
@after
但是,它不能用于,因为无法说出何时调用了最后一个测试。