टेस्ट रनर का एक ही काम है: एक हल लेना, उसके सारे टेस्ट चलाना और एक मानकीकृत आउटपुट लौटाना। Exercism वेबसाइट के साथ होने वाली सारी बातचीत अपने आप संभाली जाती है और वह इस स्पेक का हिस्सा नहीं है।
two-fer)./tmp इस्तेमाल करना बेहतर है।results.json फाइल लिखनी होगी।हर हल के लिए टेस्ट रनर को 20 सेकंड की अवधि के लिए 100% CPU और 3GB मेमोरी मिलती है। 20 सेकंड बाद प्रोसेस को रोक दिया जाता है और टाइम-आउट की सूचना दी जाती है।
टाइम-आउट की संभावना कम करने के लिए हम प्रदर्शन संबंधी सर्वोत्तम प्रथाओं वाले दस्तावेज़ का पालन करने की पूरी सलाह देते हैं।
results.json फाइलों में ये फील्ड समर्थित हैं:
कुंजी:
version, प्रकार:number, उपस्थिति: आवश्यक
वर्ज़न: 1, 2, 3
यह फाइल जिस स्पेक वर्ज़न का पालन करती है:
1: उन ट्रैकों के लिए जिनके टेस्ट रनर अलग-अलग टेस्ट की जानकारी नहीं दे सकते।2: उन ट्रैकों के लिए जिनके टेस्ट रनर अलग-अलग टेस्ट की जानकारी दे सकते हैं। कॉन्सेप्ट अभ्यास वाले ट्रैकों के लिए यह कम से कम आवश्यक वर्ज़न है।3: उन ट्रैकों के लिए जिनके टेस्ट रनर अलग-अलग टेस्ट को किसी टास्क से जोड़ सकते हैं।कुंजी:
status, प्रकार:string, उपस्थिति: आवश्यक
वर्ज़न: 1, 2, 3
ये समग्र स्टेटस मान्य हैं:
pass: सारे टेस्ट पास हुएfail: कम से कम एक टेस्ट का स्टेटस fail या error हैerror: कोई भी टेस्ट नहीं चला (आमतौर पर इसका मतलब कंपाइल एरर या सिंटैक्स एरर है)error स्टेटस का उपयोग केवल तब करना चाहिए जब सारे टेस्ट में एरर हुआ हो।
कंपाइल होने वाली भाषाओं में यह आमतौर पर कोड के कंपाइल न हो पाने का नतीजा होता है।
इंटरप्रेट होने वाली भाषाओं में यह रनटाइम एरर होती है, जैसे कोई सिंटैक्स एरर जिसकी वजह से फाइल पार्स नहीं हो पाती।
कुंजी:
message, प्रकार:string, उपस्थिति: आवश्यक यदिstatus=error, या जबstatus=failऔरversion=1
वर्ज़न: 1, 2, 3
जब स्टेटस error हो (यानी कोई भी टेस्ट ठीक से नहीं चला), तब टॉप लेवल की message कुंजी देनी चाहिए। इसमें उपयोगकर्ता को हुई एरर बतानी चाहिए। चूँकि अपनी समस्या का पता लगाने के लिए उपयोगकर्ता को यही एकमात्र जानकारी मिलेगी, इसलिए यह जितनी साफ हो सके उतनी साफ होनी चाहिए:
<solution-dir>/relative/path जैसा कुछ लिखिए, /full/path/to जैसा नहीं, क्योंकि उसमें ECR से जुड़ी बेकार जानकारी शामिल होगीRuby में सिंटैक्स एरर होने पर हम रनटाइम एरर और स्टैक ट्रेस देते हैं। कंपाइल होने वाली भाषाओं में कंपाइलेशन एरर दी जानी चाहिए।
टॉप लेवल message वैल्यू अधिकतम 65535 अक्षरों तक सीमित है।
अगर वैल्यू में मल्टीबाइट अक्षर हों तो असल अधिकतम लंबाई इससे कम रहती है।
जब स्टेटस error न हो, तो या तो वैल्यू को null रखिए या कुंजी को पूरी तरह छोड़ दीजिए।
कुंजी:
tests, प्रकार:array, उपस्थिति: आवश्यक यदिstatus=failयाstatus=pass
वर्ज़न: 2, 3
यह टेस्ट नतीजों का ऐरे है, जिसका ब्यौरा नीचे "हर टेस्ट" वाले हिस्से में दिया गया है।
टेस्ट अवश्य उसी क्रम में लौटाए जाने चाहिए जिस क्रम में वे टेस्ट फाइल में लिखे हैं। जो भाषाएँ टेस्ट किसी भी क्रम में चलाती हैं, उनमें इसका मतलब हो सकता है कि नतीजों को टेस्ट फाइल में दिए क्रम के मुताबिक फिर से लगाना पड़े।
इसका कारण यह है कि छात्रों को सिर्फ पहली विफलता दिखाई जाती है, इसलिए यह ज़रूरी है कि सही विफलता दिखे। चूँकि टेस्ट फाइल में टेस्ट आमतौर पर TDD के तरीके से लगे होते हैं, और चूँकि प्रैक्टिस अभ्यासों में छात्र एडिटर में टेस्ट फाइल देखते हैं, इसलिए नतीजों को टेस्ट फाइल के क्रम से मिलाना बहुत ज़रूरी है।
कुंजी:
name, प्रकार:string, उपस्थिति: आवश्यक
वर्ज़न: 2, 3
यह टेस्ट का नाम है, ऐसे रूप में जिसे इंसान पढ़ और समझ सके।
कुंजी:
test_code, प्रकार:string, उपस्थिति: आवश्यक यदि अभ्यास कॉन्सेप्ट अभ्यास हो
वर्ज़न: 2, 3
कॉन्सेप्ट अभ्यासों में यह अवश्य मौजूद होना चाहिए और प्रैक्टिस अभ्यासों में यह मौजूद होना चाहिए।
इस अंतर की वजह यह है कि कॉन्सेप्ट अभ्यासों में छात्रों को टेस्ट नहीं दिखाए जाते, इसलिए test_code दिखाए बिना अभ्यास हल करना नामुमकिन हो सकता है, जबकि प्रैक्टिस अभ्यासों में टेस्ट दिखाए जाते हैं।
यह उस कमांड का मुख्य हिस्सा है जिसकी जाँच हो रही है। उदाहरण के लिए, नीचे दिया गया Ruby टेस्ट:
def test_duplicate_items_uniqs_list
cart = ShoppingCart.new
cart.add(:STARIC)
cart.add(:MEDNEW)
cart.add(:MEDNEW)
assert_equal 'Newspaper, Rice', cart.items_list
end
से test_code की यह वैल्यू लौटनी चाहिए:
"cart = ShoppingCart.new
cart.add(:STARIC)
cart.add(:MEDNEW)
cart.add(:MEDNEW)
assert_equal 'Newspaper, Rice', cart.items_list"
(JSON को मान्य बनाने के लिए लाइनब्रेक की जगह \n रखा गया है)।
कुंजी:
status, प्रकार:string, उपस्थिति: आवश्यक
वर्ज़न: 2, 3
हर टेस्ट के लिए ये स्टेटस मान्य हैं:
pass: टेस्ट पास हुआfail: टेस्ट विफल हुआerror: टेस्ट में एरर आया, यानी उसने कोई वैल्यू नहीं लौटाईकुंजी:
message, प्रकार:string, उपस्थिति: आवश्यक यदिstatusfailयाerrorहो
वर्ज़न: 2, 3
हर टेस्ट की message कुंजी का उपयोग ऐसे टेस्ट का नतीजा लौटाने के लिए होता है जिसका status fail या error हो। यह जितनी इंसानी पढ़ने लायक हो सके, उतनी होनी चाहिए। यहाँ जो कुछ लिखा जाएगा, वह छात्र को तब दिखाया जाएगा जब उसका टेस्ट पास नहीं होगा। अगर टेस्ट विफलता का संदेश या एरर संदेश न हो, तो या तो वैल्यू null रखिए या कुंजी पूरी तरह छोड़ दीजिए। यहाँ टेस्ट सूट का आउटपुट देना भी मान्य है। message वैल्यू की लंबाई पर कोई सीमा नहीं है।
कुंजी:
output, प्रकार:string, उपस्थिति: वैकल्पिक
वर्ज़न: 2, 3
हर टेस्ट की output कुंजी का उपयोग उस सब कुछ को संग्रहीत करने और दिखाने के लिए करना चाहिए जो उपयोगकर्ता किसी टेस्ट के लिए जानबूझकर आउटपुट करता है।
puts, Python में print या C# में Debug.WriteLine), या ऐसा मेथड दे सकते हैं जिसका उपयोग उपयोगकर्ता कर सके (जैसे Ruby टेस्ट रनर उपयोगकर्ता को एक ऐसा debug मेथड देता है जो हर जगह उपलब्ध है और जिसकी विशेषताएँ मानक puts मेथड जैसी ही हैं)।कुंजी:
task_id, प्रकार:number, उपस्थिति: वैकल्पिक
वर्ज़न: 3
टेस्ट को टास्क की ID के ज़रिए किसी खास टास्क से जोड़िए; यह ID टास्क के शीर्षक की शुरुआत में इस्तेमाल हुई संख्या होती है। टेस्ट को किसी टास्क से तभी जोड़िए जब उसे ठीक एक टास्क से जोड़ा जा सकता हो।
फिलहाल सिर्फ कॉन्सेप्ट अभ्यासों में ही ऐसे सुस्पष्ट टास्क होते हैं जिनसे आप टेस्ट जोड़ सकते हैं, लेकिन आगे यह बदल सकता है।
उदाहरण के लिए, नीचे दी गई instructions.md फाइल देखिए:
# Instructions
You're going to write some code to help Lucian cook an exquisite lasagna from his favorite cook book.
## 1. Define the expected oven time in minutes
...
## 2. Calculate the remaining oven time in minutes
...
इन निर्देशों में दो टास्क तय किए गए हैं:
तब results.json फाइल में ऐसी एंट्री हो सकती है:
{
"name": "Expected oven time in minutes",
"status": "pass",
"task_id": 1,
"test_code": "Assert.Equal(40, Lasagna.ExpectedMinutesInOven());"
}
अब यह टेस्ट पहले टास्क से जुड़ा है: "मिनटों में ओवन का अपेक्षित समय तय कीजिए"। ध्यान दीजिए कि नाम का टास्क के विवरण से मेल खाना ज़रूरी नहीं है।
ट्रैक इसे कई तरह से लागू कर सकते हैं:
.meta/config.json फाइल) और इस जानकारी को बनी हुई results.json फाइल में मिला दीजिए।अलग-अलग वर्ज़न के लिए एक मान्य results.json फाइल कैसी दिख सकती है, इसके उदाहरण ये हैं:
{
"version": 1,
"status": "fail",
"message": "Failed: test_answer\nExpected: 42, actual: 3"
}
{
"version": 2,
"status": "fail",
"message": null,
"tests": [
{
"name": "Test that the thing works",
"status": "fail",
"message": "Expected 42 but got 123123",
"output": "Debugging information output by the user",
"test_code": "assert_equal 42, answerToTheUltimateQuestion()"
}
]
}
{
"version": 3,
"status": "fail",
"message": null,
"tests": [
{
"name": "Test that the thing works",
"status": "fail",
"message": "Expected 42 but got 123123",
"output": "Debugging information output by the user",
"test_code": "assert_equal 42, answerToTheUltimateQuestion()",
"task_id": 1
}
]
}
जब छात्र का हल किसी टेस्ट में विफल हो, तो कुछ ऐसा दिखना चाहिए:
Test Code:
<test_code>
Test Result:
<message>
जब हल किसी टेस्ट को पास करे, तो कुछ ऐसा दिखना चाहिए:
Test Code:
<test_code>
हर रास्ता रोम की ओर जाता है और इस तक पहुँचने का कोई तय तरीका नहीं है। अब तक कई तरीके अपनाए गए हैं: