Что возвращает Xdebug в PHP?

Этот код с PHP/Xdebug (с использованием Xdebug 2.2.1 и PHP 5.4 в Windows 7 x64, также я добавил счетчик строк для удобства чтения):

1: xdebug_start_code_coverage();
2:
3: for ($ii = 0; $ii < 3; ++$ii)
4:    $x = time();
5:
6: if (false)
7:    echo "Never executed.";
8:
9: echo var_dump(xdebug_get_code_coverage());

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

array (size=1)
  '..\testpage.php' => 
    array (size=4)
      3 => int 1
      4 => int 1
      7 => int 1
      9 => int 1

В документации на сайте Xdebug говорится:

«Значение в элементах представляет собой общее количество выполненных единиц исполнения в этой строке».

Источник: http://www.xdebug.com/docs/code_coverage

Так что, видимо, вывод неверный. Строки 3 и 4 должны были быть выполнены три раза, тогда как Xdebug сказал 1 соответственно. Строка 6 должна была быть выполнена один раз, у Xdebug вообще не было поговорки. Строка 7 определенно не должна была выполняться, но Xdebug сказал, что она выполнялась один раз. Следует сказать, что вывод остается одинаковым с фигурными скобками или без них.

По этому адресу: http://xdebug.org/archives/xdebug-general/0377.html

.. Дерика Ретанса поймали на высказывании (7 лет назад!), что документация почему-то неверна (и до сих пор так и есть), что Xdebug возвращает только -1, 0 или 1. Однако, как показывает мой пример, Xdebug возвращает 1 сразу и сфальсифицированный счетчик, кажется, делает его выбор произвольным. Даже если бы Xdebug вернул -1, 0 или 1, я бы не знал, что говорят эти значения.

Итак, у кого-нибудь из вас, элитных кодеров, есть идея? И если с Xdebug здесь что-то серьезно не так, значит ли это, что я не могу доверять никаким другим приложениям и плагинам, используемым для профилирования и покрытия кода, которые, в свою очередь, используют Xdebug? Я думаю о Phing и PHPUnit, что кажется обычным браком.

Кроме того, если вы хотите уточнить некоторые вопросы по этому вопросу; если Xdebug неисправен и, следовательно, все зависимые приложения, что вы используете для отчетов о покрытии кода в PHP?

EDIT: выходные данные, перечисленные выше с использованием того же примера кода, не изменятся, если я отправлю аргументы XDEBUG_CC_UNUSED или XDEBUG_CC_DEAD_CODE в качестве аргументов для xdebug_start_code_coverage. Я начинаю думать, что Xdebug вообще не работает для покрытия кода, не в моей системе.


person Martin Andersson    schedule 22.09.2012    source источник
comment
Может быть, синтаксический анализатор PHP все еще должен прочитать его и сгенерировать для него собственный код, даже если он не будет выполнен?   -  person Cole Johnson    schedule 23.09.2012
comment
Коул, держу пари, ты думаешь о строке 7, и да, это может быть так. Но разве Xdebug не был бы совершенно бесполезен, если бы не мог объяснить такие вещи? И еще, есть проблема строк 3, 4 и 6.   -  person Martin Andersson    schedule 23.09.2012
comment
Я никогда не использовал Xdebug, поэтому не могу дать однозначный ответ, но согласно ( digipedia.pl/usenet/thread/15739/883 ) похоже, что на самом деле он не возвращает количество раз, которое строка должна выполнить.   -  person kennypu    schedule 23.09.2012
comment
kennypu, во втором URL-адресе, который вы можете найти в моем посте, вы увидите, что Дерик говорит именно это. Предполагается, что Xdebug возвращает -1, 0 или 1. Но я не могу полностью понять, что означают эти числа. И в моей системе Xdebug, кажется, возвращает 1 для каждой строки кода из-за некоторого произвольного выбора, делающего Xdebug совершенно бесполезным.   -  person Martin Andersson    schedule 23.09.2012


Ответы (1)


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

XDebug знает только об «утверждениях» и на самом деле не понимает «строки», хотя именно так они отображаются и обсуждаются.

Этот:

1  <?php
2
3  xdebug_start_code_coverage();
4
5  for ($ii = 0; $ii < 3; ++$ii) {
6     $x = time();
7  }
8 
9  if (false) {
10    echo "Never executed.";
11 }
12 
13 echo var_dump(xdebug_get_code_coverage());

производит:

array(1) {
  ["./test.php"]=>
  array(5) {
    [5]  => int(1)
    [6]  => int(1)
    [7]  => int(1)
    [9]  => int(1)
    [13] => int(1)
  }
}

Для получения дополнительной информации см.: Пограничные случаи в руководстве по PHPUnit

и другие вопросы SO:

person willoller    schedule 25.09.2012
comment
Спасибо, виллоллер, ваш комментарий был очень полезен. Но теперь я еще больше запутался. Я воспроизвел ваш код и получил тот же результат. Мне интересно, почему Xdebug говорит, что была выполнена строка 7, а не строка 11 (или это оператор 7 и оператор 11?)? - person Martin Andersson; 25.09.2012
comment
На моем коде 7 выполняется, потому что 6 есть. 11 нет, потому что 10 нет. Конечная цифра } — это проклятие для тех, кто навязчиво стремится к 100% охвату. Чтобы решить эту проблему, phpUnit добавил //@codeCoverageIgnore (?), чтобы вы могли поставить его после фигурных скобок: } //@codeCoverageIgnore. Блех. - person willoller; 25.09.2012