Ответ 1
Взгляните на setUpBeforeClass()
из раздел 6 документации PHPUnit.
В одно время tearDown вы должны использовать tearDownAfterClass();
.
Оба эти метода должны быть определены в вашем классе как статические методы.
У меня есть класс тестового примера PHPUnit (состоящий из некоторых тестовых функций). Я хотел бы написать функцию oneTimeSetUp()
, которая будет вызываться один раз для всех моих тестов в классе (в отличие от стандартной функции setUp()
, которая вызывается один раз для каждого теста в классе). Другими словами, я ищу эквивалент PHPUnit для аннотации JUnit @BeforeClass
.
Тот же вопрос с функцией oneTimeTearDown()
.
Возможно ли это сделать в PHPUnit?
Взгляните на setUpBeforeClass()
из раздел 6 документации PHPUnit.
В одно время tearDown вы должны использовать tearDownAfterClass();
.
Оба эти метода должны быть определены в вашем классе как статические методы.
Я пришел на эту страницу с тем же вопросом, однако принятый ответ был запущен на всех классах, и для меня это был не правильный ответ.
Если вы похожи на меня, ваш первый "тест интеграции" - это очистить БД и выполнить миграцию. Это позволяет получить базовую базу данных для всех тестов. Я постоянно меняю файлы миграции на этом этапе, поэтому настройка базовой линии действительно является частью всех тестов.
Миграция занимает некоторое время, поэтому я не хочу, чтобы она выполнялась во всех тестах.
Затем мне нужно было создать базу данных, проверяющую каждую часть. Мне нужно написать тест заказа, но сначала мне нужно создать некоторые продукты и проверить это, тогда мне нужно протестировать импорт.
Итак, что я сделал, СУПЕР легко, но не очень хорошо объяснялся в Интернете. Я создал простой тест для настройки базы данных. Затем в вашем файле phpspec.xml добавьте testuite....
<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 Продукты
В конце концов, его тонна легче. Это позволит мне правильно создать мою систему.
Кроме того, я использую laravel 5. При использовании setUpBeforeClass()
у меня возникают проблемы с загрузкой, которые я уверен, что могу исправить, но метод, который я использую выше, работает отлично.
Опция bootstrap
может быть использована в этих случаях.
Вы можете вызвать это из командной строки
phpunit --bootstrap myBootstrap.php
Или поместите его в файл XML, например так:
<phpunit bootstrap="myBootstrap.php">
...
</phpunit>
Расширение на принятый ответ:
Ни один из setUpBeforeClass()
, tearDownAfterClass()
, @beforeClass
, @afterClass
выполняется в контексте объекта (статические методы). Вы можете обойти это ограничение, @before
любой код @before
статическим свойством, например, так:
class MyTest extends PHPUnit\Framework\TestCase
{
private static $ready;
/**
* @before
*/
protected function firstSetUp()
{
if (self::$ready))
return;
/* your one time setUp here */
self::$ready = true;
}
}
Однако он не может быть использован для @after
, потому что невозможно сказать, когда был вызван последний тест.
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;
}
}
}
Последний вариант может быть слушателем теста.