Я писал несколько модульных тестов и решил попробовать Devel::Cover. Я вижу кое-что, что не могу объяснить, просматривая отчет об условном покрытии, включающий использование операторов «ИЛИ» (||
) и «Определенное-ИЛИ» (//
).
Это базовый код, который работает как положено:
use strict;
use warnings;
use 5.026;
my($DEF_MIN) = 1;
our($DEF_MAX) = 10;
sub test
{
my($hashref) = @_;
$hashref ||= {};
my($min) = $hashref->{'min'} || 1;
my($max) = $hashref->{'max'} // 10;
say qq(MIN: $min / MAX: $max);
return;
}
test();
test({});
test({ min => 14 });
test({ max => 14 });
test({ min => 10, max => 14 });
Когда я запускаю это, я получаю следующий отчет о состоянии:
Примерно то, что я ожидал.
Если я внесу эти изменения:
my($min) = $hashref->{'min'} || $DEF_MIN;
my($max) = $hashref->{'max'} // $DEF_MAX;
то вместо этого я получаю этот отчет:
Почему вместо просто столбца A
заменены столбцы A
и B
? Как я могу завершить покрытие или пометить его как не покрываемое?
Как можно видеть, не имеет значения, использую ли я ||
или //
, и не имеет значения, является ли правая часть лексической или пакетной переменной.
Вероятное решение, т.е. результат логической операции
Следующее определяет работу ||
:
Ваш тест охватывает оба этих пути. В рамках этой модели у вас будет полное покрытие. Однако Devel::Cover использует другую модель.
Выражение «полностью покрыто» учитывается только в том случае, если во время теста были посещены все три пути. Это имеет смысл в логическом контексте, но здесь ||
используется вне логического контекста.
Поскольку вы не запустили свой код с ложным значением $DEF_MIN
, первый путь не был посещен, и покрытие считается неполным.
Когда операнд является литералом, он исключает путь, по которому он ожидал бы, что истинный литерал окажется ложным, поскольку его невозможно охватить, и удаляет его. (То же самое происходит, когда он ожидает, что ложный литерал будет истинным.) Вот почему при использовании литерала на один столбец меньше.
Это имеет большой смысл - спасибо. Есть ли способ пометить его как необнаружимый?
Я подозреваю, что использование константы (use constant DEF_MIN => ...;
) решит проблему.
Если кто-нибудь знает, что означает заголовок столбца
dec
?