كيف يمكنني التقاط الإخراج من الكارب في بيرل؟

StackOverflow https://stackoverflow.com/questions/483622

  •  20-08-2019
  •  | 
  •  

سؤال

أنا أكتب وحدة Perl ، وأنا أستخدم Carp لرمي تحذير غير مميت إلى برنامج الاتصال.

يعمل تحذير CARP بشكل جيد - أنا أتحقق مما إذا كانت معلمة إدخال تلبي شرطًا معينًا - إذا لم تفي بالشرط ، فسيتم إرسال تحذير باستخدام CARP ويستمر الوحدة في استخدام الافتراضي للمعلمة بدلاً من برنامج الاتصال تم الاجتياز بنجاح. التحذير هو فقط إخطار المعلمة الافتراضية يتم استخدامها بدلاً من تم تمريرها في المعلمة.

مشكلتي هي مع البرنامج النصي للاختبار. يقوم البرنامج النصي للاختبار الخاص بي بإرسال معلمة سيئة إلى الوحدة النمطية ، وأحاول التقاط رسالة التحذير التي تعود وتأكد من تلقي رسالة التحذير الصحيحة.

الوحدة النمطية الخاصة بي تبدو مثل هذا:

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

ويبدو نصي الاختبار الخاص بي مثل هذا:

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

عندما أقوم بإجراء الاختبار ، يمكنني رؤية التحذير (يجب أن يكون Stderr) على الشاشة ، ولكن محتويات $@ المتغير هي " - فارغة.

هنا هو الإخراج من البرنامج النصي للاختبار:

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.

إذا قمت بتغيير الكارب إلى croak ، فإن البرنامج النصي الخاص بي يعمل - فهو يمسك رسالة الخطأ (لكنني أريد فقط التحذير ، وليس الإجهاض).

لأكون صادقًا ، ليس لدي أفضل فهم لـ Eval - ربما لا يكون هذا هو أفضل طريقة لالتقاط ناتج التحذير من CARP. حاولت استخدام $ sig {حذر} ، لكن ذلك كان فارغًا أيضًا.

هل هناك أي طريقة لالتقاط الإخراج من الكارب؟ إنها ليست أكبر صفقة لأن هذا هو فقط في البرنامج النصي للاختبار ، لكنني ما زلت أرغب في الحصول على البرنامج النصي للاختبار بشكل صحيح.

شكرا مقدما!

هل كانت مفيدة؟

المحلول

من هذه الصفحة ، http://perldoc.perl.org/perlvar.html, ، يبدو أنك تريد ضبط المحلية $SIG{__WARN__} إلى روتين فرعي من شأنه أن يحول التحذيرات إلى أخطاء قاتلة لبرنامج الاختبار الخاص بك. المثال الذي يقدمونه هو:

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

نصائح أخرى

طريقة أخرى لكيفية التقاط التحذيرات وأيضًا جميعها STERR انتاج:

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

يمكن للمرء أن يجعل وظيفة الاختبار الفاخرة:

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';

إذا كنت تفعل هذا من برنامج نصي اختبار ، فيمكنك استخدام وحدات Test ::* التي تلتقط الإخراج لك. أنا أميل إلى الإعجاب اختبار :: الإخراج.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top