Почему мой модульный тест Perl терпит неудачу в EPIC, но работает в отладчике? - PullRequest
1 голос
/ 19 ноября 2009

Кто-нибудь когда-либо испытывал модульный тест, который не прошел, и когда он пытался отладить его, чтобы выяснить, где произошел сбой, модульный тест завершается успешно при запуске кода в отладчике?

Я использую Eclipse 3.5.1 с EPIC 0.6.35 и ActiveState ActivePerl 5.10.0. Я написал модуль A и модуль B с несколькими процедурами. Подпрограмма в модуле B вызывает кучу подпрограмм из модуля A. Я добавляю фиктивные объекты в мой файл модульного теста модуля B, чтобы попытаться получить более полное покрытие кода в модуле B, где код в модуле B тестирует, чтобы увидеть, вызовы к модулю Как рутины терпят неудачу или преуспевают. Поэтому я добавил несколько фиктивных объектов в свой модульный тест, чтобы заставить некоторые подпрограммы модуля A возвращать сбои, но я не получал сбои, как ожидалось. Когда я отлаживал свой файл модульного теста, вызовы к модулю A завершились неудачно, как и ожидалось (и мой модульный тест прошел успешно) Когда я запускаю файл модульного теста в обычном режиме без отладки, вызов поддельной подпрограммы модуля A не завершается, как ожидалось (и мой модульный тест завершается неудачно).

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

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

Мой проект Eclipse содержит каталог "lib" с двумя модулями ... MainModule.pm и UtilityModule.pm. Мой проект Eclipse также содержит на верхнем уровне файл модульного теста с именем MainModuleTest.t и текстовый файл с именем input_file.txt, который просто содержит какой-то мусорный текст.

EclipseProject/
    MainModuleTest.t
    input_file.txt
    lib/
        MainModule.pm
        UtilityModule.pm

Содержимое файла MainModuleTest.t:

use Test::More qw(no_plan);
use Test::MockModule;
use MainModule qw( mainModuleRoutine );

$testName = "force the Utility Module call to fail";
# set up mock utility routine that fails
my $mocked = new Test::MockModule('UtilityModule');
$mocked->mock( 'slurpFile', undef );
# call the routine under test
my $return_value = mainModuleRoutine( 'input_file.txt' );
if ( defined($return_value) ) {
    # failure; actually expected undefined return value
    fail($testName);
}
else {
    # this is what we expect to occur
    pass($testName); 
}

Содержимое файла MainModule.pm:

package MainModule;

use strict;   
use warnings; 
use Exporter; 
use base qw(Exporter); 
use UtilityModule qw( slurpFile );

our @EXPORT_OK = qw( mainModuleRoutine );

sub mainModuleRoutine {
    my ( $file_name ) = @_;
    my $file_contents = slurpFile($file_name);
    if( !defined($file_contents) ) {
        # failure
        print STDERR "slurpFile() encountered a problem!\n";
        return;
    }
    print "slurpFile() was successful!\n";
    return $file_contents;
}

1;  

Содержимое файла UtilityModule.pm:

package UtilityModule;

use strict;   
use warnings; 
use Exporter; 
use base qw(Exporter); 

our @EXPORT_OK = qw( slurpFile );

sub slurpFile {
    my ( $file_name ) = @_;
    my $filehandle;
    my $file_contents = "";
    if ( open( $filehandle, '<', $file_name ) ) {
        local $/=undef;
        $file_contents = <$filehandle>;
        local $/='\n';
        close( $filehandle ); 
    }
    else {
        print STDERR "Unable to open $file_name for read: $!";
        return;    
    } 
    return $file_contents;
}

1;   

Когда я щелкаю правой кнопкой мыши MainModuleTest.t в Eclipse и выбираю Run As | Perl Local , это дает мне следующий вывод:

slurpFile() was successful!
not ok 1 - force the Utility Module call to fail
1..1
#   Failed test 'force the Utility Module call to fail'
#   at D:/Documents and Settings/[SNIP]/MainModuleTest.t line 13.
# Looks like you failed 1 test of 1.

Когда я щелкаю правой кнопкой мыши на том же файле модульного теста и выбираю Debug As | Perl Local , это дает мне следующий вывод:

slurpFile() encountered a problem!
ok 1 - force the Utility Module call to fail
1..1

Итак, это, очевидно, проблема. Run As и Debug As должны давать одинаковые результаты, верно?!?!?

Ответы [ 2 ]

1 голос
/ 23 ноября 2009

И Exporter, и Test :: MockModule работают, манипулируя таблицей символов. Вещи, которые делают это, не всегда хорошо играют вместе. В этом случае Test :: MockModule устанавливает макетированную версию slurpFile в UtilityModule после того, как Exporter уже экспортировал ее в MainModule. Псевдоним, который использует MainModule, все еще указывает на исходную версию.

Чтобы исправить это, измените MainModule на полное имя подпрограммы:

 my $file_contents = UtilityModule::slurpFile($file_name);

Причина, по которой это работает в отладчике, заключается в том, что отладчик также использует манипулирование таблицей символов для установки хуков. Эти крючки должны быть установлены правильно и в нужное время, чтобы избежать несоответствия, которое обычно происходит.

Можно утверждать, что это ошибка (в отладчике) всякий раз, когда код ведет себя там не так, как при запуске вне отладчика, но когда у вас три модуля, все взаимодействующие с таблицей символов, неудивительно, что все может вести себя странно .

0 голосов
/ 19 ноября 2009

Ваш насмешливый манипулирует таблицей символов? Я видел ошибку в отладчике , которая мешает манипулированию таблицей символов. Хотя в моем случае проблема была решена; код сломался под отладчиком, но работал при нормальной работе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...