#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
, но вы, вероятно, уже проверили это.