2009-07-09 17 views
14

मेरे पास एक कक्षा है जो वस्तुओं के एक सेट को क्रमबद्ध करती है (एक्सएमएल क्रमबद्धता का उपयोग करके) कि मैं इकाई परीक्षण करना चाहता हूं।क्या कोई इकाई यूनिट परीक्षण क्रमबद्धता है?

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

मुझे लगता है कि सवाल (वहाँ 3 लेकिन वे सभी संबंधित) मैं अंततः पर प्रतिक्रिया के लिए देख रहा हूँ कर रहे हैं:

  1. यह रीडर का उपयोग किए बिना लेखक परीक्षण करने के लिए, संभव है?
  2. पाठक (एक्सएमएल फ़ाइल? रिकॉर्ड/प्लेबैक के साथ मॉकिंग) का परीक्षण करने के लिए सबसे अच्छी रणनीति क्या है? क्या यह मामला है कि आप वास्तव में क्या कर रहे हैं उन वस्तुओं के संपत्ति मूल्यों का परीक्षण करना जो deserialized किया गया है?
  3. लेखक का परीक्षण करने के लिए सबसे अच्छी रणनीति क्या है! Xml क्रमबद्धता पर

पृष्ठभूमि की जानकारी

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

public class MyObject 
{ 
    public string Name { get;set; } 
    public int Age { get;set; } 

    [XmlAttribute] 
    public int Height { get;set; } 
} 

और वीजा प्रतिकूल करने के लिए नक्शे होगा एक उदाहरण

<MyObject Height="300"> 
    <Name>Bob</Name> 
    <Age>20</Age> 
<MyObject> 

है। यदि ऑब्जेक्ट नीचे एक्सएमएल में बदल गया है तो सफलतापूर्वक deserialize होगा, लेकिन फर्स्टनाम खाली हो जाएगा।

public class MyObject 
{ 
    public string FirstName { get;set; } 
    public int Age { get;set; } 

    [XmlAttribute] 
    public int Height { get;set; } 
} 

एक अमान्य XML फ़ाइल सही तरीके deserialize होता है, इसलिए इकाई परीक्षण से होकर गुजरेगा जब तक आप MyObject के मूल्यों पर दावे भाग गया।

उत्तर

19

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

आप का उल्लेख है कि आप एक स्कीमा ... क्यों नहीं एक उत्पन्न नहीं है? या तो हाथ से (यह बहुत कठिन नहीं है), या xsd.exe के साथ। फिर आपके पास टेम्पलेट के रूप में उपयोग करने के लिए कुछ है, और आप इसे XmlReader का उपयोग करके सत्यापित कर सकते हैं। मैं इस समय एक्सएमएल क्रमबद्धता के साथ काम का एक बहुत कर रहा हूँ, और यह की तुलना में इसके बारे में है कि क्या मैं डेटा सही हो रही है चिंता करने की है स्कीमा अद्यतन करने के लिए बहुत आसान है।

भी XmlSerializer जटिल हो सकता है; खासकर यदि आप उपवर्गों ([XmlInclude]), कस्टम क्रमांकन (IXmlSerializable), या गैर-डिफ़ॉल्ट XmlSerializer निर्माण शामिल (ctor के क्रम में अतिरिक्त मेटाडेटा गुजर)।एक और संभावना [XmlIngore], [XmlAnyAttribute] या [XmlAnyElement] का रचनात्मक उपयोग है; उदाहरण के लिए आप राउंड ट्रिप (केवल) संस्करण एक्स में के लिए अप्रत्याशित डेटा का समर्थन है, लेकिन यह सामान्य रूप में क्रमबद्धता के साथ संस्करण वाई में एक ज्ञात संपत्ति में स्टोर


सकता है:

वजह साफ है: आप डेटा तोड़ सकते हैं! आप यह कितनी बुरी तरह से serializer पर निर्भर करता है; उदाहरण के लिए, BinaryFormatter (और मुझे पता है सवाल XmlSerializer है), बस से बदल रहा है के साथ:

public string Name {get;set;} 

को
private string name; 
public string Name { 
    get {return name;} 
    set {name = value; OnPropertyChanged("Name"); } 
} 

, enough to break serialization हो सकता है के रूप में क्षेत्र का नाम बदल दिया गया है (और BinaryFormatter क्षेत्रों प्यार करता है) ।

ऐसे कई मौके हैं जब आप गलती से डेटा का नाम बदल सकते हैं (यहां तक ​​कि XmlSerializer/DataContractSerializer जैसे अनुबंध-आधारित धारावाहिकों में भी)। ऐसे मामलों में आप आमतौर पर तार पहचानकर्ताओं को ओवरराइड कर सकते हैं (उदाहरण के लिए [XmlAttribute("name")] आदि), लेकिन यह जांचना महत्वपूर्ण है!

आखिरकार, यह नीचे आता है: क्या यह महत्वपूर्ण है कि आप पुराने डेटा को पढ़ सकें? यह आमतौर पर है; तो बस इसे जहाज न करें ... साबित करें कि आप कर सकते हैं।

+0

मूल रूप से यह एक स्कीमा था, और पढ़ना + लेखन मेरी अपनी कक्षा द्वारा किया गया था जिसने ऑब्जेक्ट ग्राफ़ लिखा था। मैं तब (1 साल बाद!) पता चला कि सभी काम XmlSerializer द्वारा किया जा सकता था। पिछड़े संगतता के संदर्भ में, मैं कहूंगा कि एक्सएमएल असेंबली संस्करण से जुड़ा होगा जो इसे लिखा गया था। इसलिए यदि आपने असेंबली का नवीनतम संस्करण पिछले संस्करणों द्वारा उत्पादित कुछ एक्सएमएल दिया है, तो संभावना है कि ऑब्जेक्ट मॉडल बदल गया है, इसलिए यह अब मेल नहीं खाता है। मुझे यकीन नहीं है कि इसके लिए कभी भी ऐसा होगा, लेकिन मैं नहीं देख सकता कि कैसे (cont'd) –

+0

आप पुराने प्रारूप (जैसा कि जॉन उल्लेख करता है) को बिना किसी क्रमबद्ध करना होगा और इसे हमेशा मैन्युअल रूप से निष्पादित करना होगा एक एक्सएमएल रीडर? –

+0

XmlSerializer बिना किसी त्रुटि के अप्रत्याशित डेटा छोड़ देता है, या आप '[XmlAny *] 'का उपयोग कर सकते हैं - इसलिए किसी ऑब्जेक्ट को आंशिक रूप से * deserialize करने के तरीके हैं (और" किसी भी "प्रोप से अन्य डेटा प्राप्त करें)। –

7

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

26

क्या आपको पिछड़े संगतता को करने में सक्षम होना चाहिए? यदि ऐसा है, तो पुराने संस्करणों द्वारा उत्पादित फ़ाइलों के यूनिट परीक्षणों के निर्माण के लायक हो सकते हैं जिन्हें अभी भी नए संस्करणों द्वारा deserialized किया जा सकता है।

उसके अलावा, अगर आप कभी भी कुछ भी "रोचक" परिचय यह एक इकाई परीक्षण के लायक केवल आपके जांच को क्रमानुसार और deserialize कर सकते हैं करने के लिए सिर्फ बनाने के लिए हो सकता है कि आप एक केवल पढ़ने के लिए संपत्ति के साथ आदि कुछ अजीब नहीं कर रहे हैं

+1

हम भविष्य में (पत्ते) गुण जोड़ और निकाल सकते हैं, लेकिन यह नाटकीय रूप से –

+3

नहीं बदलेगा, मैं कहूंगा कि परीक्षण के लायक बनाने के लिए अभी भी पर्याप्त बदलाव है। –

0

कुछ भी नहीं आप जिस तरह से अपनी कक्षा को धारावाहिक को बदलने के लिए कुछ नहीं कर सकता है, तो आप XML क्रमांकन ;-)

0

धारावाहिक एक्सएमएल मामलों के प्रारूप हैं की नेट के कार्यान्वयन का परीक्षण कर रहे हैं, तो आप परीक्षण की आवश्यकता serialization। यदि यह महत्वपूर्ण है कि आप इसे deserialize कर सकते हैं, तो आप deserialization परीक्षण करने की जरूरत है।

5

यदि आप यह सुनिश्चित करना चाहते हैं कि आपकी वस्तुओं का क्रमबद्धता टूट न जाए, तो सभी माध्यमों से यूनिट परीक्षण।आप XMLSerializer वर्ग के लिए MSDN डॉक्स पढ़ें:

XmlSerializer को क्रमानुसार नहीं कर सकते हैं या निम्न deserialize: सूची < की ArrayList
सरणी के

सरणी टी >

वहाँ भी एक अजीब मुद्दा है अनगिनत लम्बाई के रूप में घोषित enums के साथ। इसके अतिरिक्त, [Obsolete] के रूप में चिह्नित किसी भी ऑब्जेक्ट को .NET 3.5 के बाद से क्रमबद्ध नहीं किया जाता है।

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

वास्तव में, आप इकाई परीक्षण एक्सएमएल क्रमबद्धता नहीं हैं, आप परीक्षण कर रहे हैं कि आपके वस्तुओं धारावाहिक जा सकता है। वही deserialization के लिए लागू होता है।

0

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

बोलते हुए, मैंने हाल ही में एक अभ्यास अपनाया है जहां मैं यूनिट परीक्षणों के निष्पादन के बजाए संकलन-समय पर ऐसी चीजों की जांच करता हूं। यह थोड़ा कठिन है, लेकिन मेरे पास एक घटक है जो एएसटी को पार कर सकता है, और फिर मैं इसे टी 4 टेम्पलेट में पढ़ सकता हूं और #error संदेशों को लिख सकता हूं अगर मैं ऐसा कुछ नहीं मिलता जो वहां नहीं होना चाहिए।

+0

क्षमा करें, यह गलत है। धारावाहिक होने वाले वर्गों में विशेषताओं को जोड़कर आप एक्सएमएल सीरियलाइजेशन के कई विवरणों को बहुत प्रभावित कर सकते हैं। –

+1

व्याख्या की बात हो सकती है - लेकिन मुझे "धारावाहिक तंत्र के साथ * जिस तरह से * इंटरैक्ट * * का परीक्षण करने का परीक्षण किया गया है" में यह परीक्षण शामिल है कि आपके द्वारा रखे गए गुणों के तरीके से आप जिस तरह से सोचते हैं। आप परीक्षण नहीं कर रहे हैं कि किसी संपत्ति को क्रमबद्ध किया जा सकता है, आप परीक्षण कर रहे हैं कि ** इस प्रॉपर्टी ** की कॉन्फ़िगरेशन को सही तरीके से कॉन्फ़िगर किया गया है या नहीं। – Bevan

1

मैं कुछ मामलों में यह किया है ... इस तरह के रूप क्रमबद्धता का परीक्षण नहीं, लेकिन कुछ 'के नाम से अच्छा' एक्सएमएल serializations उपयोग करके और फिर उन्हें अपने वर्गों में लोड हो रहा है, और यह जांच (जो लागू हो) सभी गुण है अपेक्षित मूल्य

यह पहले संस्करण के लिए कुछ भी परीक्षण करने वाला नहीं है ... लेकिन यदि कक्षाएं विकसित होती हैं तो मुझे पता है कि मैं प्रारूप में किसी भी तोड़ने वाले बदलाव को पकड़ूंगा।

2

मेरे अनुभव में यह निश्चित रूप से करने योग्य है, खासकर यदि एक्सएमएल उपभोक्ता द्वारा एक्सएमएल दस्तावेज़ के रूप में उपयोग किया जा रहा है। उदाहरण के लिए, उपभोक्ता को दस्तावेज में मौजूद प्रत्येक तत्व की आवश्यकता हो सकती है, या तो स्कीमा सत्यापन को पार करने या पास करने के दौरान नोड्स की शून्य जांच से बचने के लिए।

डिफ़ॉल्ट रूप से एक्सएमएल सीरियलाइज़र गुणों को शून्य मान के साथ छोड़ देगा जब तक कि आप [XmlElement (IsNullable = true) विशेषता नहीं जोड़ते। इसी तरह, आपको जेनेरिक सूची गुणों को XMLArray विशेषता के साथ मानक सरणी में रीडायरेक्ट करना पड़ सकता है।

जैसा कि एक अन्य योगदानकर्ता ने कहा, यदि वस्तु समय के साथ बदल रही है, तो आपको लगातार जांच करनी होगी कि आउटपुट सुसंगत है। यह आपको सीरिएलाइज़र के खिलाफ खुद को बदल देगा और पीछे की तरफ संगत नहीं होगा, हालांकि आपको उम्मीद है कि ऐसा नहीं होगा।

तो छोटे उपयोगों के अलावा किसी अन्य चीज़ के लिए, या जहां उपर्युक्त विचार अप्रासंगिक हैं, यह इकाई परीक्षण के प्रयास के लायक है।

2

ऐसे कई प्रकार हैं जो क्रमबद्धता का सामना नहीं कर सकते हैं आदि। यदि आपके गुण गलत हैं, तो एक्सएमएल को पढ़ने की कोशिश करते समय अपवाद प्राप्त करना आम बात है।

मैं उन ऑब्जेक्ट्स का एक उदाहरण वृक्ष तैयार करता हूं जिन्हें प्रत्येक वर्ग (और सबक्लास) के कम से कम एक उदाहरण के साथ क्रमबद्ध किया जा सकता है। फिर कम से कम ऑब्जेक्ट पेड़ को स्ट्रिंगस्ट्रीम पर क्रमबद्ध करें और फिर इसे स्ट्रिंगस्ट्रीम से वापस पढ़ें।

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

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

2

मैं आपसे सहमत हूं कि आप अपने कोड का परीक्षण करने से अधिक .NET कार्यान्वयन का परीक्षण करेंगे। लेकिन अगर आप यही करना चाहते हैं (शायद आप .NET कार्यान्वयन पर भरोसा नहीं करते हैं :)), मैं आपके तीन प्रश्नों को निम्नानुसार देख सकता हूं।

  1. हां, पाठक के बिना लेखक का परीक्षण करना निश्चित रूप से संभव है। मेमोरीस्ट्रीम को प्रदान किए गए उदाहरण (20-वर्षीय बॉब) को क्रमबद्ध करने के लिए लेखक का उपयोग करें। XmlDocument के साथ मेमोरीस्ट्रीम खोलें। रूट नोड को "MyObject" नाम दिया गया है। मान लें कि इसमें "ऊंचाई" नामक "ऊंचाई" नामक एक विशेषता है। मान लें कि "बॉब" मान वाला टेक्स्ट नाम नोड वाला "नाम" तत्व है। मान लें कि एक "आयु" तत्व है जिसमें "20" मान वाला टेक्स्ट नोड होता है।

  2. बस # 1 की रिवर्स प्रक्रिया करें। 20-वर्षीय बॉब एक्सएमएल स्ट्रिंग से XmlDocument बनाएं। पाठक के साथ स्ट्रीम deserialize। नाम संपत्ति "बॉब" के बराबर बताएं। आयु संपत्ति के बराबर बताएं 20. आप चीजों को दोबारा उद्धरण के बजाय कम-से-कम कोट्स के बजाय कमजोर सफेद जगह या सिंगल कोट्स के साथ टेस्ट केस जोड़ सकते हैं।

  3. # 1 देखें। आप इसे "बढ़िया" मामलों के बारे में सोचने के द्वारा बढ़ा सकते हैं जो आपको लगता है कि इसे तोड़ सकता है। विभिन्न यूनिकोड वर्णों के साथ नाम। अतिरिक्त लंबे नाम। खाली नाम नकारात्मक उम्र आदि

1

हम इकाई परीक्षण हमारे क्रमबद्धता का स्वीकृति परीक्षण के बजाय है।

इसका अर्थ यह है कि हमारी स्वीकृति परीक्षक एक्सएमएल स्कीमा लेते हैं, या आपके मामले में कुछ नमूना एक्सएमएल लेते हैं, और अपने स्वयं के क्रमिक डेटा-ट्रांसफर क्लास को फिर से बनाते हैं।

हम फिर इस स्वच्छ कमरे एक्सएमएल के साथ हमारी डब्ल्यूसीएफ सेवा का परीक्षण करने के लिए एनयूनीट का उपयोग करते हैं।

इस तकनीक के साथ हमने कई, कई त्रुटियों की पहचान की है। उदाहरण के लिए, जहां हमने .NET सदस्य का नाम बदल दिया है और Name = संपत्ति के साथ [XmlElement] टैग जोड़ने के लिए भूल गए हैं।

3

हां, जब तक परीक्षण की आवश्यकता होती है, तब तक हस्तक्षेप के माध्यम से ठीक से परीक्षण किया जाता है।

तथ्य यह है कि आप पहली जगह में क्रमबद्ध और deserializing कर रहे हैं इसका मतलब है कि आप शायद "बाहरी दुनिया" के साथ डेटा का आदान-प्रदान कर रहे हैं - .NET serialization डोमेन के बाहर की दुनिया। इसलिए, आपके परीक्षणों में एक ऐसा पहलू होना चाहिए जो इस डोमेन के बाहर है। रीडर का उपयोग करके लेखक का परीक्षण करना ठीक नहीं है, और इसके विपरीत।

यह केवल इतना नहीं है कि आप .NET serialization/deserialization का परीक्षण करना समाप्त कर देंगे या नहीं; आपको बाहरी दुनिया के साथ अपने इंटरफ़ेस का परीक्षण करना होगा - कि आप अपेक्षित प्रारूप में एक्सएमएल आउटपुट कर सकते हैं और आप अनुमानित प्रारूप में एक्सएमएल का सही ढंग से उपभोग कर सकते हैं।

आपके पास स्थिर XML डेटा होना चाहिए जिसका उपयोग धारावाहिक आउटपुट के विरुद्ध तुलना करने और deserialization के लिए इनपुट डेटा के रूप में उपयोग करने के लिए किया जा सकता है।

आप नोट लेने और नोट्स एक ही पुरुष के लिए वापस पढ़ने की नौकरी दे मान लें:

 
You - Bob, I want you to jot down the following: "small yellow duck." 
Bob - OK, got it. 
You - Now, read it back to me. 
Bob - "small yellow duck" 

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

 
You - Bob, I want you to jot down the following: "small yellow duck." 
Bob - OK, got it. 
You - Alice, can you please check what Bob wrote? 
Alice - OK, he's got it. 
You - Alice, can you please jot down a few words? 
Alice - Done. 
You - Bob, can you please read them? 
Bob - "red fox" 
Alice - Yup, that sounds right. 

अब हम निश्चितता के साथ, पता है,:

अब की तस्वीर के लिए ऐलिस परिचय करते हैं। स्टेटिक एक्सएमएल डेटा (आदर्श रूप से एक स्कीमा के खिलाफ परीक्षण किया गया) पर्याप्त रूप से भरोसेमंद होना चाहिए।

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