2008-10-24 11 views
17

मुझे कुछ पुरानी स्क्रिप्ट्स में यूनिट परीक्षण जोड़ने की आवश्यकता है, स्क्रिप्ट सभी मूल रूप से निम्न रूप में हैं:क्या यह संभव है या इसके विवरणों को निष्पादित किए बिना पर्ल स्क्रिप्ट की आवश्यकता है?

#!/usr/bin/perl 

# Main code 
foo(); 
bar(); 

# subs 
sub foo { 

} 
sub bar { 

} 

अगर मैं इकाई कोड में इस कोड की 'आवश्यकता' करने का प्रयास करता हूं, तो कोड का मुख्य भाग होगा भागो, जहां मैं अलगाव में "foo" का परीक्षण करने में सक्षम होना चाहता हूं।

क्या foo, bar को अलग-अलग .pm फ़ाइल में घुमाने के बिना ऐसा करने का कोई तरीका है?

उत्तर

16

इकाई परीक्षण स्क्रिप्ट के लिए एक अन्य आम चाल एक 'फोन करने वाले' ब्लॉक में अपने कोड के शरीर रैप करने के लिए है:

#!/usr/bin/perl 

use strict; 
use warnings; 

unless (caller) { 
    # startup code 
} 

sub foo { ... } 

जब कमांड लाइन, क्रॉन, एक bash स्क्रिप्ट, आदि से चलाने के लिए, यह सामान्य रूप से चलता है। हालांकि, अगर आप इसे किसी अन्य पर्ल प्रोग्राम से लोड करते हैं, तो "जब तक (कॉलर) {...}" कोड नहीं चलता है। फिर अपने परीक्षण कार्यक्रम में, नामस्थान घोषित करें (चूंकि स्क्रिप्ट शायद पैकेज मुख्य में कोड चला रही है: :) और स्क्रिप्ट 'करें'।

#!/usr/bin/perl 

package Tests::Script; # avoid the Test:: namespace to avoid conflicts 
         # with testing modules 
use strict; 
use warnings; 

do 'some_script' or die "Cannot (do 'some_script'): $!"; 

# write your tests 

'डू' इसके लिए eval और काफी साफ से अधिक कुशल है।

स्क्रिप्ट का परीक्षण करने के लिए एक और चाल Expect का उपयोग करना है। यह क्लीनर है, लेकिन इसका उपयोग करना भी कठिन है और यदि आपको कुछ भी नकल करने की ज़रूरत है तो यह आपको स्क्रिप्ट के भीतर कुछ भी ओवरराइड नहीं करने देगा।

+0

यदि कोई दूरस्थ संभावना है कि कोई व्यक्ति आपकी स्क्रिप्ट को PAR (यानी "pp -o binary script.pl; .bbinary") के साथ पैकेज करेगा या वास्तव में इसे eval और इसे चलाने की उम्मीद है, तो * कृपया * ऐसा न करें । जब मैंने अपनी वाईएपीसी :: ईयू बात की तैयारी की थी तो इससे मुझे परेशानियों के साथ बहुत सारी चिंताएं मिलीं। – tsee

+0

निष्पक्ष होने के लिए, मैं PAR के बारे में थोड़ी सी चिंता में चिंता नहीं करता हूं। पर्ल 5 में विशेष रूप से गैर-कोर कोड के लिए सभी विशेष मामलों को याद रखने के लिए बहुत अधिक त्रुटियां हैं :( – Ovid

+0

@tsee किस पर आपकी चिंता है? 'कॉलर' ब्लॉक में स्क्रिप्ट लिखना? या ' क्या करें या मरें? – ajwood

17

मान लें कि आप किसी भी सुरक्षा चिंताएं हैं, एक उप {...} में लपेट और यह eval: कि eval किसी भी lexicals कि बंद कर दिया जाएगा के दायरे में नहीं है

use File::Slurp "read_file"; 
eval "package Script; sub {" . read_file("script") . "}"; 

is(Script::foo(), "foo"); 

(देखभाल लिपि द्वारा खत्म)।

+1

चूंकि किसी को इसका परीक्षण करने के लिए कोड चलाया जाना है, यहां eval STRING का उपयोग करने के साथ कोई विशेष सुरक्षा चिंता नहीं है। – Schwern

10

आह, पुराना "मैं एक प्रोग्राम का परीक्षण कैसे करूं" प्रश्न।

return 1 unless $0 eq __FILE__; 

__FILE__ वर्तमान स्रोत फ़ाइल है: सरल चाल अपने कार्यक्रम में इस डाल करने के लिए इससे पहले कि यह कर बातें शुरू होता है। $0 प्रोग्राम का नाम चल रहा है। यदि वे वही हैं, तो आपका कोड प्रोग्राम के रूप में निष्पादित किया जा रहा है। यदि वे अलग हैं, तो इसे पुस्तकालय के रूप में लोड किया जा रहा है।

यह आपके प्रोग्राम के अंदर सबराउटिन का परीक्षण करने के लिए पर्याप्त है। किसी भी अन्य सबरूटीन तरह

main() if $0 eq __FILE__; 

और अब आप मुख्य परीक्षण कर सकते हैं():

require "some/program"; 
...and test... 

अगला कदम तो आप ऐसा कर सकते हैं main में एक सबरूटीन के बाहर सभी कोड स्थानांतरित करने के लिए है।

एक बार ऐसा करने के बाद आप प्रोग्राम के सबराउटिन को अपने वास्तविक पुस्तकालयों में ले जाने पर विचार करना शुरू कर सकते हैं।

+0

ओविड के समाधान पर टिप्पणी में उल्लिखित वही गोचा यहां लागू होता है: पैकेजिंग को PAR :: पैकर या इसी तरह के टूल के साथ आज़माएं। – tsee

+0

@tsee जब मैं आता हूं तो मैं उस पुल को उड़ाऊंगा। ysth की चाल है चालाक हालांकि और कोड को संपादित किए बिना समस्या के आसपास मिल रहा है। – Schwern

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