2012-02-01 16 views
17

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

संपादित करें: मेरे व्यापार तर्क अपनी प्रस्तुति तर्क से, वहाँ अलग है है 1 या 2 सार्वजनिक तरीकों मेरे व्यापार तर्क उजागर तो प्रपत्र उन तक पहुँच सकते हैं, लेकिन क्या सभी निजी तरीकों कि व्यापार तर्क में हैं के बारे में?

उत्तर

14

पहली बात यह है कि मैं यह सुनिश्चित करूँ कि आपके पास अपने व्यापार तर्क से उचित रूप से अलग हो। मूल रूप से, MVC पैटर्न का उपयोग कर। फिर, आप फ़ॉर्म के बाहर सबकुछ आसानी से जांच सकते हैं, जैसे कि फॉर्म भी मौजूद नहीं था।

अब, यह अभी भी कुछ अनचाहे फ़ॉर्म-विशिष्ट कार्यक्षमता को छोड़ सकता है। आईई, क्या सेवा सही ढंग से सेवा के लिए तार है? इसके लिए, फिर भी आप NUnit फॉर्म या किसी अन्य विकल्प जैसे कुछ पर विचार कर सकते हैं।

+0

ठीक है मेरे पास है, लेकिन अगर मेरे पास अपने व्यवसाय तर्क में 1 या 2 सार्वजनिक विधियां हैं जो मेरा फॉर्म एक्सेस करता है, और इन्हें मेरे व्यापार तर्क में निजी तरीकों तक पहुंचने में मदद मिलती है, तो क्या यह मेरे फॉर्म में सार्वजनिक इंटरफ़ेस का परीक्षण करने के लिए पर्याप्त है व्यापार तर्क? और यूनिट परीक्षण नहीं लिखते हैं जो मेरी किसी भी निजी विधि का सीधे परीक्षण करते हैं? – DukeOfMarmalade

+0

@Jim - हां, यह मेरे कई स्वीकार्य माना जाता है, क्योंकि सार्वजनिक तरीकों का परीक्षण निजी तरीकों के भीतर कोड का उपयोग कर रहा है। (यह वास्तव में निजी तरीकों को हटाने से अलग नहीं होगा, और सार्वजनिक कोड के भीतर अपने कोड को आंतरिक ब्लॉक में ले जायेगा।) – ziesemer

+0

सहमत! धन्यवाद! – DukeOfMarmalade

4

सभी व्यावसायिक तर्क को एक अलग परियोजना और इकाई परीक्षण में तोड़ दें। या कम से कम सभी तर्कों को फॉर्मों से अलग वर्गों में ले जाएं।

5

आपके पास कुछ विकल्प हैं।

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

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

+0

# 1 के लिए: न केवल यह एक अच्छा विकल्प है क्योंकि यह धीमा है, यह यूनिट परीक्षण भी नहीं है। यूआई परीक्षण सिर्फ यही है, यह एकीकरण परीक्षण के करीब है। # 2 के लिए: न केवल अगर आपके पास निजी तरीकों का "बहुत" है, लेकिन यदि आपके पास व्यावसायिक तर्क करने वाले किसी भी निजी तरीके से आपके कोड को जोड़ दिया गया है। युग्मित युग्मित है, एक पैमाने नहीं होना चाहिए। इसके अलावा, # 2 बिल्कुल सही है। – Suamere

25

यूनिट परीक्षण ग्राफिकल अनुप्रयोगों की कुंजी यह सुनिश्चित करना है कि सभी व्यवसाय तर्क सभी अलग-अलग वर्ग में हों और पीछे कोड में न हों।

Model View Presenter और Model View Controller जैसे डिज़ाइन पैटर्न ऐसे सिस्टम को डिज़ाइन करते समय सहायता कर सकते हैं।

public partial class Form1 : Form, IMyView 
{ 
    MyPresenter Presenter; 
    public Form1() 
    { 
     InitializeComponent(); 
     Presenter = new MyPresenter(this); 
    } 

    public string SomeData 
    { 
     get 
     { 
      throw new NotImplementedException(); 
     } 
     set 
     { 
      MyTextBox.Text = value; 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Presenter.ChangeData(); 
    } 
} 

public interface IMyView 
{ 
    string SomeData { get; set; } 
} 

public class MyPresenter 
{ 
    private IMyView View { get; set; } 
    public MyPresenter(IMyView view) 
    { 
     View = view; 
     View.SomeData = "test string"; 
    } 

    public void ChangeData() 
    { 
     View.SomeData = "Some changed data"; 
    } 
} 

आप देख सकते हैं, फार्म केवल तेरा सब कुछ करने के लिए कुछ बुनियादी ढांचे कोड एक साथ है:

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

यदि आप यूनिट का परीक्षण करना चाहते हैं तो आप व्यू इंटरफ़ेस को नकल करने और अपने प्रस्तुतकर्ता को पास करने के लिए Rhino Mocks जैसे मॉकिंग टूल का उपयोग कर सकते हैं।

[TestMethod] 
public void TestChangeData() 
{ 
    IMyView view = MockRepository.DynamickMock<IMyView>(); 
    view.Stub(v => v.SomeData).PropertyBehavior(); 

    MyPresenter presenter = new MyPresenter(view); 

    presenter.ChangeData(); 

    Assert.AreEqual("Some changed data", view.SomeData); 
} 
0

यूनिट परीक्षण दृश्य अनुमोदन (www.approvaltests.com या nuget) का उपयोग करके काफी सरल है। यहां एक वीडियो है: http://www.youtube.com/watch?v=hKeKBjoSfJ8

हालांकि, ऐसा लगता है कि आप कार्यक्षमता का परीक्षण करने में सक्षम होने के उद्देश्य से फ़ंक्शन डिफ़ॉल्ट या सार्वजनिक बनाने के बारे में चिंतित हैं।

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

आप प्रोग्रामर हैं, और ऐसे में परीक्षण करने के लिए आसान होने के लिए अपने कोड को डिजाइन करें। यह आम तौर पर कुछ तरीकों सार्वजनिक बदलकर और कुछ connivence तरीकों कि dependences में पारित करने की अनुमति बनाने की तुलना में थोड़ा और अधिक मतलब है

उदाहरण के लिए:।

buttonclick += (o,e)=> {/*somecode*/}; 

बहुत परीक्षण करने के लिए कठिन है।

private void button1_Click(object sender, EventArgs e) {/*somecode*/} 

अभी भी कठिन

public void button1_Click(object sender, EventArgs e) {/*somecode*/} 

आसान परीक्षण करने के लिए परीक्षण करने के लिए

private void button1_Click(object sender, EventArgs e) { DoSave();} 
public void DoSave(){/*somecode*/} 

सच आसान का परीक्षण करने के लिए!

यदि आपको घटना से कुछ जानकारी चाहिए तो यह दोगुना हो जाता है। अर्थात।

public void ZoomInto(int x, int y) 

ज्यादा परीक्षण करने के लिए है कि इसी माउस क्लिक घटना, और पासथ्रू कॉल अभी भी एक भी अनदेखा करने योग्य लाइन हो सकता है आसान है।

+1

कुछ लोग कारणों को भ्रमित करते हैं कि कुछ सही करने के कारणों से बुरे कारण नगण्य क्यों हो सकते हैं। Encapsulation केवल सुरक्षा से अधिक के लिए है। पल कोडर सोचते हैं कि यह निष्पक्ष सदस्यों को सार्वजनिक करना होगा, जब वे चिंताओं और ठोस विकास प्रथाओं को अलग करते हैं। अब आपके पास एक ऐप है जो सुरक्षा खो नहीं सकता है, लेकिन इसे बनाए रखना उतना आसान नहीं है, और इसे सही करने के बजाए परीक्षण करने के लिए वर्कअराउंड्स को नियोजित करता है। – Suamere

+0

जब निजी सार्वजनिक चीजों को बनाए रखने के लिए कठिन होता है ... मुझे अक्सर आश्चर्य होता है कि यह उन सभी भाषाओं पर कैसे लागू होगा जिनके पास सार्वजनिक/निजी जैसे रूबी/जावास्क्रिप्ट/आदि नहीं है ... –

+1

कोई भाषा चुनते समय , आप हार्डवेयर पर अधिक से अधिक सोच सकते हैं, और कोड बेस के रखरखाव की ताकत के बारे में सोचते हैं। आप भाषा की ताकत पर भी विचार करते हैं। सी # की मुख्य ताकत में टाइप-सेफ, कचरा-एकत्रित, जेनेरिक, दोस्ताना मूल संरचना इत्यादि शामिल हैं। सिर्फ इसलिए कि एक और भाषा (अपनी ताकत के साथ) सी # के बारे में टिप्पणी से मेल नहीं खाती है, इसका मतलब यह नहीं है कि टिप्पणी प्रासंगिक है। जावास्क्रिप्ट की मुख्य ताकत यह है कि यह टाइप-सुरक्षित नहीं है। यह हल होने वाली समस्याओं के लिए सबसे अच्छा है। इसके अलावा, आप जावास्क्रिप्ट में निजी सदस्यों के पास बहुत अच्छी तरह से हो सकते हैं। – Suamere

0

कोई प्रतिक्रियाशील WinForms कोड के लिए Reactive.UI के साथ एमवीवीएम (मॉडल-व्यू-व्यू मॉडेल) पैटर्न को नियोजित कर सकता है। चिंताओं को अलग करने के लिए वास्तव में जरूरत है। देखें: Reactive.UI https://reactiveui.net/ Winforms/MVVM/Reactive.UI का उपयोग करने का मुख्य नकारात्मक हिस्सा यह है कि इसके उपयोग के कई उदाहरण नहीं हैं (WinForms के लिए)। उलझन यह है कि यह केवल सभी डेस्कटॉप ढांचे और भाषाओं के लिए लागू है। आप इसे एक के लिए सीखते हैं, लेकिन सिद्धांत सभी के लिए लागू होते हैं। जब आपके पास बहुत से निजी तरीके हैं, तो यह ठीक है। आईएमएचओ: एक व्यावसायिक प्रक्रिया शुरू करने के लिए सार्वजनिक विधियों का उपयोग करने का प्रयास करें जिसे आप परीक्षण करना चाहते हैं। आप बता सकते हैं कि पूछें: https://martinfowler.com/bliki/TellDontAsk.html और अभी भी उन सभी विधियों को निजी रखें।

कोई यूआई चलाकर कोड का परीक्षण भी कर सकता है लेकिन इसकी अत्यधिक अनुशंसा नहीं की जाती है, क्योंकि परिणामी परीक्षण (1) बहुत नाजुक होते हैं, (2) काम करने के लिए कठिन होता है, और आईएमएचओ, (3) नहीं कर सकता शुद्ध कोड परीक्षण के रूप में ठीक समानता के समान स्तर पर लिखा जाना चाहिए; (4) अंत में: यदि आप डेटाबेस का उपयोग करते हैं, तो आपको इसे टेस्ट डेटा के साथ पॉप्युलेट करने पर विचार करना होगा, और, क्योंकि प्रत्येक डेटाबेस प्रत्येक परीक्षण से पहले एक साफ, अच्छी तरह से परिभाषित स्थिति में होना चाहिए, (5) आपके परीक्षण धीमे हो सकते हैं आपके विचार से आप प्रत्येक परीक्षण के लिए डेटा को फिर से शुरू कर सकते हैं।

सारांश: अच्छा कोड (उदा। एमवीवीएम लागू करके) के साथ अपना कोड लेखक, तो आपके कोड में बेहतर परीक्षण क्षमता होगी।

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