Подтвердить что ты не робот

PHPUnit: Как создать функцию, которая будет вызываться один раз для всех моих тестов?

У меня есть класс тестового примера PHPUnit (состоящий из некоторых тестовых функций). Я хотел бы написать функцию oneTimeSetUp(), которая будет вызываться один раз для всех моих тестов в классе (в отличие от стандартной функции setUp(), которая вызывается один раз для каждого теста в классе). Другими словами, я ищу эквивалент PHPUnit для аннотации JUnit @BeforeClass.

Тот же вопрос с функцией oneTimeTearDown().

Возможно ли это сделать в PHPUnit?

4b9b3361

Ответ 1

Взгляните на setUpBeforeClass() из раздел 6 документации PHPUnit.

В одно время tearDown вы должны использовать tearDownAfterClass();.

Оба эти метода должны быть определены в вашем классе как статические методы.

Ответ 2

Я пришел на эту страницу с тем же вопросом, однако принятый ответ был запущен на всех классах, и для меня это был не правильный ответ.

Если вы похожи на меня, ваш первый "тест интеграции" - это очистить БД и выполнить миграцию. Это позволяет получить базовую базу данных для всех тестов. Я постоянно меняю файлы миграции на этом этапе, поэтому настройка базовой линии действительно является частью всех тестов.

Миграция занимает некоторое время, поэтому я не хочу, чтобы она выполнялась во всех тестах.

Затем мне нужно было создать базу данных, проверяющую каждую часть. Мне нужно написать тест заказа, но сначала мне нужно создать некоторые продукты и проверить это, тогда мне нужно протестировать импорт.

Итак, что я сделал, СУПЕР легко, но не очень хорошо объяснялся в Интернете. Я создал простой тест для настройки базы данных. Затем в вашем файле 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() у меня возникают проблемы с загрузкой, которые я уверен, что могу исправить, но метод, который я использую выше, работает отлично.

Ответ 3

Опция bootstrap может быть использована в этих случаях.

Вы можете вызвать это из командной строки

phpunit --bootstrap myBootstrap.php

Или поместите его в файл XML, например так:

<phpunit bootstrap="myBootstrap.php">
...
</phpunit>

Ответ 4

Расширение на принятый ответ:

Ни один из 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, потому что невозможно сказать, когда был вызван последний тест.

Ответ 5

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;
    }
  }

}

Последний вариант может быть слушателем теста.