Как я могу получить 100%-е тестовое покрытие в модуле Perl, который использует DBI?

Я немного плохо знаком с Devel:: модуль Покрытия, но нашли это очень полезным в проверке, что я не пропускаю тесты.

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

Редактирование - я должен прояснить, что не говорю, что мне нужно 100%-е покрытие, потому что, поскольку несколько человек указывают, 100%-е покрытие является широким термином, не означает, что мой код является бесплатной ошибкой, и не может всегда быть абсолютно необходимым. Так как я являюсь новым в Devel:: Покрытие, мне интересно знать, почему мой код не является 100%-м покрытием, в случае, если я пропускаю некоторые важные тесты.

Вот вывод из отчета о покрытии:

line  err   stmt   bran   cond    sub    pod   time   code
...
36                                                    sub connect_database {
37             3                    3      1   1126       my $self = shift;
38             3    100                          24       if ( !$self->{dsn} ) {
39             1                                  7           croak 'dsn not supplied - cannot connect';
40                                                        }
41    ***      2            33                   21       $self->{dbh} = DBI->connect( $self->{dsn}, q{}, q{} )
42                                                          || croak "$DBI::errstr";
43             1                                 11       return $self;
44                                                    }
...
line  err      %      l  !l&&r !l&&!r   expr
----- --- ------ ------ ------ ------   ----
41    ***     33      1      0      0   'DBI'->connect($$self{'dsn'}, '', '') || croak("$DBI::errstr")

И вот и пример моего кода, который тестирует эту определенную строку:

my $database = MyModule::Database->new( { dsn => 'Invalid DSN' });
throws_ok( sub { $database->connect_database() }, 
   qr/Can't connect to data source/, 
   'Test connection exception (invalid dsn)' );

Этот тест передает - подключение действительно бросает ошибку и выполняет мой тест "throws_ok".

У меня действительно есть некоторые тесты, которые тестируют на успешное соединение, которое является, почему я думаю, что у меня есть 33%-е покрытие, но если я читаю его правильно, покрытие думает, что я не тестирую "|| карканье" часть оператора. Я думал, что был с тестом "throws_ok", но очевидно я пропускаю что-то.

У кого-либо есть совет относительно того, как я могу протестировать свой DBI-> строка подключения успешно?

Спасибо!

Править:

brian информировал меня к отчету HTML и таблице истинности, которая объясняет, почему строка № 41 не является передающей. Единственная проблема состоит в том, что я не могу выяснить то, что это говорит мне. Я предполагаю, что реальное ядро моего вопроса - то, почему эта определенная строка не передает покрытие.

Вот таблица истинности:

LINE # %  # coverage    # condition
41   # 33 # A | B | dec # 'DBI'->connect($$self{'dsn'}, '', '') || croak("$DBI::errstr")
     #    # 0 | 0 | 0   #
     #    # 0 | 1 | 1   #
     #    # 1 | X | 1   # (THIS LINE IS Green - the rest are red)

Если бы кто-либо мог бы помочь объяснить эту таблицу истинности, я ценил бы ее. Было также упомянуто, что для передачи покрытия у меня должен быть ложный объект базы данных, но я не вполне вижу, как что-либо в результатах покрытия, которые были бы подсказка меня в к этому.

Еще раз спасибо!

6
задан brian d foy 18 March 2010 в 18:22
поделиться

2 ответа

Также не стоит слишком зацикливаться на 100% тестовом покрытии. Целью является полное тестирование вашего приложения, а не получение идеальных оценок в Devel::Cover. См. сообщения Овида на эту тему:

В вашем случае, похоже, вы не покрываете все ветви, поэтому не получаете идеальных оценок. Вам нужны тесты, которые проверяют обе стороны этого ||. Вы получаете 33% покрытия, потому что обрабатываете только треть случаев для этой строки. HTML-отчет от Devel::Cover показывает вам таблицу истинности и то, какие случаи вы пропустили.

Таблица истинности показывает возможные состояния, которые вы должны покрыть для ветвления. 1 показывает истинное состояние, 0 показывает ложное состояние, а X показывает состояние, которого вы не достигнете. Вы должны проверить все комбинации, которые могут выполниться. Поскольку || является оператором замыкания, вам не нужно проверять условия, если одно из них проходит:

 0 || 1     connect to database fails and croak succeeds
 0 || 0     connect to database fails and croak fails (unlikely)
 1 || X     connect to database succeeds, so short circuit

Это немного не связано с вашей конкретной задачей, но я нахожу, что это часто встречается в подобных задачах. Хотя Эффективное программирование на Perl еще только через месяц появится на полках магазинов, Джош МакАдамс потратил довольно много времени на обсуждение внедрения зависимостей в Perl. Если вы испытываете трудности с тестированием кода, то, как правило, у вас проблемы с проектированием. Если вы, например, генерируете объекты базы данных во внутренних подпрограммах, вы загоняете себя в угол. Вот почему тестирование может быть затруднено. Возможно, в вашем случае проблема не в этом, но это повод задуматься.

10
ответ дан 8 December 2019 в 16:01
поделиться

Вы должны имитировать библиотеку DBI (или любую другую внешнюю зависимость), чтобы полностью покрыть ваши модульные тесты.

Вы можете использовать Test :: MockObject или любой другой метод имитации (например, наша компания разработала собственную очень мощную библиотеку имитаций Perl).

Также см. эту статью , посвященную фиксации DBI.

Также убедитесь, что вы используете последнюю версию Devel :: Cover.Однажды я провел 3 дня, борясь с модульным тестом, пока меня не осенило, что ошибка была не в моем коде и не в моем модульном тесте, а в более старой версии Devel :: Cover, которую установила моя компания. Он буквально игнорировал определенные пути кода в случаях «A || B».

5
ответ дан 8 December 2019 в 16:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: