2015-07-15 5 views
2

Я пытаюсь создать модульные тесты для своего сценария, используя библиотеки Test::More и Test::Exception.
Я прочитал эти статьи How to test for exceptions in Perl и Test::Exception.
В первой статье описывается, что мне нужно, чтобы проверить мою подпрограмму для исключения или смерти.
Но я не могу заставить его работать. Рассмотрим некоторые примерыЕд. Тест для тестирования ошибок и умирания скрипта/модуля Perl

#!/usr/bin/env perl 
    package My::SuperModule; 
    use strict; 
    use warnings; 
    use Net::Ping; 
    use Utils::Variables::Validator; 

    sub new 
    { 
     die "Hello"; 
     #Getting class name from, stored in $_[0] 
     my $class = shift; 
     #Getting user name from arguments $_[1] 
     my $user_name = shift; 
    ........ 
} 

, и мой тестовый файл

use warnings; # this warns you of bad practices 
    use strict;  # this prevents silly errors 
    use Test::More; # for the is() and isnt() functions 
    use Test::Exception; 
    do './My/SuperModule.pm'; 
    #Testing module loading 
    print "=================Testing module loading=================\n"; 
    use_ok ('My::SuperModule'); 
    use_ok ('My::SuperModule', 'new'); 
    #Testing module subroutines 
    dies_ok { My::SuperModule->new() } "Died in class constructor"; 
    sub div { 
    my ($a, $b) = @_; 
    return $a/$b; 
}; 
    dies_ok { div(1, 0) } 'divide by zero detected'; 

Он останавливает выполнение скрипта в любом случае, но мне нужно просто обращаться, если умер, мне нужно, чтобы проверить это, потому что я вручную вызвать кубик, если данные неверно или что-то другое, но оно умирает и не продолжает выполнять скрипт дальше. Давая мне сообщение

Uncaught exception from user code: 
    Hello at ../libs/My/SuperModule.pm line 31. 
    My::SuperModule::new('My::SuperModule', '') called at SuperModule.t line 24 
# Tests were run but no plan was declared and done_testing() was not seen. 
# Looks like your test exited with 2 just after 8. 

Но если использовать деление на ноль он работает, как я хочу

ok 16 - divide by zero detected 

Так он терпит неудачу, но не прекращает выполнение сценария.

Я новичок в Perl, поэтому я не могу решить проблему самостоятельно, возможно, нет проблем вообще, просто нет способа делать то, что я хочу.
Пожалуйста, предложите, что делать или сказать, где моя ошибка здесь.

EDIT

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

Illegal division by zero at ../libs/My/SuperModule.pm line 33 (#1) 
    (F) You tried to divide a number by 0. Either something was wrong in 
    your logic, or you need to put a conditional in to guard against 
    meaningless input. 

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

+1

Почему вы «делаете» свой модуль? Достаточно сказать 'use_ok 'My :: SuperModule';' один раз. Все остальные 'use_ok' и' do' не нужны. – simbabque

ответ

4

Вот минимальный пример, который работает:

package My::SuperModule; 
use strict; 
use warnings; 

sub new { 
    die "Hello"; 
} 

package main; 

run() unless caller; 

use Test::More; 
use Test::Exception; 

sub run { 
    dies_ok { My::SuperModule->new } "dies ok"; 
    done_testing; 
} 

Выход:

C:\...\t> prove -v my.pl 
my.pl .. 
ok 1 - dies ok 
1..1 
ok 
All tests successful. 
Files=1, Tests=1, 0 wallclock secs (0.09 usr + 0.00 sys = 0.09 CPU) 
Result: PASS

Обратите внимания, что, с целью обеспечения самодостаточного примера, я объединил код модуля и тест скрипт в один файл.

Также обратите внимание, что я не загромождал тестовый скрипт ненужными операциями print.

Если вы хотите, вы можете использовать diag, чтобы показать некоторый вывод:

diag "Checking if Test::Exception::dies_ok will catch die in new"; 
dies_ok { My::SuperModule->new } "dies ok"; 
done_testing; 

Выход:

C:\...\t> prove my.pl 
my.pl .. # Checking if Test::Exception::dies_ok will catch die in new 
my.pl .. ok 
All tests successful. 
Files=1, Tests=1, 0 wallclock secs (0.05 usr + 0.02 sys = 0.06 CPU) 
Result: PASS

В отличие от простых print заявлений, diag выход на самом деле будет показано, когда тесты выполняются из жгута, такого как prove.

3

Это работает для меня. Все, что мне нужно было сделать:

  1. Прокомментировать два модуля, которые не использовались в тесте (Net :: Ping и Utils :: Variables :: Validator - у меня их нет).
  2. Добавить 1; в качестве последней строки модуля - так что оно возвращает истинное значение.
  3. Снять дополнительные испытания require и use_ok.
  4. Добавлено done_testing; до конца испытания - так что тестовая упряжь знает, что она дошла до конца испытаний.

Возможно, вам не нравится первый элемент в этом списке, но если вы исправите остальных, он должен сработать для вас.