टेस्ट जनरेटर एक ट्रैक-विशिष्ट सॉफ्टवेयर होता है, जो किसी प्रैक्टिस अभ्यास के टेस्ट अपने आप बना देता है। यह अभ्यास के JSON टेस्ट केसों को ट्रैक की भाषा के टेस्ट में बदलकर ऐसा करता है।
टेस्ट जनरेटर होने के कुछ लाभ ये हैं:
आम तौर पर टेस्ट जनरेटर इन दो में से किसी एक काम के लिए चलाया जाता है:
किसी नए अभ्यास के लिए टेस्ट जनरेटर जोड़ने पर आप उसकी टेस्ट फाइलें बना सकते हैं। अगर टेस्ट जनरेटर खुद पहले से बन चुका हो, तो नए अभ्यास के टेस्ट बनाना उन्हें शुरू से लिखने से (कहीं) कम मेहनत का काम होगा।
किसी अभ्यास में टेस्ट जनरेटर आ जाने के बाद, आप उसे दोबारा चलाकर अभ्यास को उसके नवीनतम कैनोनिकल डेटा के साथ अपडेट या सिंक कर सकते हैं। हमारा सुझाव है कि आप समय-समय पर ऐसा करें, ताकि देख सकें कि कहीं कोई ऐसा टेस्ट केस तो नहीं जिसे अपडेट करना ज़रूरी है, या कोई नया टेस्ट जिसे आप शामिल करना चाहते हैं।
किसी अभ्यास के लिए टेस्ट जनरेटर बनाते समय शुरुआत दो जगह से हो सकती है:
अगर टेस्ट पहले से मौजूद हैं, तो टेस्ट जनरेटर ऐसे बनाइए कि उससे बनने वाले टेस्ट मौजूदा हल न तोड़ें।
मोटे तौर पर, टेस्ट फाइलें इन दो तरीकों से बनाई जाती हैं:
हमने देखा है कि कोड आधारित तरीके में टेस्ट जनरेटर का कोड काफी जटिल हो जाता है, जबकि टेम्पलेट आधारित तरीका आसान होता है।
हम यह क्रम अपनाने का सुझाव देते हैं:
tests.toml फाइल में include = false के रूप में चिह्नित टेस्ट केसों को छोड़ दीजिएइस व्यवस्था का मुख्य लाभ यह है कि हर अभ्यास का अपना टेम्पलेट होता है, जो:
टेस्ट जनरेटर डिज़ाइन करते समय कोशिश कीजिए कि:
टेस्ट जनरेटर आमतौर पर (ज़्यादातर) ट्रैक की भाषा में ही लिखा जाता है।
आप दूसरी भाषाएँ इस्तेमाल करने के लिए स्वतंत्र हैं, लेकिन हर अतिरिक्त भाषा ट्रैक को बनाए रखना या उसमें योगदान देना और मुश्किल बना देती है। इसलिए हमारा सुझाव है कि जहाँ संभव हो, ट्रैक की भाषा ही इस्तेमाल कीजिए, क्योंकि इससे उसे बनाए रखना और उसमें योगदान देना आसान हो जाता है।
अगर आपके ट्रैक में कोड फॉर्मैट करने का टूल है, तो टेम्पलेट रेंडर करने के बाद इसे पोस्ट-प्रोसेसिंग के तौर पर चलाने पर विचार कीजिए।
टेस्ट जनरेटर जिस मुख्य डेटा के साथ काम करता है, वह अभ्यास की canonical-data.json फाइल है।
यह फाइल exercism/problem-specifications रिपॉज़िटरी में परिभाषित होती है, जो Exercism के कई अभ्यासों के लिए साझा मेटाडेटा तय करती है।
सभी अभ्यासों में canonical-data.json फाइल नहीं होती!
जिन अभ्यासों में यह नहीं होती, उनके टेस्ट आपको खुद बनाने पड़ेंगे, क्योंकि टेस्ट जनरेटर के काम करने के लिए कोई डेटा ही नहीं होगा।
कैनोनिकल डेटा एक JSON ऑब्जेक्ट में परिभाषित होता है।
इस ऑब्जेक्ट में एक "cases" फील्ड होता है, जिसमें टेस्ट केस होते हैं।
ये टेस्ट केस (आमतौर पर) आपके ट्रैक के टेस्ट से एक-से-एक मेल खाते हैं।
हर टेस्ट केस में कुछ प्रॉपर्टी होती हैं, जिनमें description, property, input वैल्यू और expected वैल्यू सबसे ज़रूरी होती हैं। यहाँ लीप अभ्यास की canonical-data.json फाइल का एक (आंशिक) उदाहरण है:
{
"exercise": "leap",
"cases": [
{
"uuid": "6466b30d-519c-438e-935d-388224ab5223",
"description": "year not divisible by 4 in common year",
"property": "leapYear",
"input": {
"year": 2015
},
"expected": false
},
{
"uuid": "4fe9b84c-8e65-489e-970b-856d60b8b78e",
"description": "year divisible by 4, not divisible by 100 in leap year",
"property": "leapYear",
"input": {
"year": 1996
},
"expected": true
}
]
}
टेस्ट जनरेटर की मुख्य ज़िम्मेदारी इस JSON डेटा को ट्रैक-विशिष्ट टेस्ट में बदलना है। ऊपर का JSON Nim टेस्ट कोड में ऐसे बदला जा सकता है:
import unittest
import leap
suite "Leap":
test "year not divisible by 4 in common year":
check isLeapYear(2015) == false
test "year divisible by 4, not divisible by 100 in leap year":
check isLeapYear(1996) == true
canonical-data.json फाइल की संरचना को अच्छी तरह से डॉक्युमेंट किया गया है, और उसकी एक JSON स्कीमा परिभाषा भी है।
कुछ अभ्यासों में उनके कैनोनिकल डेटा में नेस्टिंग का उपयोग होता है।
इसका मतलब है कि cases ऐरे का हर एलिमेंट इन दो में से एक हो सकता है:
किसी एलिमेंट का प्रकार यह देखकर पहचाना जा सकता है कि उसमें ऐसी फील्ड हैं या नहीं जो सिर्फ एक ही प्रकार के एलिमेंट में आती हैं।
ऐसा करने का सबसे अच्छा तरीका शायद "cases" कुंजी का उपयोग करना है, जो सिर्फ टेस्ट केस समूहों में ही होती है।
यहाँ नेस्टेड टेस्ट केसों का एक उदाहरण है:
{
"cases": [
{
"uuid": "e9c93a78-c536-4750-a336-94583d23fafa",
"description": "data is retained",
"property": "data",
"input": {
"treeData": ["4"]
},
"expected": {
"data": "4",
"left": null,
"right": null
}
},
{
"description": "insert data at proper node",
"cases": [
{
"uuid": "7a95c9e8-69f6-476a-b0c4-4170cb3f7c91",
"description": "smaller number at left node",
"property": "data",
"input": {
"treeData": ["4", "2"]
},
"expected": {
"data": "4",
"left": {
"data": "2",
"left": null,
"right": null
},
"right": null
}
}
]
}
]
}
अगर आपका ट्रैक टेस्ट को समूहों में बाँटना नहीं देता, तो आपको यह करना होगा:
cases पदानुक्रम को पार करना या चपटा करना, ताकि अंत में सिर्फ सबसे अंदर वाले (लीफ) टेस्ट केस ही बचेंटेस्ट केस की input और expected कुंजियों में जो होता है, वह बहुत अलग-अलग तरह का होता है।
ज़्यादातर मामलों में ये स्केलर वैल्यू (जैसे संख्याएँ, बूलियन या स्ट्रिंग) या साधारण ऑब्जेक्ट होती हैं।
लेकिन कभी-कभी ऐसी ज़्यादा जटिल वैल्यू भी मिलती हैं, जिनके लिए थोड़ी प्री-प्रोसेसिंग की ज़रूरत पड़ सकती है, जैसे स्यूडो कोड में लैम्ब्डा, छात्र के कोड पर करने वाले ऑपरेशनों की सूची, और भी बहुत कुछ।
टेस्ट केसों में एक वैकल्पिक scenarios फील्ड होता है।
टेस्ट जनरेटर इस फील्ड का उपयोग कुछ खास टेस्ट केसों को अलग तरीके से संभालने के लिए कर सकता है।
सबसे आम उपयोग यह है कि कुछ तरह के टेस्ट छोड़ दिए जाएँ, जैसे "unicode" परिदृश्य वाले टेस्ट, क्योंकि आपके ट्रैक की भाषा शायद Unicode सपोर्ट न करती हो।
परिदृश्यों की पूरी सूची यहाँ मिल जाएगी।
canonical-data.json फाइलें पढ़ने के कुछ विकल्प हैं:
problem-specifications रिपॉज़िटरी से लाइए (जैसे https://raw.githubusercontent.com/exercism/problem-specifications/main/exercises/leap/canonical-data.json)।problem-specifications रेपो को ट्रैक रेपो में Git सबमॉड्यूल के तौर पर जोड़िए।configlet कैश से पढ़िए।
इसकी जगह उपयोगकर्ता के सिस्टम पर निर्भर करती है, लेकिन जगह प्रोग्राम के ज़रिए पाने के लिए आप configlet info -o -v d | head -1 | cut -d " " -f 5 चला सकते हैं।अगर आपका ट्रैक कुछ अतिरिक्त, ट्रैक-विशिष्ट टेस्ट केस जोड़ना चाहता है (जो कैनोनिकल डेटा में नहीं मिलते), तो एक विकल्प यह है कि आप एक additional-test-cases.json फाइल बनाइए। इसके बाद टेस्ट जनरेटर उसे रेंडरिंग के लिए टेम्पलेट को सौंपने से पहले canonical-data.json फाइल के साथ मिला सकता है।
जो टेम्पलेट इंजन इस्तेमाल होगा, वह शायद ट्रैक-विशिष्ट ही होगा। आदर्श रूप से आप चाहेंगे कि आपके टेम्पलेट जितने सीधे-सरल हो सकें, उतने हों, इसलिए कोड डुप्लीकेशन जैसी चीज़ों की चिंता न कीजिए।
टेम्पलेट अपना डेटा टेस्ट जनरेटर से लेते हैं, और रेंडर करने के लिए उसी डेटा पर इटरेशन करते हैं।
टेम्पलेट को सरल रखने में मदद के लिए यह अच्छा रहेगा कि टेस्ट जनरेटर की तरफ थोड़ी प्री-प्रोसेसिंग कर ली जाए, या फिर कुछ "फिल्टर" बना लिए जाएँ, या आपके टेम्पलेट जो भी एक्सटेंशन का तरीका देते हों, वह इस्तेमाल किया जाए।
configlet ट्रैक बनाए रखने का मुख्य टूल है और इसका उपयोग इन कामों के लिए किया जा सकता है:
bin/configlet create --practice-exercise <slug> चलाइएtests.toml फाइल सिंक करना: bin/configlet sync --tests --update --exercise <slug> चलाइएइसी वजह से configlet टेस्ट जनरेटर के साथ मिलाकर बहुत काम के वर्कफ्लो बनाने के लिए शानदार टूल है।
आप चाहेंगे कि टेस्ट जनरेटर का इस्तेमाल आसान भी हो और शक्तिशाली भी। इसके लिए हम एक या अधिक स्क्रिप्ट फाइलें बनाने का सुझाव देते हैं।
आप कोई भी स्क्रिप्ट फाइल फॉर्मैट चुन सकते हैं, जो आपके ट्रैक के लिए सबसे अच्छा बैठे। Shell स्क्रिप्ट और PowerShell स्क्रिप्ट आम विकल्प हैं, और दोनों अच्छी तरह काम कर सकते हैं।
यहाँ एक shell स्क्रिप्ट का उदाहरण है, जो configlet और टेस्ट जनरेटर को मिलाकर नया अभ्यास जल्दी से बना देती है:
bin/fetch-configlet
bin/configlet create --practice-exercise <slug>
path/to/test-generator <slug>
टेस्ट जनरेटर बनाना शुरू करने से पहले हमारा सुझाव है कि आप कुछ मौजूदा टेस्ट जनरेटर देख लें, ताकि अंदाज़ा हो जाए कि दूसरे ट्रैक ने इन्हें कैसे बनाया है:
अगर आपके कोई सवाल हैं, तो उन्हें पूछने की सबसे अच्छी जगह फोरम है। Rust टेस्ट जनरेटर के बारे में और JavaScript टेस्ट जनरेटरों पर हुई फोरम चर्चाएँ भी आपके काम आ सकती हैं।
हमारा सुझाव है कि टेस्ट जनरेटर को थोड़ा-थोड़ा करके बनाइए, और शुरुआत न्यूनतम व्यवहार्य उत्पाद से कीजिए।
सबसे बुनियादी वर्ज़न बस इतना करेगा कि वह अभ्यास की canonical-data.json पढ़े और उस डेटा को सीधे टेम्पलेट को सौंप दे।
शुरुआत एक ही अभ्यास पर ध्यान देकर कीजिए, और बेहतर होगा कि वह leap जैसा आसान अभ्यास हो।
जब वह काम करने लगे, तभी धीरे-धीरे और अभ्यास जोड़िए।
और टेस्ट जनरेटर को जितना सरल रख सकें, उतना सरल रखने की कोशिश कीजिए।
आदर्श रूप से एक योगदानकर्ता बिना यह समझे कि टेस्ट जनरेटर अंदर से कैसे काम करता है, किसी मौजूदा टेम्पलेट को चिपका या बदल सके।
किसी टेस्ट जनरेटर का इस्तेमाल कैसे करें या उसमें योगदान कैसे दें, यह ट्रैक पर निर्भर करता है।
निर्देश ट्रैक की README.md, CONTRIBUTING.md या टेस्ट जनरेटर के कोड वाली डायरेक्टरी में देखिए।