2012-11-28 10 views
9

के साथ दोहराए गए एकल या एकाधिक परीक्षण this question के समान, मैं नाक को एक परीक्षण (या सभी परीक्षण) n बार चलाने के लिए चाहता हूं - लेकिन समानांतर में नहीं है।नाक

मेरे पास एक परियोजना में कुछ सौ परीक्षण हैं; कुछ कुछ साधारण यूनिट परीक्षण हैं। अन्य एकीकरण परीक्षण w/कुछ डिग्री समेकन हैं। अक्सर डिबगिंग परीक्षण करते समय मैं एक परीक्षण को "हिट" करना चाहता हूं; एक बैश लूप काम करता है, लेकिन बहुत सारे अव्यवस्थित आउटपुट के लिए बनाता है - कोई और अच्छा एकल नहीं। " प्रत्येक उत्तीर्ण परीक्षण के लिए। कुछ परीक्षणों के लिए चयनित परीक्षणों पर हरा करने की क्षमता होने के कारण नाक से पूछने के लिए प्राकृतिक बात की तरह लग रहा है, लेकिन मुझे इसे दस्तावेज़ों में कहीं भी नहीं मिला है।

नाक को ऐसा करने का सबसे आसान तरीका क्या है (बैश लूप के अलावा)?

+0

यदि आप कहते हैं कि आप ऐसा क्यों करना चाहते हैं तो यह मदद कर सकता है। इसके अलावा, क्या 'एन' भिन्न होता है? यदि हां, तो आप इसे कैसे निर्दिष्ट करना चाहते हैं? (उदाहरण के लिए जब आप परीक्षण चलाते हैं तो कमांड लाइन पर?) क्यों कोई बैश नहीं? यह नौकरी के लिए एकदम सही प्रतीत होता है। –

+0

मैंने प्रश्न में तर्क का विस्तार किया। – JohnJ

उत्तर

14

आप write a nose test as a generator कर सकते हैं, और नाक तो प्रत्येक समारोह चलेंगे झुकेंगे:

def check_something(arg): 
    # some test ... 

def test_something(): 
    for arg in some_sequence: 
     yield (check_something, arg) 

nose-testconfig उपयोग करके, आप परीक्षण की संख्या बना सकता है एक कमांड लाइन तर्क चलाता है:

from testconfig import config 

# ... 

def test_something(): 
    for n in range(int(config.get("runs", 1))): 
     yield (check_something, arg) 

आप कौन सा उदाहरण के साथ कमांड लाइन से कॉल करें

$ nosetests --tc=runs:5 

... एक से अधिक रन के लिए।

वैकल्पिक रूप से (लेकिन यह भी नाक-testconfig का प्रयोग करके), तो आप एक डेकोरेटर लिख सकते हैं: तो

from functools import wraps 
from testconfig import config 

def multi(fn): 
    @wraps(fn) 
    def wrapper(): 
     for n in range(int(config.get("runs", 1))): 
      fn() 
    return wrapper 

@multi 
def test_something(): 
    # some test ... 

और, यदि आप अलग अलग समूहों में अपने परीक्षण विभाजित करना चाहते हैं, के लिए अपने स्वयं के कमांड लाइन तर्क के साथ प्रत्येक रनों की संख्या:

from functools import wraps 
from testconfig import config 

def multi(cmd_line_arg): 
    def wrap(fn): 
     @wraps(fn) 
     def wrapper(): 
      for n in range(int(config.get(cmd_line_arg, 1))): 
       fn() 
     return wrapper 
    return wrap 

@multi("foo") 
def test_something(): 
    # some test ... 

@multi("bar") 
def test_something_else(): 
    # some test ... 

जो तुम इस तरह कॉल कर सकते हैं:

$ nosetests --tc=foo:3 --tc=bar:7 
+0

आप वास्तव में अपने उदाहरण में लपेटें का उपयोग नहीं करते हैं। क्या इसकी आवश्यकता है? – JohnJ

+0

अच्छी तरह से देखा गया :-) हां, क्योंकि अन्यथा सजाए गए फ़ंक्शन का सही नाम नहीं होगा और नाक इसे नहीं ढूंढ पाएगा। फिक्स्ड (कुछ अन्य छोटी त्रुटियों के साथ)। –

+0

ग्रेट! उत्तर को ऊपर उठाया - हालांकि यह अभी भी काफी नहीं है जो मुझे अभी भी चाहिए, क्योंकि मुझे ओ (200) परीक्षणों में से प्रत्येक को सजाना होगा। आश्चर्य की बात है कि मुझे सिर्फ बुलेट काटने चाहिए और देखें कि इसके लिए नाक प्लगइन लिखना संभव है या नहीं। एक बार फिर धन्यवाद। – JohnJ

2

बदलें इस:

class MyTest(unittest.TestCase): 

    def test_once(self): 
     ... 
इस के लिए

:

class MyTest(unittest.TestCase): 

    def assert_once(self): 
     ... 

    def test_many(self): 
     for _ in range(5): 
      self.assert_once() 
+2

निश्चित रूप से, यह करने के लिए तुच्छ है - मैं आम तौर पर एक बार प्रत्येक परीक्षण चलाने के लिए खुश हूं, लेकिन अगर मुझे कभी-कभी असफल होने के लिए एक परीक्षण (या परीक्षण की कक्षा) पर संदेह होता है, तो परीक्षण फ्रेमवर्क मुझे यह अच्छा लगेगा कि विकल्प। – JohnJ

0

वहाँ एक परीक्षण एक बार से अधिक को चलाने के लिए एक कारण नहीं होना चाहिए 210 एक तरह से परीक्षण अपने आप में है। यह महत्वपूर्ण है कि आपके परीक्षण निर्धारक हैं (यानी कोडबेस के समान राज्य को देखते हुए, वे हमेशा एक ही परिणाम उत्पन्न करते हैं।) यदि यह मामला नहीं है, तो परीक्षणों को एक से अधिक बार चलाने की बजाय, आपको परीक्षणों को फिर से डिजाइन करना चाहिए और/या कोड ताकि वे हैं।

उदाहरण के लिए, एक कारण है कि परीक्षण रुक-रुक कर असफल परीक्षण और कोड-अंडर-परीक्षण (कट) के बीच एक दौड़ शर्त है। इस परिस्थिति में, एक निष्पक्ष प्रतिक्रिया परीक्षण में एक बड़ी 'वूडू नींद' जोड़ना है, 'सुनिश्चित करें' कि परीक्षण शुरू होने से पहले सीयूटी समाप्त हो गया है।

यह त्रुटियां उत्पन्न हो सकती है, हालांकि, क्योंकि अगर आपकी कट किसी भी कारण (underpowered हार्डवेयर, लोड बॉक्स, व्यस्त डेटाबेस, आदि) तो यह कई मायनों विफल हो जाएगी धीमी है। इस उदाहरण में एक बेहतर समाधान के लिए अपने परीक्षण एक घटना लिए प्रतीक्षा करें, बल्कि सो से अधिक है।

घटना आपके चयन के कुछ भी हो सकती है। कभी-कभी, जिन घटनाओं का आप उपयोग कर सकते हैं वे पहले से ही उत्पन्न हो रहे हैं (उदाहरण के लिए जावास्क्रिप्ट डोम इवेंट्स, 'पेजरेंडर्ड' प्रकार की घटनाएं जो सेलेनियम परीक्षण का उपयोग कर सकती हैं।) अन्य बार, आपके क्यूटी में कोड जोड़ने के लिए यह उचित हो सकता है जो एक उठाता है जब यह किया जाता है (शायद आपके आर्किटेक्चर में ऐसे अन्य घटक शामिल होते हैं जो इस तरह की घटनाओं में रूचि रखते हैं।)

हालांकि, आपको परीक्षण फिर से लिखना होगा जैसे कि यह पता लगाने की कोशिश करता है कि आपका कट निष्पादन समाप्त हो गया है या नहीं (उदाहरण के लिए आउटपुट फ़ाइल अभी तक मौजूद है?), और यदि नहीं, तो 50ms के लिए सोता है और फिर फिर से प्रयास करता है। आखिरकार यह समय समाप्त हो जाएगा और असफल हो जाएगा, लेकिन केवल बहुत लंबे समय के बाद ऐसा करें (उदाहरण के लिए आपके क्यूटी के अपेक्षित निष्पादन समय 100 गुना)

एक और तरीका 'प्याज/हेक्सागोनल/बंदरगाहों' का उपयोग करके अपने कट को डिजाइन करना है। एडाप्टर के सिद्धांत, जो आपके व्यापार तर्क को जोर देते हैं, सभी बाहरी निर्भरताओं से मुक्त होना चाहिए। इसका मतलब है कि आपके व्यापार तर्क का परीक्षण सादे पुराने उप-मिलीसेकंड यूनिट परीक्षणों का उपयोग करके किया जा सकता है, जो कभी भी नेटवर्क या फाइल सिस्टम को स्पर्श नहीं करता है। एक बार ऐसा करने के बाद, आपको बहुत कम एंड-टू-एंड सिस्टम परीक्षण की आवश्यकता होती है, क्योंकि वे अब एकीकरण परीक्षण के रूप में सेवा कर रहे हैं, और यूआई के माध्यम से आपके व्यवसाय तर्क के हर विवरण और किनारे के मामले में हेरफेर करने की आवश्यकता नहीं है । इस दृष्टिकोण से अन्य क्षेत्रों में बड़े लाभ भी मिलेंगे, जैसे उन्नत सीयूटी डिजाइन (घटकों के बीच निर्भरता को कम करना), परीक्षण लिखना बहुत आसान है, और पूरे टेस्ट सूट को चलाने के लिए लिया गया समय बहुत कम हो गया है।

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

+0

डाउनवोट क्योंकि ओपी ने नहीं पूछा * चाहे * उसे कई बार परीक्षण चलाना चाहिए, उसने पूछा * यह कैसे करें *। –

+0

सही, लेकिन कभी-कभी सबसे अच्छा जवाब वास्तव में गलत सड़क को आगे बढ़ाने में मदद करने के बजाय "एक अलग दृष्टिकोण का प्रयास करें" कहना है। मुझे यकीन नहीं है कि स्थानीय मानदंड क्या हैं, लेकिन मुझे लगता है कि एक डाउनवोट कठोर है: यह उत्तर अन्य लोगों के लिए समान समस्या पर विचार करने के लिए उपयोगी हो सकता है। –

+3

निश्चित रूप से! हालांकि, यही है कि "एक टिप्पणी जोड़ें" बटन के लिए है। वैकल्पिक रूप से, ऐसा लगता है कि आपने सवाल का जवाब भी दिया है, क्यों नहीं अपनी चेतावनी जोड़ें? –

2

आपको ऐसा करने के लिए एक स्क्रिप्ट लिखनी होगी, लेकिन आप कमांडलाइन X बार पर परीक्षण नाम दोहरा सकते हैं।

nosetests testname testname testname testname testname testname testname 

आदि

1

समाधान मैं का उपयोग कर समाप्त हो गया श स्क्रिप्ट run_test.sh बनाने है:

var=0 
while $1; do 
    ((var++)) 
    echo "*** RETRY $var" 
done 

उपयोग:

./run_test.sh "nosetests TestName" 

यह असीम परीक्षण चलता है, लेकिन पहले पर बंद हो जाता है त्रुटि।

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