Код выполняется перед инициализацией PHPUnit

#php #unit-testing #phpunit #code-coverage

#php #модульное тестирование #phpunit #покрытие кода

Вопрос:

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

 bool(true)
PHPUnit 3.5.5 by Sebastian Bergmann.

...
  

Это странно. Как возможно, что строка выполняется до инициализации PHPUnit? Я полагаю, что именно по этой причине покрытие кода говорит, что строка не покрыта.

Какие-либо подсказки?

РЕДАКТИРОВАТЬ: вот некоторый код. Это IRC-фреймворк, который использует общую библиотеку Doctrine для чтения аннотаций, а также использует компоненты ClassLoader и EventDispatcher Symfony. Это инкриминируемый метод:

 /**
 * Returns this module's reflection.
 * 
 * @return ReflectionClass
 * @access public
 */
static public function getReflection()
{
    // The var_dump() displaying bool(false) is executed before PHPUnit, while the other
    // ones are correctly executed.
    var_dump(is_null(self::$reflection));

    if (null === self::$reflection) {
        // This line is reported as uncovered, but it must be executed since I'm
        // accessing the reflection!
        self::$reflection = new ReflectionClass(get_called_class());
    }

    return self::$reflection;
}
  

Что вы думаете?

Комментарии:

1. Как вы можете сказать, что это до инициализации PHPUnits? Это происходит только перед записью выходных данных PHPUnit (TextUI).

2. @hakre Тогда почему все остальные var_dump() (этот метод выполняется много раз в приложении) отображаются после вывода PHPUnit? И почему эта строка не отображается в покрытии кода, даже если она выполнена?

3. Это не связано с вашим вопросом, могу я спросить, почему вы назначаете get_called_class (что является поздней статической привязкой) self::$... , а не static::$... ?

4. Когда getReflection() вызывается get?

5. Он вызывается в другом статическом методе, который возвращает события, к которым приписан модуль. Я должен использовать ReflectionClass , потому что я использую аннотации для подписки на события. Этот последний статический метод вызывается в тестовом примере. Вот почему я не понимаю, что происходит. Что касается поздней статической привязки, это моя ошибка. Я исправлю это. Спасибо.

Ответ №1:

Тогда почему все остальные var_dump() (этот метод выполняется много раз в приложении) отображаются после вывода PHPUnit? И почему эта строка не отображается в покрытии кода, даже если она выполнена?

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

Ответ №2:

Средство доступа должно вызываться вне модульного теста, который инициализируется self::$reflection . После этого все дальнейшие вызовы getReflection() пропускают if блок, чтобы он никогда не считался закрытым. PHPUnit создает экземпляры всех классов тестового примера — по одному для каждого метода тестирования, метода поставщика данных и массива аргументов поставщика данных — перед запуском любого из тестов или отслеживанием покрытия кода. Ищите тестовый пример, который вызывается getReflection() из его конструктора или вне самого класса, где код выполняется при загрузке.

Я забыл, создаются ли тестовые примеры до того, как PHPUnit выводит свою версию, и не могу проверить сейчас, но я считаю, что это так. Другая возможность заключается в том, что вы вызываете getReflection() из bootstrap.php , но вы, вероятно, уже проверили это.