2012-01-12 18 views
10

परीक्षण के लिए उपयोग किए गए डमी डेटा का प्रबंधन कैसे करते हैं? उन्हें अपनी संबंधित संस्थाओं के साथ रखें? एक अलग परीक्षण परियोजना में? उन्हें बाह्य संसाधनों से एक सीरिएलाइज़र के साथ लोड करें? या जहां भी जरूरत हो उन्हें फिर से बनाएँ?मॉड्यूलर एप्लिकेशन स्टैक में डमी डेटा और यूनिट परीक्षण रणनीतियों

हमारे पास प्रत्येक युक्त इकाइयों के साथ दूसरे मॉड्यूल के साथ कई मॉड्यूल के साथ एक एप्लिकेशन स्टैक है। प्रत्येक मॉड्यूल के अपने परीक्षण होते हैं और साथ चलने के लिए डमी डेटा की आवश्यकता होती है।

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

इसके अलावा: हमारी संस्थाओं में सबसे अधिक क्षेत्रों ताकि वस्तु परत के खिलाफ भी चल लेनदेन व्यर्थ नहीं कर रहे हैं उन्हें कुछ मान होना चाहिए की आवश्यकता है, विशिष्टता, लंबाई, आदि

की तरह आगे सीमाओं के साथ समय के सबसे अधिक है वहाँ एक इस से सबसे अच्छा अभ्यास तरीका या सभी समाधान समझौता कर रहे हैं?


अधिक विस्तार

हमारे ढेर इस तरह दिखता है:

एक मॉड्यूल:

src/main/java --> gets jared (.../entities/*.java contains the entities) 
src/main/resources --> gets jared 
src/test/java --> contains dummy object setup, will NOT get jared 
src/test/resources --> not jared 

हम Maven का उपयोग निर्भरता को संभालने के लिए।

मॉड्यूल उदाहरण:

  • मॉड्यूल एक कुछ डमी वस्तुओं
  • है
  • मॉड्यूल बी अपनी ही वस्तुओं और मॉड्यूल एक के रूप में ही

विकल्प एक की जरूरत है)

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

विकल्प ख)

मॉड्यूल एक जबकि एकके बारे में बी की डमी डेटा

पता नहीं है बी उन्हें प्राप्त करने के लिए अनुमति src/main/java../entities/dummy में कहीं डमी वस्तुओं प्रदान करता है विकल्प सी)

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

विकल्प घ)

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

क्या हम

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


क्या मेरे विचार सही दिशा में जा रहे हैं? परीक्षणों से निपटने के लिए सबसे अच्छा अभ्यास क्या है जिसके लिए बहुत सारे डेटा की आवश्यकता होती है? हमारे पास कई परस्पर निर्भर मॉड्यूल होंगे जिनके लिए कई अन्य मॉड्यूल से किसी प्रकार के डेटा से भरी वस्तुओं की आवश्यकता होगी।


संपादित

कैसे हम दूसरे जवाब के जवाब में अभी भी कर रहे हैं पर कुछ अधिक जानकारी:

तो सादगी के लिए, हम तीन मॉड्यूल है: Person, Product, OrderPerson एक MockPerson वस्तु का उपयोग कर कुछ प्रबंधक तरीकों का परीक्षण होगा:

(व्यक्ति में/src/परीक्षण/जावा :)

public class MockPerson { 

    public Person mockPerson(parameters...) { 
     return mockedPerson; 
    } 
} 

public class TestPerson() { 
    @Inject 
    private MockPerson mockPerson; 
    public testCreate() { 
     Person person = mockPerson.mockPerson(...); 
     // Asserts... 
    } 
} 

MockPerson वर्ग पैक नहीं किया जाएगा।

एक ही उत्पाद टेस्ट मैचों के लिए लागू होता है:

(उत्पाद में/src/परीक्षण/जावा :)

public class MockProduct() { ... } 
public class TestProduct { 
    @Inject 
    private MockProduct mockProduct; 
    // ... 
} 

MockProduct की जरूरत है लेकिन पैक नहीं किया जाएगा।

अब आदेश टेस्ट MockPerson और MockProduct की आवश्यकता होगी, इसलिए अब हम वर्तमान में दोनों बनाने के रूप में अच्छी तरह के रूप में MockOrderOrder का परीक्षण करने की जरूरत है।

(आदेश/src/परीक्षण/जावा में :)

इन डुप्लिकेट हैं और हर बार Person या Product बदलता है

public class MockProduct() { ... } 
public class MockPerson() { ... } 

यह केवल वर्ग है परिवर्तित करने की आवश्यकता होगी यह यहां होना चाहिए:

public class MockOrder() { ... } 

public class TestOrder() { 
    @Inject 
    private order.MockPerson mockPerson; 
    @Inject 
    private order.MockProduct mockProduct; 
    @Inject 
    private order.MockOrder mockOrder; 
    public testCreate() { 

     Order order = mockOrder.mockOrder(mockPerson.mockPerson(), mockProduct.mockProduct()); 
     // Asserts... 
    } 
} 

probl एम है, अब हमें person.MockPerson और order.MockPerson अपडेट करना होगा जब भी Person बदल दिया गया हो।

क्या मैक्स के साथ सिर्फ मोक्स प्रकाशित करना बेहतर नहीं है ताकि वैसे भी निर्भरता वाले हर दूसरे टेस्ट को मॉक.मॉक पर कॉल कर सकें और अच्छी तरह से सेटअप ऑब्जेक्ट प्राप्त कर सकें? या यह अंधेरा पक्ष है - आसान तरीका?

उत्तर

3

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

मैं usaully क्या किया है (और AFAIKT जावा में इस सबसे अच्छा अभ्यास है) के रूप में अपने Test Data Builders पोस्ट में Nat Pryce द्वारा वर्णित, टेस्ट डाटा बिल्डर पैटर्न का उपयोग करने की कोशिश है।

यदि आपको लगता है यह कुछ हद तक प्रासंगिक है, इन पर गौर करें:

+0

अरे cwash! कारखाने सूचक के लिए धन्यवाद। मुझे एक रेल ट्यूटोरियल में इसका उपयोग याद है;) यह समाधान हो सकता है, मुझे इसे और जांचना होगा। – Pete

+0

@Pete - ठंडा, क्या आप एक नोट/अपडेट छोड़ सकते हैं जो हमें बता रहा है कि आपने क्या तय किया है? – cwash

+0

तो, ऐसा लगता है कि हम इसे केंद्रीय डमी डेटा प्रदाता के रूप में उपयोग कर सकते हैं। अंत में हालांकि यह सिर्फ विकल्प ए है) जिसका अर्थ है कि कुछ बाहरी परियोजना में सभी आवश्यक डेटा जेनरेटर होंगे। अभी भी सोच रहा है कि क्या यह जाने का सबसे अच्छा तरीका है। इस पर कुछ और राय प्राप्त करने की उम्मीद है .. – Pete

1

मुझे आश्चर्य है कि क्या आप अपने परीक्षण दृष्टिकोण को बदलकर अपनी समस्या का समाधान नहीं कर पाएंगे।

यूनिट एक मॉड्यूल का परीक्षण करना जो अन्य मॉड्यूल पर निर्भर करता है और इसके कारण, अन्य मॉड्यूल के परीक्षण डेटा पर वास्तविक इकाई परीक्षण नहीं है!

यदि आप परीक्षण के तहत अपने मॉड्यूल की सभी निर्भरताओं के लिए एक नकली इंजेक्ट करेंगे तो आप पूर्ण अलगाव में इसका परीक्षण कर सकते हैं। फिर आपको एक पूर्ण वातावरण स्थापित करने की आवश्यकता नहीं है, जहां प्रत्येक निर्भर मॉड्यूल में आवश्यक डेटा होता है, आप केवल मॉड्यूल के लिए डेटा सेट करते हैं जो वास्तव में परीक्षण करता है।

यदि आप एक पिरामिड की कल्पना करते हैं, तो आधार आपके यूनिट परीक्षण होंगे, ऊपर आपके पास कार्यात्मक परीक्षण होंगे और शीर्ष पर आपके पास कुछ परिदृश्य परीक्षण होंगे (या जैसे Google उन्हें, छोटे, मध्यम और बड़े परीक्षण कहते हैं)।

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

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

सीवाश द्वारा उल्लिखित बिल्डर पैटर्न निश्चित रूप से आपके कार्यात्मक परीक्षणों में मदद करेगा। हम एक .NET बिल्डर का उपयोग कर रहे हैं जो एक पूर्ण ऑब्जेक्ट पेड़ बनाने के लिए कॉन्फ़िगर किया गया है और प्रत्येक प्रॉपर्टी के लिए डिफ़ॉल्ट मान जेनरेट करता है, इसलिए जब हम इसे डेटाबेस में सहेजते हैं तो सभी आवश्यक डेटा मौजूद होते हैं।

+0

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

+0

@Pete मैं कोई जावा डेवलपर नहीं हूं, तो क्या आप कृपया बता सकते हैं कि आप क्या मतलब रखते हैं: 'समस्या यह है कि अब हमें व्यक्ति को अपडेट करना होगा। मॉकपर्सन और ऑर्डर। जब भी व्यक्ति बदल जाता है तो मॉकपर्सन।' आपको क्या बदलना है? क्या आप केवल उन गुणों और विधियों का नकल नहीं करते हैं जो महत्वपूर्ण हैं? –

+0

शायद मेरा प्रश्न कुल मिलाकर बहुत लंबा है इसलिए निरंतर विवरण चुनना मुश्किल है। क्षमा करें ... मैंने वर्णन किया है कि हमें सभी फ़ील्ड का नकल कैसे करना है क्योंकि अधिकांश 'nullable = false' हैं। इसलिए यदि मैं 'व्यक्ति' इकाई में एक नया कॉलम जोड़ता हूं, तो मुझे प्रत्येक मॉड्यूल में मॉकपर्सन के सभी अवसरों पर मॉकिंग जोड़नी होगी। – Pete

3

ठीक है, मैंने अब तक सभी मूल्यांकन सावधानी से पढ़ा है, और यह बहुत अच्छा सवाल है। मैं समस्या के लिए निम्नलिखित दृष्टिकोण देखता हूं:

  1. सेट (स्थैतिक) परीक्षण डेटा बेस;
  2. प्रत्येक परीक्षण में यह स्वयं का सेट अप डेटा होता है जो यूनिट परीक्षण चलाने से पहले (गतिशील) परीक्षण डेटा बनाता है;
  3. डमी या नकली वस्तु का उपयोग करें। सभी मॉड्यूल सभी डमी ऑब्जेक्ट्स जानते हैं, इस तरह कोई डुप्लिकेट नहीं है;
  4. यूनिट परीक्षण के दायरे को कम करें;

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

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

तीसरा विकल्प अच्छा होना चाहिए विकल्प ए) और डी) मेरे लिए बहुत अच्छा लगता है। अपने डमी ऑब्जेक्ट के लिए आप नकली ढांचे का उपयोग कर सकते हैं या आप इसका उपयोग नहीं कर सकते हैं। मॉक फ्रेमवर्क केवल आपकी मदद करने के लिए है। मुझे समस्या नहीं दिख रही है कि आपकी सभी इकाइयां आपकी सभी संस्थाओं को जानती हैं।

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

+0

हे! इनपुट के लिए धन्यवाद। खासकर चौथा विकल्प दिलचस्प था। आप सही हैं, हम वास्तव में यूनिट परीक्षण नहीं बल्कि एकीकरण परीक्षण नहीं करते हैं, क्योंकि हम उच्च मॉड्यूल में यूनिट परीक्षण में आवश्यक वस्तुओं को बनाने के लिए निचले मॉड्यूल से प्रबंधक फ़ंक्शंस का आह्वान करते हैं, इस प्रकार निचले स्तर पर निम्न मॉड्यूल की कार्यक्षमता का परीक्षण करते हैं। मुझे एहसास है कि यह परीक्षण सख्ती से स्वतंत्र नहीं है। मुझे लगता है कि हमने सोचा था: ओह ठीक है, तो यह सिर्फ सभी मॉड्यूल के लिए परीक्षण घनत्व में वृद्धि करेगा। मुझे लगता है कि मुझे इकाई परीक्षण बनाम एकीकरण परीक्षण की उपयोगिता पर पढ़ना चाहिए ... – Pete

+1

@Pete यह बिल्कुल सही बात है। आपको यह सुनिश्चित करने की ज़रूरत है कि आप अलगाव में अपने कार्यों का परीक्षण कर सकते हैं। परीक्षण डेटा उत्पन्न करने के लिए प्रत्येक निर्भरता का मज़ाक उड़ाकर और बिल्डर का उपयोग करना। यह भी सुनिश्चित करें कि आप डेमेटर के कानून को ध्यान में रखें (जब आपको केवल पते की आवश्यकता हो तो पूरे ग्राहक को पास न करें) क्योंकि इससे आपका कोड बेहतर परीक्षण योग्य होगा। –