2009-10-08 13 views
33

मैं स्क्रीन पर प्रिंट करने वाले यूनिट परीक्षण पर्ल फ़ंक्शंस में Test::More का उपयोग करने का प्रयास कर रहा हूं।मैं स्क्रीन पर प्रिंट करने वाले पर्ल फ़ंक्शंस का परीक्षण कैसे कर सकता हूं?

मैं समझता हूं कि यह आउटपुट prove जैसे उपकरणों में हस्तक्षेप कर सकता है।

मैं इस आउटपुट को कैप्चर कैसे कर सकता हूं ताकि मैं इसे diag() से प्रिंट कर सकूं, और आउटपुट पर परीक्षण भी चला सकता हूं?

उत्तर

32

अद्यतन: IMHO, इस सवाल का सही जवाब Test::Output उपयोग करने के लिए होना चाहिए:

#!/usr/bin/perl 

use strict; use warnings; 

use Test::More tests => 1; 
use Test::Output; 

sub myfunc { print "This is a test\n" } 

stdout_is(\&myfunc, "This is a test\n", 'myfunc() returns test output'); 

आउटपुट:

 
C:\Temp> tm 
1..1 
ok 1 - myfunc() returns test output 

मैं के रूप में संदर्भ के लिए मूल जवाब जा रहा हूँ, मुझे विश्वास है, यह अभी भी एक उपयोगी तकनीक दिखाता है।

आप STDOUT स्थानीय बनाना और समारोह कॉल करने से पहले एक अदिश को फिर से खोलना कर सकते हैं, बाद में बहाल:

#!/usr/bin/perl 

use strict; use warnings; 

use Test::More tests => 1; 

sub myfunc { print "This is a test\n" } 

sub invoke { 
    my $sub = shift; 
    my $stdout; 
    { 
     local *STDOUT; 
     open STDOUT, '>', \$stdout 
      or die "Cannot open STDOUT to a scalar: $!"; 
     $sub->(@_); 
     close STDOUT 
      or die "Cannot close redirected STDOUT: $!"; 
    } 
    return $stdout; 
} 

chomp(my $ret = invoke(\&myfunc)); 

ok($ret eq "This is a test", "myfunc() prints test string"); 
diag("myfunc() printed '$ret'"); 

आउटपुट:

 
C:\Temp> tm 
1..1 
ok 1 - myfunc() prints test string 
# myfunc() printed 'This is a test' 

5,8 से अधिक उम्र के perl के संस्करणों के लिए, आप शायद उपयोग करने की आवश्यकता IO::Scalar, लेकिन मुझे 5.8 से पहले काम करने के तरीके के बारे में बहुत कुछ पता नहीं है।

+4

बस जब मुझे लगता है कि मैं SO पर बहुत अधिक समय बर्बाद कर रहा हूं, तो मैं कुछ अच्छा सीखता हूं! धन्यवाद। – FMc

+0

ठीक है, तकनीकी रूप से वे नहीं करते हैं, लेकिन यह सुनिश्चित करते समय यह अच्छा है। : पी (+1, यह एक अद्भुत मॉड्यूल है) –

+0

मैंने इसे कम नहीं किया, लेकिन मुझे लगता है कि मूल जवाब नौकरी पाने के लिए बहुत अधिक काम करता है। यह बहुत जटिल है। मैं टेस्ट :: आउटपुट की तरफ थोड़ा पक्षपातपूर्ण हूं, लेकिन मैं इसे अंतिम उपाय के रूप में उपयोग करता हूं। उपयोगिता के लिए –

7

मैं एक मॉड्यूल को आपके लिए इसे संभालने की अनुमति दूंगा। Capture::Tiny देखें।

+0

+1 मुझे कैप्चर :: टिनी के बारे में पता नहीं था। –

5

यदि यह कोड है जिसे आप स्वयं लिख रहे हैं, तो इसे बदलें ताकि प्रिंट स्टेटमेंट डिफ़ॉल्ट फ़ाइलहेडल का उपयोग न करें।

 
sub my_print { 
    my $self = shift; 
    my $fh = $self->_get_output_fh; 
    print { $fh } @_; 
    } 

sub _get_output_fh { $_[0]->{_output} || \*STDOUT } 
sub _set_output_fh { $_[0]->{_output} = $_[1] } # add validation yourself 

जब आप परीक्षण करने पर आपको _set_output_fh फोन यह अपने परीक्षण filehandle (शायद यह भी एक IO::Null संभाल) देने के लिए कर सकते हैं: इसके बजाय, अपने आप को आप की तरह कुछ भी करने के लिए उत्पादन filehandle स्थापित करने के लिए एक तरह से दे। जब कोई अन्य व्यक्ति आपके कोड का उपयोग करना चाहता है लेकिन आउटपुट कैप्चर करना चाहता है, तो उसे ऐसा करने के लिए पिछड़े पर मोड़ना नहीं पड़ता क्योंकि वे अपना खुद का फाइलहेडल आपूर्ति कर सकते हैं।

जब आप अपने कोड का एक हिस्सा पाते हैं जो परीक्षण करना मुश्किल है या आपको हुप्स के माध्यम से काम करने के लिए कूदना है, तो शायद आपके पास एक खराब डिज़ाइन है। मैं अभी भी आश्चर्यचकित हूं कि परीक्षण कोड इन चीजों को कैसे स्पष्ट करता है, क्योंकि मैं अक्सर उनके बारे में नहीं सोचता। यदि परीक्षण करना मुश्किल है, तो परीक्षण करना आसान बनाएं। यदि आप ऐसा करते हैं तो आप आमतौर पर जीतते हैं।

+0

आमेन। लेखन इकाई परीक्षण (या यदि आप टीडीडी करते हैं, चाहे आप इसे जानते हों या नहीं) के लिए योजना बनाते हैं) अक्सर डिजाइन डिज़ाइन सुधारों में परिणाम होते हैं। – DVK

संबंधित मुद्दे