Intereting Posts
(php oop) статический метод vs нет статического метода PHP: регулярное выражение для игнорирования скрытых кавычек в кавычках php merge json массивы Вставьте данные в базу данных из массива checkbox с помощью Codeigniter проверка проверки на 3 поля для проверки дублирования Msgstr "Не получать доступ к суперглобальному массиву $ _SERVER прямо" на Netbeans 7.4 для PHP Fontawesome шрифты терпят неудачу после активов: установить и уснуть: дамп Запуск нескольких запросов в MySQL без использования подзапроса Как гиперссылка на веб-адрес или не веб-адрес в php Включить php на mac snow leopard PHP – сравнение даты, проверка, если в течение последнего часа Поток как html5 аудио или конвертировать .amr в .ogg Получение выбранных значений из формы множественного выбора в Laravel Как я могу использовать хеширование MD5 для паролей в Laravel? Использование Md5 для хэша паролей в компоненте Auth Cakephp 2.x

Достижение 100% охвата кода с помощью PHPUnit

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

Смотрите скриншот:

введите описание изображения здесь

Поскольку последняя строка тестируемого метода – это return , конечная строка (которая является только закрывающей скобкой) отображается как никогда не исполняемая, и, как следствие, весь метод помечен как не выполненный в обзоре. (Или это, или я не читаю отчет правильно.)

Полный метод:

 static public function &getDomain($domain = null) { $domain = $domain ?: self::domain(); if (! array_key_exists($domain, self::$domains)) { self::$domains[$domain] = new Config(); } return self::$domains[$domain]; } 

Есть ли причина для этого, или это сбой?

(Да, я прочитал, как получить 100% покрытие кода с помощью PHPUnit , в другом случае, хотя и аналогичный.)

Редактировать:

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

Edit2:

Я запускаю: PHPUnit 3.6.7, PHP 5.4.0RC5, XDebug 2.2.0-dev на OS X

Во-первых: 100% -ый охват кода – отличный показатель, к которому нужно стремиться . Это просто не всегда достижимо с разумным количеством усилий, и это не всегда важно делать это 🙂

Проблема заключается в том, что xDebug сообщает PHPUnit, что эта строка является исполняемой, но не распространяется.

Для простых случаев xDebug может сказать, что линия НЕ доступна, поэтому вы получаете 100% -ый охват кода там.

См. Простой пример ниже.


2-е обновление

Проблема теперь исправлена xDebug bugtracker поэтому создание новой версии xDebug решит эти проблемы 🙂

Обновление (см. Ниже проблемы с php 5.3.x)

Поскольку вы используете PHP 5.4 и DEV-версию xDebug, я их установил и протестировал. Я сталкиваюсь с теми же проблемами, что и вы, с тем же результатом, о котором вы прокомментировали.

Я не уверен на 100%, если проблема исходит из php-code-coverage (модуль phpunit) для xDebug. Это также может быть проблемой с xDebug dev.

Я подал ошибку с php-code-coverage и мы выясним, откуда эта проблема.


Для проблем с PHP 5.3.x:

Для более сложных случаев эта CAN не работает.

Для кода, который вы показали, я могу сказать, что «Он работает для меня» ( сложный пример ниже ).

Возможно, обновите xDebug и PHPUnit Versions и повторите попытку.

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

Удаление ?: Операторы и другие однострочные многозадачные вещи также могут помочь.

Существует постоянный рефакторинг в xDebug, чтобы избежать большего количества случаев, насколько мне известно. xDebug однажды хочет иметь возможность «охвата заявлений», и это должно исправить многие из этих случаев. Пока что здесь мало что можно сделать

В то время как //@codeCoverageIgnoreStart и //@codeCoverageIgnoreEnd получит эту «покрытую» строку, она выглядит действительно уродливой и обычно делает хуже, чем хорошо.

В другом случае, когда это происходит, см. Вопрос и ответы от:

what-to-do-when-project-coding-standards-conflicts-with-unit-test-code-coverage


Простой пример:

 <?php class FooTest extends PHPUnit_Framework_TestCase { public function testBar() { $x = new Foo(); $this->assertSame(1, $x->bar()); } } <?php class Foo { public function bar() { return 1; } } 

производит:

 phpunit --coverage-text mep.php PHPUnit 3.6.7 by Sebastian Bergmann. . Time: 0 seconds, Memory: 3.50Mb OK (1 test, 1 assertion) Generating textual code coverage report, this may take a moment. Code Coverage Report 2012-01-10 15:54:56 Summary: Classes: 100.00% (2/2) Methods: 100.00% (1/1) Lines: 100.00% (1/1) Foo Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 1/ 1) 

Комплексный пример:

 <?php require __DIR__ . '/foo.php'; class FooTest extends PHPUnit_Framework_TestCase { public function testBar() { $this->assertSame('b', Foo::getDomain('a')); $this->assertInstanceOf('Config', Foo::getDomain('foo')); } } <?php class Foo { static $domains = array('a' => 'b'); static public function &getDomain($domain = null) { $domain = $domain ?: self::domain(); if (! array_key_exists($domain, self::$domains)) { self::$domains[$domain] = new Config(); } return self::$domains[$domain]; } } class Config {} 

производит:

 PHPUnit 3.6.7 by Sebastian Bergmann. . Time: 0 seconds, Memory: 3.50Mb OK (1 test, 2 assertions) Generating textual code coverage report, this may take a moment. Code Coverage Report 2012-01-10 15:55:55 Summary: Classes: 100.00% (2/2) Methods: 100.00% (1/1) Lines: 100.00% (5/5) Foo Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 5/ 5) 

Большая часть проблемы здесь заключается в настойчивости в получении 100% -ного охвата выполнения «строк». (Менеджеры подобны этой идее, это простая модель, которую они могут понять). Многие строки не являются «исполняемыми» (пробелы, пробелы между объявлениями функций, комментариями, декларациями, «чистым синтаксисом», например, закрытие «}» объявления коммутатора или класса или сложные инструкции, разделенные на несколько строк исходного кода).

То, что вы действительно хотите знать, – это весь исполняемый код? Это различие кажется глупым, но приводит к решению. XDebug отслеживает то, что выполняется, ну, по номеру строки, и ваша схема на основе XDebug, таким образом, сообщает диапазоны выполненных строк. И вы получаете проблемы, обсуждаемые в этой теме, в том числе решения klunky, связанные с необходимостью комментировать код комментариями «не считайте меня», помещая «}» в ту же строку, что и последний исполняемый оператор, и т. Д. На самом деле программист не является желая сделать это, не говоря уже об этом.

Если определить исполняемый код в качестве кода, который может быть вызван или управляется условным (то, что люди-компиляторы называют «базовыми блоками»), и отслеживание покрытия выполняется таким образом, тогда макет кода и глупых случаев просто исчезают. Инструмент тестового покрытия этого типа собирает то, что называется «охват филиалов», и вы можете получить или не получить 100% «охват филиалов» буквально, выполнив весь исполняемый код. Кроме того, он подберет те забавные случаи, когда у вас есть условное выражение в строке (используя «x? Y: z») или у вас есть два обычных оператора в строке (например,

  if (...) { if (...) stmt1; else stmt2; stmt3 } 

Поскольку XDebug отслеживает по строкам, я верю, что он рассматривает это как один элемент и рассматривает его охват, если контроль попадает на линию, когда на самом деле есть 5 частей для фактического тестирования.

Наш инструмент тестирования PHP Test Coverage реализует эти идеи. В частности, он понимает, что код, следующий за оператором return, не является исполняемым, и он скажет вам, что вы его не выполнили, если он не пуст. Это заставляет оригинальную проблему OP просто исчезнуть. Нет больше игр, чтобы получить «реальные» номера покрытия.

Как и во всех вариантах, иногда есть недостаток. Наш инструмент имеет компонент инструмента кода, который работает только под Windows; инструментальный PHP-код может работать в любом месте, а обработка / отображение выполняется с помощью независимой от платформы Java-программы. Так что это может быть неудобно для OS OS OS. Инструментарий отлично работает с файловыми системами, совместимыми с NFS, поэтому он мог бы, возможно, запустить инструментарий на ПК и обработать его файлы OSX.

Эта конкретная проблема была поднята кем-то, кто пытался подтолкнуть его номера покрытия; проблема была ИМХО искусственной и может быть излечена, обойдя искусственность. Есть еще один способ увеличить количество ваших номеров, не набирая больше тестов, и это поиск и удаление дублирующего кода. Если вы удаляете дубликаты, есть меньше кода для тестирования и тестирования одной (не) копии в тестах эффектов (теперь несуществующей другой копии), поэтому легче получить более высокие цифры. Вы можете прочитать об этом подробнее.

Что касается вопроса о распространении кода оператора switch, просто добавьте случай «по умолчанию», который ничего не делает, и вы получите полный охват.

Вот что нужно сделать, чтобы получить оператор switch 100%:

Убедитесь, что есть хотя бы один тест, который отправляет случай, который не существует.

Итак, если у вас есть:

 switch ($name) { case 'terry': return 'blah'; case 'lucky': return 'blahblah'; case 'gerard': return 'blahblah'; } 

убедитесь, что хотя бы одно из ваших тестов отправляет имя, которое не является ни terry ни lucky ни gerard .