phpunit testsuite независимости - PullRequest
10 голосов
/ 13 января 2011

Я запускаю серию тестов в phpunit, которые существуют в отдельных тестовых наборах, список которых контролируется конфигурационным файлом phpunit. Когда тесты запускаются по отдельности (то есть не через файл конфигурации и, следовательно, после тестового набора за раз), они проходят, но при совместном запуске я получаю ошибку.

При ближайшем рассмотрении проблема заключается в том, что каждый из этих наборов тестов загружается в среду (через require_once), и эта структура выполняет некоторую внутреннюю настройку на основе настроек во время require_once. Похоже, что между запуском тестовых наборов, отдельно перечисленных в файле конфигурации phpunit, сохраняются различные вещи. В этом конкретном случае каркас уже рассматривается как загруженный.

Итак - есть ли способ заставить phpunit выполнить последовательность тестовых наборов независимо, то есть эквивалентно запуску phpunit в тестовых наборах по одному за раз? (phpunit запускается cruisecontrol на машине для автотеста и локально разработчиками до подачи заявок.) Я безуспешно пробовал такие опции, как --process-изоляция и --no-globals-backup.

Быстрый пример, иллюстрирующий проблему, - файл 'constant.php':

<?php
if (defined('XYZZY')) define('TEST', 1);
else define('TEST', 2);

набор тестов 'TestOne.php':

<?php
define('XYZZY', "");
require_once('constant.php');
class TestOne extends PHPUnit_Framework_TestCase
{
   public function testOne()
   {
      $this->assertEquals(TEST, 1);
   }
}

аналогичный набор тестов 'TestTwo.php':

<?php
require_once('constant.php');
class TestTwo extends PHPUnit_Framework_TestCase
{
   public function testTwo()
   {
      $this->assertEquals(TEST, 2);
   }
}

и файл конфигурации phpunit:

<phpunit>
  <testsuites>
    <testsuite name="First">
      <file>./TestOne.php</file>
    </testsuite>

    <testsuite name="Second">
      <file>./TestTwo.php</file>
    </testsuite>
  </testsuites>
</phpunit>

Ответы [ 2 ]

1 голос
/ 19 января 2011

Я пытаюсь предоставить вам несколько рабочих примеров --process-изоляция без глобального резервного копирования.

Надеюсь, вы сможете заставить свои тесты работать с ними.Если нет, просто оставьте мне комментарий, и я постараюсь вернуться к вам.

Я протестировал большую часть этого с 3.4.15, и все с HEAD (3.5.x, как ожидается, тоже будет работать)

Самый простой способ сделать это:

<?php
class Test extends PHPUnit_Framework_TestCase
{
    public function testOne()
    {
        define('FOO', 'BAR');
        $this->assertEquals('BAR', FOO);
    }

    public function testTwo()
    {
        define('FOO', 'BAZ');
        $this->assertEquals('BAZ', FOO);
    }
}

и производит:

phpunit --process-изоляция processTest.php

PHPUnit @ package_version @ от Себастьяна Бергманна.

..

Время: 0 секунд, Память: 1,25 МБ

OK (2 теста, 2 утверждения)

Итак, если вы сгруппируете свой тест в комплекты тестов или сможете запустить настройку для каждого тестового набора (в зависимости от того, насколько он дорогой), вы можете сделать что-то простое, например:

<?php
class Test extends PHPUnit_Framework_TestCase
{
    public function setUp() 
    {
        // your bootstrap for testsuite X
        // Maybe put this in a baseclass for that suite ?
    }

    public function testOne()
    {
        $this->assertEquals('BAR', FOO);
    }

Inshort

Убедитесь, что вы запустили свой установочный код ПОСЛЕ того, как вы ввели тест (и изоляцию процесса)

Если все остальное не удалось и вы / мы не можем решить эту проблему:

С расширением runkit (небезопасно ни для чего, даже вблизи производства, используйте в качестве крайней меры), вы можете вызывать такие функции, какrunkit-constant-remove()


Надеюсь, это поможет.Если нет: дайте мне знать

0 голосов
/ 12 апреля 2016

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

В моем случае мне пришлось протестировать некоторый устаревший код, которыйпроверил глобальную константу и выполнил определенное действие, если оно было установлено.Это было достаточно просто, но после define использования константы в одном тесте она сохранялась в остальных тестах.Чтобы изменить это поведение, PHPUnit предоставляет аннотации @ runInSeparateProcess и @ preserveGlobalState .

/**
 * @runInSeparateProcess
 * @preserveGlobalState disabled
 */
public function test_presence_of_constant() {
  define('SOME_OVERRIDE', 'true');
  $result = $this->target->legacyMethod();
  $this->assertEquals('thereWasSomeOverride', $result);
}

Это хорошо работает, если у вас есть только несколько тестов, которые должны выполняться изолированно.

...