2010-04-20 6 views
6

मैं छोटे क्ली कार्यक्रम पर काम करते समय इकाई परीक्षण के साथ शुरू करने की कोशिश कर रहा हूं।यूनिट परीक्षण के लिए इसे सक्षम बनाने के लिए मुझे अपने डेटाबेस निष्पादन/प्रतिबद्धता को फिर से लिखना चाहिए?

मेरा प्रोग्राम मूल रूप से कमांड लाइन तर्क और विकल्पों को पार करता है, और यह तय करता है कि कौन सा फ़ंक्शन कॉल करना है। प्रत्येक कार्य डेटाबेस पर कुछ ऑपरेशन करता है।

तो, उदाहरण के लिए, मैं एक बनाने के समारोह हो सकता है:

def create(self, opts, args): 
    #I've left out the error handling. 
    strtime = datetime.datetime.now().strftime("%D %H:%M") 
    vals = (strtime, opts.message, opts.keywords, False) 
    self.execute("insert into mytable values (?, ?, ?, ?)", vals) 
    self.commit() 

अपने परीक्षण मामले कॉल इस समारोह है, तो जाँच करने के लिए उस पंक्ति दर्ज किया गया था का चयन करें एसक्यूएल निष्पादित करना चाहिए? यह उचित लगता है, लेकिन परीक्षणों को बनाए रखने के लिए और भी मुश्किल बनाता है। क्या आप कुछ वापस करने और वापसी मूल्य की जांच करने के लिए फ़ंक्शन को फिर से लिखेंगे?

धन्यवाद

+0

मुझे लगता है कि इकाई परीक्षण दो शब्द है। पुस्तक में –

उत्तर

8

एलेक्स का उत्तर निर्भरता इंजेक्शन दृष्टिकोण को शामिल करता है। एक और आपकी विधि का कारक है। जैसा कि यह खड़ा है, इसमें दो चरण हैं: एक SQL कथन बनाएं, और SQL कथन निष्पादित करें। आप दूसरे चरण का परीक्षण नहीं करना चाहते हैं: आपने एसक्यूएल इंजन या डेटाबेस नहीं लिखा है, आप मान सकते हैं कि वे ठीक से काम करते हैं। चरण 1 आपका काम है: एक SQL कथन का निर्माण।

def create_sql(self, opts, args): 
    #I've left out the error handling. 
    strtime = datetime.datetime.now().strftime("%D %H:%M") 
    vals = (strtime, opts.message, opts.keywords, False) 
    return "insert into mytable values (?, ?, ?, ?)", vals 

def create(self, opts, args): 
    self.execute(*self.create_sql(opts, args)) 
    self.commit() 

create_sql समारोह चरण 1 है, और अब यह एक तरह से आप इसके खिलाफ सीधे परीक्षण लिखने देता है कि में व्यक्त किया है: यह मान लेता है तो तुम कोड ताकि आप चरण 1 परीक्षण कर सकते हैं फिर से व्यवस्थित कर सकते हैं और मान देता है, ताकि आप यूनिट परीक्षण लिख सकें जो इसकी कार्यक्षमता को कवर करता है। create फ़ंक्शन स्वयं अब सरल है, और इसकी जांच पूरी तरह से नहीं की जानी चाहिए: आपके पास कुछ परीक्षण हो सकते हैं जो दिखाते हैं कि यह वास्तव में SQL को सही तरीके से निष्पादित करता है, लेकिन आपको create में सभी किनारे के मामलों को कवर करने की आवश्यकता नहीं है।

बीटीडब्ल्यू: This video from Pycon (Tests and Testability) दिलचस्प हो सकता है।

6

मैं निश्चित रूप से परीक्षण में आसानी के लिए इस विधि refactor होगा - उदाहरण के लिए, निर्भरता इंजेक्शन मदद कर सकता है:

def create(self, opts, args, strtime=None, exec_and_commit=None): 
    #I've left out the error handling. 
    if strtime is None: 
     strtime = datetime.datetime.now().strftime("%D %H:%M") 
    vals = (strtime, opts.message, opts.keywords, False) 
    if exec_and_commit is None: 
     exec_and_commit = self.execute_and_commit 
    exec_and_commit("insert into mytable values (?, ?, ?, ?)", vals) 

निश्चित रूप से यह मान लिया गया है कि आप एक execute_and_commit विधि है कि execute और फिर कहता है commit विधियां।

इस तरह, परीक्षण कोड strtime के ज्ञात मान इंजेक्षन, और अपने स्वयं के प्रतिदेय exec_and_commit के रूप में सत्यापित करने के लिए यह उम्मीद तर्कों के साथ कॉल हो जाता है कि इंजेक्षन कर सकते हैं।

0

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

उम्मीद है कि आप जावा सी # वाक्य रचना के साथ परिचित से मैं अजगर वाक्य रचना के साथ कर रहा हूँ कर रहे हैं :)

public string GetSqlCommand(string[] commandLineArgs) 
{ 
    //do your parsing here 
    return sqlCommand; 
} 
[Test] 
public void emptyArgs_returnsEmptySqlCommand() 
{ 
    string expectedSqlCommand=""; 
    assert.AreEqual(expectedSqlCommand, GetSqlCommand(new string[]) 
} 
3

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

उस ने कहा, कुछ छोटे रिफैक्टरिंग हैं जो व्यवहार को बदले बिना सुरक्षित रूप से किया जा सकता है। नाम बदलें और निकालें दो हैं।

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

+0

और सी ++ कोड का उपयोग किया जाता है – Gutzofter

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