تقع على مشغّلات الاختبارات مسؤولية واحدة: أخذ حل، وتشغيل جميع الاختبارات، وإرجاع مخرجات موحّدة. تتم كل التفاعلات مع موقع Exercism تلقائيًا وليست جزءًا من هذه المواصفات.
two-fer)./tmp للملفات المؤقتة (مثل تصريف المصادر).results.json إلى مجلد المخرجات.يحصل مشغّل الاختبارات على 100% من وحدة المعالجة المركزية (CPU) و3 غيغابايت من الذاكرة خلال نافذة مدتها 20 ثانية لكل حل. بعد 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"
(مع استبدال فواصل الأسطر بـ \n لجعل JSON صالحًا).
المفتاح:
status، النوع:string، الوجود: مطلوب
الإصدار: 2، 3
حالات الاختبار الفردي التالية صالحة:
pass: نجح الاختبار.fail: فشل الاختبار.error: حدث خطأ في الاختبار، أي أنه لم يُرجع قيمة.المفتاح:
message، النوع:string، الوجود: مطلوب إذا كانتstatusهيfailأوerror
الإصدار: 2، 3
يُستخدم المفتاح message الخاص بكل اختبار لإرجاع نتائج اختبار حالته fail أو error. ينبغي أن يكون مقروءًا للبشر قدر الإمكان. أي شيء يُكتب هنا سيُعرض على الطالب عندما لا ينجح اختباره. إذا لم توجد رسالة فشل اختبار أو رسالة خطأ، فإما اضبط القيمة على null أو احذف المفتاح تمامًا. يُسمح أيضًا بإخراج مخرجات مجموعة الاختبارات هنا. قيمة message غير محدودة الطول.
المفتاح:
output، النوع:string، الوجود: اختياري
الإصدار: 2، 3
ينبغي استخدام المفتاح output الخاص بكل اختبار لتخزين وإخراج أي شيء يُخرجه المستخدم عمدًا من أجل اختبار.
puts في Ruby، أو print في Python، أو Debug.WriteLine في C#)، أو يمكنك توفير طريقة يمكن للمستخدم استخدامها (مثل أن يوفر مشغّل اختبارات Ruby للمستخدم طريقة debug متاحة عالميًا يمكنه استخدامها، ولها نفس خصائص طريقة puts القياسية).المفتاح:
task_id، النوع:number، الوجود: اختياري
الإصدار: 3
اربط اختبارًا بمهمة محددة عبر معرّف المهمة، وهو الرقم المستخدم في بداية عنوان المهمة. لا تربط اختبارًا بمهمة إلا إذا أمكن ربطه بمهمة واحدة تحديدًا.
في الوقت الحالي، لا تحتوي سوى التمارين المفاهيمية على مهام محددة جيدًا يمكنك ربط الاختبارات بها، لكن هذا قد يتغير في المستقبل.
على سبيل المثال، انظر إلى ملف 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>
كل الطرق تؤدي إلى روما، ولا يوجد نمط محدد لتحقيق ذلك. هناك عدة مقاربات اتبعت حتى الآن: