JUnit @Parameters का उपयोग करके उदाहरण के साथ पैरामीटरीकृत परीक्षण
⚡ स्मार्ट सारांश
पैरामीटराइज्ड परीक्षणों में JUnit एक ही परीक्षण विधि को अलग-अलग इनपुट मानों के साथ बार-बार चलाएँ, ताकि एक ही विधि कई परिदृश्यों को कवर कर सके। @RunWith और @Parameters एनोटेशन प्रत्येक पुनरावृति के लिए डेटा सेट प्रदान करते हैं।
पैरामीटराइज्ड टेस्ट क्या होता है? JUnit?
A पैरामीटराइज्ड परीक्षण यह एक ऐसा परीक्षण है जो अलग-अलग मानों का उपयोग करके एक ही परीक्षण विधि को बार-बार निष्पादित करता है। यह डेवलपर्स को उन परीक्षणों को लिखने में समय बचाने में मदद करता है जो केवल इनपुट और अपेक्षित परिणामों में भिन्न होते हैं।
पैरामीटराइज्ड टेस्ट का उपयोग करके, एक टेस्ट विधि स्थापित की जा सकती है जो किसी डेटा स्रोत से डेटा प्राप्त करती है। यह इसे सबसे सरल रूप बनाता है। डेटा-संचालित परीक्षण अंदर उपलब्ध है JUnit यह स्वयं ही काम करता है, इसके लिए किसी बाहरी लाइब्रेरी की आवश्यकता नहीं होती।
एक साधारण परीक्षण पर विचार करें जो विभिन्न संख्याओं का योग करता है। कोड कुछ इस तरह दिख सकता है:
ऊपर बताए गए तरीके से बहुत अधिक दोहराव होता है। संख्याओं के प्रत्येक नए जोड़े के लिए उसी विधि के भीतर एक और असर्ट स्टेटमेंट की आवश्यकता होती है, और पहले असर्ट स्टेटमेंट की विफलता उसके बाद आने वाले सभी असर्ट स्टेटमेंट को छिपा देती है।
एक सरल दृष्टिकोण की आवश्यकता है। पैरामीटराइज्ड टेस्ट का उपयोग करके आप एक ऐसा मेथड जोड़ सकते हैं जो दस डेटा इनपुट प्रदान करता है, और आपका टेस्ट स्वचालित रूप से दस बार चलेगा।
पैरामीटराइज़्ड बनाने के चरण JUnit टेस्ट
निम्नलिखित कोड पैरामीटराइज्ड टेस्ट का एक उदाहरण दिखाता है। यह Airthematic क्लास के sum() मेथड का परीक्षण करता है, जो कि पूरे सैंपल प्रोजेक्ट में प्रयुक्त वर्तनी है।
चरण 1) एक क्लास बनाएं। इस उदाहरण में, हम sum(int, int) विधि का उपयोग करके दो संख्याएँ इनपुट के रूप में लेंगे, जो दी गई संख्याओं का योगफल लौटाएगी।
चरण 2) एक पैरामीटराइज्ड टेस्ट क्लास बनाएं।
Code व्याख्या
- Code रेखा 11: @RunWith(Parameterized.class) का उपयोग करके अपनी टेस्ट क्लास को एनोटेट करें।
- Code रेखा 13: 'firstNumber' चर को निजी तथा प्रकार को int घोषित करना।
- Code रेखा 14: 'secondNumber' नामक वेरिएबल को प्राइवेट और टाइप को int घोषित किया जा रहा है।
- Code रेखा 15: 'expectedResult' नामक वेरिएबल को प्राइवेट और टाइप को int घोषित करना।
- Code रेखा 16: 'airthematic' नामक चर को निजी और प्रकार को Airthematic घोषित करना।
@साथ चलाएं(क्लास_नाम.क्लास): @साथ चलाएं एनोटेशन का उपयोग रनर क्लास का नाम निर्दिष्ट करने के लिए किया जाता है। यदि हम पैरामीटर के रूप में कोई प्रकार निर्दिष्ट नहीं करते हैं, तो रनटाइम स्वयं ही चयन करेगा। खंडJUnit4क्लासरनर डिफ़ॉल्ट रूप से
यह क्लास नए टेस्ट इंस्टेंस के साथ टेस्ट चलाने के लिए ज़िम्मेदार है। यह इनवोक करने के लिए ज़िम्मेदार है। JUnit लाइफसाइकिल विधियाँ जैसे सेटअप (संसाधनों को संबद्ध करना) और टियरडाउन (संसाधनों को मुक्त करना), जिनका वर्णन इसमें किया गया है JUnit परीक्षण स्थिरता ट्यूटोरियल।
पैरामीटराइजेशन के लिए, आपको @RunWith का उपयोग करके क्लास को एनोटेट करना होगा और परीक्षण के लिए आवश्यक .class फ़ाइल पास करनी होगी।
चरण 3) एक कंस्ट्रक्टर बनाएं जो टेस्ट डेटा को स्टोर करे। इसमें 3 वेरिएबल स्टोर होंगे।
चरण 4) एक स्थैतिक विधि बनाएं जो परीक्षण डेटा उत्पन्न करे और लौटाए।
Code रेखा 32,33: दो-आयामी ऐरे बनाना (जोड़ने के लिए इनपुट पैरामीटर प्रदान करना)। asList विधि का उपयोग करके हम डेटा को List प्रकार में परिवर्तित करते हैं, क्योंकि इनपुट विधि का रिटर्न प्रकार Collection है।
Code रेखा 30: ऊपर दिए @पैरामीटर हमारे परीक्षण को चलाने के लिए इनपुट डेटा का एक सेट बनाने के लिए एनोटेशन।
@Parameters एनोटेशन द्वारा पहचाना गया स्थैतिक तरीका एक कलेक्शन लौटाता है, जिसमें प्रत्येक प्रविष्टि परीक्षण के एक पुनरावृति के लिए इनपुट डेटा होगी। तत्व {1,2,3} पर विचार करें। यहाँ:
- पहला नंबर = 1
- दूसरा नंबर = 2
- अपेक्षित परिणाम = 3
यहां, क्लास को कई बार इंस्टैंशिएट किए जाने के कारण, प्रत्येक एरे एलिमेंट को एक-एक करके कंस्ट्रक्टर को पास किया जाएगा। इसलिए, उदाहरण में घोषित पांच एरे निम्नलिखित पांच परिणाम उत्पन्न करते हैं:
| यात्रा | पहला नंबर | दूसरा नंबर | अपेक्षित परिणाम | कंसोल लाइन |
|---|---|---|---|---|
| [0] | 1 | 2 | 3 | का योग Numbers = : 3 |
| [1] | 11 | 22 | 33 | का योग Numbers = : 33 |
| [2] | 111 | 222 | 333 | का योग Numbers = : 333 |
| [3] | 10 | 9 | 19 | का योग Numbers = : 19 |
| [4] | 100 | 9 | 109 | का योग Numbers = : 109 |
चरण 5) पूरा कोड।
Code स्पष्टीकरण:
- Code रेखा 25: संसाधनों को सेट अप करने के लिए @Before एनोटेशन का उपयोग किया जा रहा है (यहाँ Airthematic.class फ़ाइल का उपयोग किया गया है)। प्रत्येक टेस्ट केस से पहले @Before एनोटेशन का उपयोग किया जाता है। इसमें टेस्ट की पूर्व शर्त शामिल होती है।
- Code रेखा 36: हम अपने टेस्ट को बनाने के लिए @Test एनोटेशन का उपयोग कर रहे हैं।
- Code रेखा 39: एक बनाना अभिकथन यह जांचने के लिए कि हमारा योग हमारी अपेक्षा के बराबर है या नहीं।
चरण 6) पैरामीटराइज्ड टेस्ट चलाने के लिए एक टेस्ट रनर क्लास बनाएं:
Code स्पष्टीकरण:
- Code रेखा 8: क्लास टेस्ट के मुख्य मेथड को घोषित करना जो हमारे कोड को चलाएगा JUnit परीक्षण.
- Code रेखा 9: टेस्ट केस निष्पादित करना JUnitCore.runClasses, जो टेस्ट क्लास का नाम एक पैरामीटर के रूप में लेता है (हमारे उदाहरण में हम AirthematicTest.class का उपयोग कर रहे हैं)।
- Code रेखा 11: परिणाम को फॉर लूप का उपयोग करके संसाधित करना और असफल परिणाम को प्रिंट करना।
- Code रेखा 13: सफल परिणाम का मुद्रण करना।
आउटपुट:
यह आउटपुट है, जो बिना किसी विफलता के सफल परीक्षण को दर्शाता है। trace, जैसा कि नीचे दिया गया है। ध्यान दें कि JUnit व्यू प्रत्येक डेटा पंक्ति में एक प्रविष्टि को सूचीबद्ध करता है, न कि एक एकल परीक्षण को:
कंसोल पर परिणाम देखें, जो दोनों संख्याओं का योग दर्शाता है:
पैरामीटराइज्ड टेस्ट में JUnit 5 with @ParameterizedTest
ऊपर दिया गया उदाहरण इसके लिए लिखा गया है JUnit 4. JUnit 5 (बृहस्पति) रनर मॉडल को पूरी तरह से हटा देता है, इसलिए @RunWith(Parameterized.class), डेटा कंस्ट्रक्टर और इंस्टेंस फ़ील्ड सभी गायब हो जाते हैं। JUnit ऊपर दिखाया गया कोड अप्रचलित नहीं है: यह अभी भी बिना किसी बदलाव के चलता है। JUnit यह प्लेटफ़ॉर्म पुराने इंजन के माध्यम से काम करता है। हालाँकि, नए परीक्षण आमतौर पर @ParameterizedTest का उपयोग करके लिखे जाते हैं।
दो निर्भरताएँ आवश्यक हैं: परीक्षण एनोटेशन के लिए junit-jupiter-api और junit-jupiter-params पैरामीटराइज्ड सपोर्ट के लिए। दूसरे आर्टिफैक्ट के बिना सोर्स एनोटेशन बिल्कुल भी हल नहीं होंगे।
import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; class AirthematicTest { // one row per iteration, no constructor and no runner @ParameterizedTest(name = "{0} + {1} = {2}") @CsvSource({"1, 2, 3", "11, 22, 33", "111, 222, 333", "10, 9, 19", "100, 9, 109"}) void sumOfTwoNumbers(int firstNumber, int secondNumber, int expectedResult) { assertEquals(expectedResult, new Airthematic().sum(firstNumber, secondNumber)); } }
बृहस्पति ग्रह तर्क के कई स्रोत प्रदान करता है, और सही स्रोत का चुनाव डेटा के स्वरूप पर निर्भर करता है:
| स्रोत एनोटेशन | आपूर्ति | इसका उपयोग तब करें जब |
|---|---|---|
| @ValueSource | लिटरल का एक एकल स्तंभ | यह परीक्षण केवल एक तर्क लेता है। |
| @CsvSource | पंक्तिबद्ध अल्पविराम-पृथक पंक्तियाँ | फ़ाइल में संख्याओं और स्ट्रिंग की छोटी सारणियाँ आसानी से पढ़ी जा सकती हैं। |
| @CsvFileSource | टेस्ट क्लासपाथ पर मौजूद CSV फ़ाइल से पढ़ी गई पंक्तियाँ | डेटा सेट बड़ा है या कोड के बाहर बनाए रखा जाता है। |
| @मेथडसोर्स | एक स्टैटिक फ़ैक्टरी जो आर्गुमेंट्स का एक स्ट्रीम लौटाती है | वास्तविक वस्तुओं, परिकलित मानों या यादृच्छिक डेटा की आवश्यकता होती है। |
| @एनमसोर्स | एक एनम के स्थिरांक | प्रत्येक एनम मान का प्रयोग किया जाना चाहिए |
शुरुआती लोगों को दो नियम भ्रमित कर देते हैं। एक साधारण @Test विधि पर लगाया गया स्रोत एनोटेशन अनदेखा कर दिया जाता है, इसलिए विधि में @ParameterizedTest होना आवश्यक है। और @CsvSource में बिना उद्धरण चिह्नों वाला खाली मान नल के रूप में पढ़ा जाता है, जबकि उद्धरण चिह्नों वाला खाली मान एक खाली स्ट्रिंग के रूप में पढ़ा जाता है।
RSI JUnit इस लेख में उपयोग किए गए 4 एनोटेशन बृहस्पति ग्रह पर इस प्रकार मैप होते हैं: @RunWith(Parameterized.class) @ParameterizedTest प्लस एक स्रोत एनोटेशन बन जाता है, @Parameters @MethodSource या @CsvSource बन जाता है, और @Before @BeforeEach बन जाता है। पूरी सूची में शामिल है। JUnit एनोटेशन ट्यूटोरियल।
पैरामीटराइज्ड परीक्षणों के लाभ और सीमाएँ
पैरामीटराइजेशन मुफ्त नहीं है। यह दोहराव को दूर करता है, लेकिन यह परीक्षण लिखने के तरीके को भी सीमित करता है, इसलिए मौजूदा सूट को परिवर्तित करने से पहले इसके दोनों पहलुओं को जानना महत्वपूर्ण है।
फायदे
- Less दोहराव: एक विधि लगभग एक जैसे असर्ट स्टेटमेंट के एक ब्लॉक को बदल देती है, जैसा कि इस लेख के पहले स्क्रीनशॉट में दिखाया गया है।
- सस्ता कवरेज: एक एज केस जोड़ने से एक पूरी नई डेटा पंक्ति के बजाय एक अतिरिक्त डेटा पंक्ति की लागत आती है। परीक्षण का मामला विधि.
- सटीक रिपोर्टिंग: प्रत्येक पुनरावृति की रिपोर्ट अलग से दी जाती है, इसलिए JUnit यह व्यू किसी एक समग्र विफलता के बजाय, ठीक-ठीक यह पहचान करता है कि कौन सी पंक्ति विफल हुई है।
- केंद्रीकृत डेटा: इनपुट एक ही मेथड में रहते हैं और बाद में उन्हें असर्शन को छुए बिना CSV फ़ाइल या फ़ैक्टरी में ले जाया जा सकता है।
सीमाओं
- अभिकथन का एक रूप: प्रत्येक पंक्ति समान अभिकथन चलाती है, इसलिए जिस परिदृश्य में अलग-अलग जांच की आवश्यकता होती है, उसके लिए अभी भी अपनी अलग परीक्षण विधि की आवश्यकता होती है।
- कक्षा-स्तर का दायरा JUnit 4: रनर पूरी क्लास को पैरामीटराइज़ करता है, इसलिए उस क्लास में असंबंधित @Test मेथड भी प्रति पंक्ति एक बार चलते हैं।
- अपठनीय रिपोर्टें: नाम टेम्पलेट के बिना, विफलताएं testAirthematicTest[3] के रूप में दिखाई देती हैं, जो उस डेटा के बारे में कुछ नहीं कहती है जो टूट गया है।
- भारी इनलाइन डेटा: बड़े एरे टेस्ट लॉजिक को बाधित करते हैं; इसके बजाय उन्हें @CsvFileSource या @MethodSource फ़ैक्टरी में ले जाएं।
सामान्य त्रुटियाँ JUnit पैरामीटराइज्ड टेस्ट
अधिकांश पैरामीटराइज्ड विफलताएं किसी भी अभिकथन के निष्पादन से पहले उत्पन्न होने वाली आरंभिक त्रुटियां होती हैं। नीचे दी गई तालिका में सबसे अधिक बार दिखाई देने वाले संदेशों और उनके कारणों की सूची दी गई है।
| मैसेज | कारण | फिक्स |
|---|---|---|
| टेस्ट क्लास में ठीक एक ही पब्लिक कंस्ट्रक्टर होना चाहिए। | यह क्लास किसी भी सार्वजनिक कंस्ट्रक्टर की घोषणा नहीं करती है, या फिर दो सार्वजनिक कंस्ट्रक्टर घोषित करती है। | एक सार्वजनिक कंस्ट्रक्टर रखें जिसके पैरामीटर डेटा कॉलम से मेल खाते हों। |
| क्लास पर कोई सार्वजनिक स्थिर पैरामीटर विधि नहीं है | @Parameters विधि सार्वजनिक स्थिर नहीं है, या गलत प्रकार लौटाती है। | इसे पब्लिक स्टैटिक कलेक्शन के रूप में घोषित करें और Arrays.asList(…) रिटर्न करें। |
| IllegalArgumentException: तर्कों की संख्या गलत है | एक पंक्ति कंस्ट्रक्टर पैरामीटर सूची से चौड़ी या संकरी होती है। | कलेक्शन में मौजूद प्रत्येक ऐरे की चौड़ाई कंस्ट्रक्टर के समान रखें। |
| कॉन्फ़िगरेशन त्रुटि: कोई तर्क प्रदाता नहीं | जुपिटर टेस्ट में @ParameterizedTest होता है जिसमें कोई सोर्स एनोटेशन नहीं होता है। | @ValueSource, @CsvSource, @CsvFileSource, @MethodSource या @EnumSource जोड़ें |
| स्रोत एनोटेशन का कोई प्रभाव नहीं दिखता। | इस विधि में @ParameterizedTest के बजाय @Test एनोटेशन का उपयोग किया गया है। | @Test को @ParameterizedTest से बदलें और junit-jupiter-params को इम्पोर्ट करें। |
एक और समस्या साझा अवस्था है। क्योंकि JUnit प्रत्येक पंक्ति के लिए एक नया इंस्टेंस बनाता है, स्टैटिक फ़ील्ड में रखी गई कोई भी चीज़ प्रत्येक पुनरावृति में बनी रहती है, और पंक्ति [0] द्वारा लिखा गया मान पंक्ति [4] के परिणाम को चुपचाप बदल सकता है। प्रति-पंक्ति स्थिति को इंस्टेंस फ़ील्ड में रखें और @Before या @BeforeEach विधि में साझा संसाधनों को रीसेट करें। परीक्षणों को अलग करने पर सामान्य मार्गदर्शन इसमें शामिल है। इकाई का परीक्षण ट्यूटोरियल।









