2009-01-27 13 views
13

Tôi đang viết một mô-đun Perl, và tôi đang sử dụng cá chép để ném một cảnh báo không gây tử vong trở lại chương trình gọi điện.Làm thế nào tôi có thể bắt đầu ra từ một con cá chép trong Perl?

Cảnh báo cá chép hoạt động tốt - Tôi kiểm tra xem thông số đầu vào có đáp ứng điều kiện nhất định hay không - nếu nó không đáp ứng điều kiện, cảnh báo sẽ được gửi với cá chép và mô-đun tiếp tục sử dụng mặc định cho tham số thay vì một chương trình gọi điện thoại đã qua. Cảnh báo chỉ để thông báo rằng một tham số mặc định đang được sử dụng thay cho tham số được truyền vào.

Vấn đề của tôi là với tập lệnh thử nghiệm của tôi. Kịch bản thử nghiệm của tôi đang gửi thông số xấu đến mô-đun và tôi đang cố gắng nắm bắt thông báo cảnh báo quay lại và đảm bảo rằng tôi nhận được thông báo cảnh báo chính xác.

mô-đun của tôi trông giống như sau:

else { 
    carp "value must be numeric - using default value"; 
} 

và kịch bản thử nghiệm của tôi trông như thế này:

eval { 
    #call to my module 
}; 
like (
    [email protected], 
    qr/value must be numeric/, 
    "Should abort on non-numeric value" 
); 

Khi tôi chạy thử nghiệm, tôi có thể thấy cảnh báo (nó phải được sắp STDERR) trên màn hình, nhưng nội dung của biến $ @ là '' - trống.

Đây là kết quả từ kịch bản thử nghiệm của tôi:

t/04bad_method_calls....ok 10/12value must be numeric - using default value at ... 
# Failed test 'Should abort on non-numeric value' 
# at t/04bad_method_calls.t line 98. 
t/04bad_method_calls....NOK 12 
#     '' doesn't match '(?-xism:value must be numeric)' 
# Looks like you failed 1 test of 12. 

Nếu tôi thay đổi cá chép đến một tiếng kêu, kịch bản thử nghiệm của tôi làm việc - nó bắt được thông báo lỗi (nhưng tôi chỉ muốn cảnh báo, không hủy bỏ) .

Thành thật mà nói, tôi không có sự hiểu biết tốt nhất về eval - có thể đó không phải là cách tốt nhất để bắt đầu cảnh báo từ cá chép. Tôi đã thử sử dụng $ SIG {WARN}, nhưng cũng trống.

Có cách nào để nắm bắt đầu ra từ cá chép không? Đây không phải là vấn đề lớn nhất vì đây chỉ là kịch bản thử nghiệm của tôi, nhưng tôi vẫn muốn kịch bản thử nghiệm của tôi hoạt động đúng.

Cảm ơn trước!

Trả lời

19

Từ trang này, http://perldoc.perl.org/perlvar.html, có vẻ như bạn muốn đặt địa phương $SIG{__WARN__} thành chương trình con sẽ chuyển cảnh báo thành lỗi nghiêm trọng cho tập lệnh thử nghiệm của bạn. Ví dụ họ đưa ra là:

local $SIG{__WARN__} = sub { die $_[0] }; 
eval $proggie; 
+0

Đúng, đó là mẹo! Tôi đã hiểu nhầm $ SIG {__ WARN__} là gì. Điều này hoạt động hoàn hảo - cảm ơn rất nhiều! – BrianH

6

Một cách làm thế nào để bắt cảnh báo và cũng tất cả STERR đầu ra:

my $stderr = ''; 
{ 
    local *STDERR; 
    open STDERR, '>', \$stderr; 
    do_stuf_here(); 
} 
like($stderr, qr/my result/, 'test stderr output'); 

Người ta có thể thực hiện chức năng kiểm tra ưa thích:

sub stderr_test (&$$) { 
    my ($code, $pattern, $text) = @_; 
    my $result = ''; 
    { 
     local *STDERR; 
     open STDERR, '>', \$result; 
     $code->(); 
    } 
    if (UNIVERSAL::isa($pattern, 'Regexp')) { 
     like($result, $pattern, $text); 
    } 
    else { 
     is($result, $pattern, $text); 
    } 
} 

# usage 
stderr_test {do_stuf_here} qr/my expected STDERR output/, 
    'stderr is like'; 
stderr_test {do_stuf_here} 'my expected STDERR output', 
    'stderr is exactly'; 
+0

Wow - rất thú vị. Ví dụ đầu tiên là khá thẳng về phía trước và dường như cũng hoạt động tốt. – BrianH

6

Nếu bạn làm điều này từ một kịch bản thử nghiệm, bạn có thể sử dụng các mô-đun Test :: * để bắt đầu cho bạn. Tôi có xu hướng thích Test::Output.

+0

Trông giống như một giải pháp khá đơn giản. Thật không may tôi không có Test :: Output được cài đặt trong môi trường của chúng tôi, và cài đặt các mô-đun là khá nhiều nản lòng ở đây. Mặc dù nó không phù hợp với nhu cầu của tôi, +1 cho một giải pháp tuyệt vời. – BrianH

+0

Test :: Exception cũng hoạt động tốt cho việc này. –