वास्तविक दुनिया में, किसी और के कोड के लिए यूनिट परीक्षण लिखना पूरी तरह से सामान्य है। निश्चित रूप से, मूल डेवलपर को यह पहले से ही करना चाहिए था, लेकिन अक्सर आपको विरासत कोड प्राप्त होता है जहां यह अभी नहीं किया गया था। वैसे, इससे कोई फर्क नहीं पड़ता कि वह विरासत कोड दशकों पहले एक आकाशगंगा से दूर, बहुत दूर से आया था, या क्या आपके सहकर्मियों में से किसी ने पिछले सप्ताह इसकी जाँच की थी, या क्या आपने इसे आज लिखा है, विरासत कोड बिना परीक्षणों के कोड है
अपने आप से पूछें: हम इकाई परीक्षण क्यों लिखते हैं? गोइंग ग्रीन स्पष्ट रूप से अंत का एक साधन है, अंतिम लक्ष्य परीक्षण के तहत कोड के बारे में दावे को साबित करना या रोकना है।
मान लें कि आपके पास एक विधि है जो फ्लोटिंग-पॉइंट संख्या के वर्गमूल की गणना करती है। जावा में, इंटरफ़ेस इसे इस प्रकार परिभाषित करेगा:
public double squareRoot(double number);
इससे कोई फर्क नहीं पड़ता है कि आपने कार्यान्वयन लिखा है या किसी और ने किया है, आप वर्ग-गुण के कुछ गुणों पर जोर देना चाहते हैं:
- यह sqrt (4.0) की तरह साधारण जड़ें लौटा सकता है
- यह एक वास्तविक सटीक sqrt (2.0) की तरह एक वास्तविक जड़ पा सकते हैं
- यह पाता है कि sqrt (0.0) 0.0 है
- यह एक अवैध संख्या फेंकता है जब एक नकारात्मक संख्या खिलाया जाता है, यानी sqrt (-1.0) पर
इसलिए आप इन्हें व्यक्तिगत परीक्षण के रूप में लिखना शुरू करते हैं:
@Test
public void canFindSimpleRoot() {
assertEquals(2, squareRoot(4), epsilon);
}
ओह, यह परीक्षण पहले से ही विफल है:
java.lang.AssertionError: Use assertEquals(expected, actual, delta) to compare floating-point numbers
आप फ़्लोटिंग पॉइंट अंकगणित के बारे में भूल गए। ठीक है, तुम परिचय double epsilon=0.01
और जाओ:
@Test
public void canFindSimpleRootToEpsilonPrecision() {
assertEquals(2, squareRoot(4), epsilon);
}
और अन्य परीक्षण जोड़ें: अंत में
@Test
@ExpectedException(IllegalArgumentException.class)
public void throwsExceptionOnNegativeInput() {
assertEquals(-1, squareRoot(-1), epsilon);
}
और उफ़, फिर से:
java.lang.AssertionError: expected:<-1.0> but was:<NaN>
आपको परीक्षण करना चाहिए:
@Test
public void returnsNaNOnNegativeInput() {
assertEquals(Double.NaN, squareRoot(-1), epsilon);
}
हमने यहाँ क्या किया है? हमने कुछ मान्यताओं के साथ शुरुआत की कि विधि को कैसे व्यवहार करना चाहिए, और पाया कि सभी सत्य नहीं थे। फिर हमने परीक्षण सूट ग्रीन बनाया, यह लिखकर कि हमारी सही मान्यताओं के अनुसार विधि व्यवहार करती है। अब इस कोड के ग्राहक इस व्यवहार पर भरोसा कर सकते हैं। यदि किसी को स्क्वायर रूट के वास्तविक कार्यान्वयन का आदान-प्रदान किसी और चीज के साथ करना होता है, तो ऐसा कुछ उदाहरण जो वास्तव में NaN को वापस करने के बजाय एक अपवाद को फेंक देता है, हमारे परीक्षण इसे तुरंत पकड़ लेंगे।
यह उदाहरण तुच्छ है, लेकिन अक्सर आपको कोड के बड़े टुकड़े विरासत में मिलते हैं, जहां यह स्पष्ट नहीं होता है कि यह वास्तव में क्या करता है। उस स्थिति में, कोड के चारों ओर एक परीक्षण दोहन रखना सामान्य है। कोड कैसे व्यवहार करना चाहिए, इसके बारे में कुछ बुनियादी मान्यताओं के साथ शुरू करें, उनके लिए इकाई परीक्षण लिखें, परीक्षण करें। यदि ग्रीन, अच्छा है, तो अधिक परीक्षण लिखें। यदि रेड, ठीक है, अब आपके पास एक असफल दावा है जिसे आप एक कल्पना के खिलाफ पकड़ सकते हैं। हो सकता है कि विरासत कोड में एक बग हो। शायद इस विशेष इनपुट के बारे में कल्पना अस्पष्ट है। शायद आपके पास कोई युक्ति नहीं है। उस मामले में, परीक्षण को फिर से लिखें जैसे कि यह अप्रत्याशित व्यवहार का दस्तावेजीकरण करता है:
@Test
public void throwsNoExceptionOnNegativeInput() {
assertNotNull(squareRoot(-1)); // Shouldn't this fail?
}
समय के साथ, आप एक परीक्षण दोहन के साथ समाप्त होते हैं जो दस्तावेज़ों को बताता है कि कोड वास्तव में कैसे व्यवहार करता है, और एक कोडित कल्पना की तरह बन जाता है। यदि आप कभी भी विरासत कोड को बदलना चाहते हैं, या इसे किसी और चीज़ से बदलना चाहते हैं, तो आपके पास यह सत्यापित करने के लिए परीक्षण कोड है कि नया कोड समान व्यवहार करता है, या यह कि नया कोड अपेक्षित और नियंत्रित तरीकों से भिन्न व्यवहार करता है (उदाहरण के लिए कि वास्तव में आप इसे ठीक करने की उम्मीद बग को ठीक करता है)। इस दोहन को पहले दिन पूरा होने की जरूरत नहीं है, वास्तव में, एक अपूर्ण दोहन होना लगभग हमेशा बेहतर होता है, जिसमें कोई हार्नेस न हो। एक दोहन होने का मतलब है कि आप अपने ग्राहक कोड को अधिक आसानी से लिख सकते हैं, आप जानते हैं कि जब आप कुछ बदलते हैं, तो चीजों को तोड़ने की उम्मीद करते हैं, और जब वे अंततः टूट गए तो वे कहां टूट गए।
आपको इस मानसिकता से बाहर निकलने की कोशिश करनी चाहिए कि आपको यूनिट टेस्ट केवल इसलिए लिखना है क्योंकि आपको एक फॉर्म पर अनिवार्य फ़ील्ड भरना होगा। और आपको केवल लाल रेखा को हरा बनाने के लिए इकाई परीक्षण नहीं लिखना चाहिए। यूनिट टेस्ट आपके दुश्मन नहीं हैं, यूनिट टेस्ट आपके दोस्त हैं।