Οι Test Runners έχουν τη μία και μοναδική ευθύνη να παίρνουν μια λύση, να εκτελούν όλα τα test και να επιστρέφουν μια τυποποιημένη έξοδο. Όλες οι αλληλεπιδράσεις με τον ιστότοπο του Exercism γίνονται αυτόματα και δεν αποτελούν μέρος αυτής της προδιαγραφής.
two-fer)./tmp για προσωρινά αρχεία (π.χ. για τη μεταγλώττιση πηγαίων αρχείων).results.json στον κατάλογο εξόδου.Ο test runner έχει στη διάθεσή του 100% της CPU και 3GB μνήμης για ένα παράθυρο 20 δευτερολέπτων ανά λύση. Μετά από 20 δευτερόλεπτα, η διεργασία σταματά και αναφέρει timeout.
Συνιστούμε ανεπιφύλακτα να ακολουθήσεις το έγγραφο με τις βέλτιστες πρακτικές απόδοσης για να μειώσεις την πιθανότητα timeout.
Τα παρακάτω πεδία υποστηρίζονται στα αρχεία results.json:
κλειδί:
version, τύπος:number, παρουσία: υποχρεωτική
έκδοση: 1, 2, 3
Η έκδοση της προδιαγραφής την οποία ακολουθεί αυτό το αρχείο:
1: Για track των οποίων ο test runner δεν μπορεί να παρέχει πληροφορίες για μεμονωμένα test.2: Για track των οποίων ο test runner μπορεί να εμφανίζει πληροφορίες για μεμονωμένα test. Ελάχιστη απαιτούμενη έκδοση για track με Concept Exercises.3: Για track των οποίων ο test runner μπορεί να συνδέει μεμονωμένα test με μια εργασία.κλειδί:
status, τύπος:string, παρουσία: υποχρεωτική
έκδοση: 1, 2, 3
Οι παρακάτω συνολικές καταστάσεις είναι έγκυρες:
pass: Όλα τα test πέρασανfail: Τουλάχιστον ένα test έχει κατάσταση fail ή error
error: Δεν εκτελέστηκε κανένα test (αυτό συνήθως σημαίνει σφάλμα μεταγλώττισης ή συντακτικό σφάλμα)Η κατάσταση error θα πρέπει να χρησιμοποιείται μόνο αν όλα τα test παρουσίασαν σφάλμα.
Στις μεταγλωττιζόμενες γλώσσες αυτό είναι συνήθως αποτέλεσμα του ότι ο κώδικας δεν μπορεί να μεταγλωττιστεί.
Στις διερμηνευόμενες γλώσσες πρόκειται για σφάλμα χρόνου εκτέλεσης, όπως ένα συντακτικό σφάλμα που εμποδίζει το αρχείο να αναλυθεί.
κλειδί:
message, τύπος:string, παρουσία: υποχρεωτική ανstatus=error, ή ότανstatus=failκαιversion=1
έκδοση: 1, 2, 3
Όταν η κατάσταση είναι error (δεν εκτελέστηκε σωστά κανένα test), θα πρέπει να παρέχεται το κλειδί message του ανώτατου επιπέδου. Θα πρέπει να δείχνει στον χρήστη το σφάλμα που προέκυψε. Καθώς είναι η μόνη πληροφορία που θα λάβει ο χρήστης για το πώς να κάνει debug στο πρόβλημά του, πρέπει να είναι όσο το δυνατόν πιο σαφής:
<solution-dir>/relative/path αντί για /full/path/to, καθώς αλλιώς θα περιλαμβάνουν άχρηστα δεδομένα ειδικά για το ECRΣτη Ruby, σε περίπτωση συντακτικού σφάλματος, παρέχουμε το σφάλμα χρόνου εκτέλεσης και το ίχνος στοίβας. Στις μεταγλωττιζόμενες γλώσσες, θα πρέπει να παρέχεται το σφάλμα μεταγλώττισης.
Η τιμή του κλειδιού message του ανώτατου επιπέδου περιορίζεται σε 65535 χαρακτήρες.
Το πραγματικό μέγιστο μήκος είναι μικρότερο αν η τιμή περιέχει χαρακτήρες πολλών byte.
Όταν η κατάσταση δεν είναι error, είτε όρισε την τιμή σε null είτε παρέλειψε εντελώς το κλειδί.
κλειδί:
tests, τύπος:array, παρουσία: υποχρεωτική ανstatus=failήstatus=pass
έκδοση: 2, 3
Πρόκειται για έναν πίνακα με τα αποτελέσματα των test, όπως προσδιορίζονται στην ενότητα "Ανά test" παρακάτω.
Τα test ΠΡΕΠΕΙ να επιστρέφονται με τη σειρά που καθορίζονται στο αρχείο test. Για γλώσσες που εκτελούν τα test με τυχαία σειρά, αυτό μπορεί να σημαίνει αναδιάταξη των αποτελεσμάτων ώστε να συμφωνούν με τη σειρά που καθορίζεται στο αρχείο test.
Ο λόγος είναι ότι στους μαθητές εμφανίζεται μόνο η πρώτη αποτυχία και επομένως είναι σημαντικό να εμφανίζεται η σωστή αποτυχία. Επειδή τα test στο αρχείο test είναι γενικά ταξινομημένα με τρόπο TDD, και επειδή στα Practice Exercises οι μαθητές βλέπουν το αρχείο test στον editor, η ευθυγράμμιση των αποτελεσμάτων με το αρχείο test είναι κρίσιμη.
κλειδί:
name, τύπος:string, παρουσία: υποχρεωτική
έκδοση: 2, 3
Είναι το όνομα του test σε μορφή αναγνώσιμη από τον άνθρωπο.
κλειδί:
test_code, τύπος:string, παρουσία: υποχρεωτική αν η άσκηση είναι Concept Exercise
έκδοση: 2, 3
Αυτό ΠΡΕΠΕΙ να υπάρχει για τα Concept Exercises και ΣΥΝΙΣΤΑΤΑΙ να υπάρχει για τα Practice Exercises.
Η διαφορά σε αυτή την απαίτηση προκύπτει από το γεγονός ότι στα Concept Exercises τα test δεν εμφανίζονται στους μαθητές, οπότε η επίλυση της άσκησης μπορεί να είναι αδύνατη χωρίς να εμφανίζεται το test_code, ενώ στα Practice Exercises τα test εμφανίζονται.
Είναι το σώμα της εντολής που ελέγχεται. Για παράδειγμα, το παρακάτω test σε 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
Οι παρακάτω καταστάσεις ανά test είναι έγκυρες:
pass: Το test πέρασεfail: Το test απέτυχεerror: Το test παρουσίασε σφάλμα, δηλαδή δεν επέστρεψε κάποια τιμήκλειδί:
message, τύπος:string, παρουσία: υποχρεωτική αν τοstatusείναιfailήerror
έκδοση: 2, 3
Το κλειδί message ανά test χρησιμοποιείται για να επιστρέφει τα αποτελέσματα ενός test του οποίου το status είναι fail ή error. Θα πρέπει να είναι όσο το δυνατόν πιο αναγνώσιμο από τον άνθρωπο. Ό,τι γράφεται εδώ θα εμφανίζεται στον μαθητή όταν το test του δεν περνάει. Αν δεν υπάρχει μήνυμα αποτυχίας ή μήνυμα σφάλματος, είτε όρισε την τιμή σε null είτε παρέλειψε εντελώς το κλειδί. Επιτρέπεται επίσης να βάλεις εδώ την έξοδο της σουίτας test. Η τιμή του message δεν έχει όριο μήκους.
κλειδί:
output, τύπος:string, παρουσία: προαιρετική
έκδοση: 2, 3
Το κλειδί output ανά test θα πρέπει να χρησιμοποιείται για την αποθήκευση και την εμφάνιση οτιδήποτε εμφανίζει ο χρήστης σκόπιμα για ένα test.
puts στη Ruby, print στην Python ή Debug.WriteLine στη C#), είτε να παρέχεις μια μέθοδο που μπορεί να χρησιμοποιήσει ο χρήστης (π.χ. ο Test Runner της Ruby παρέχει στον χρήστη μια καθολικά διαθέσιμη μέθοδο debug, την οποία μπορεί να χρησιμοποιήσει και η οποία έχει τα ίδια χαρακτηριστικά με την τυπική μέθοδο puts).κλειδί:
task_id, τύπος:number, παρουσία: προαιρετική
έκδοση: 3
Σύνδεσε ένα test με μια συγκεκριμένη εργασία μέσω του ID της εργασίας, δηλαδή του αριθμού που χρησιμοποιείται στην αρχή της επικεφαλίδας της εργασίας. Σύνδεσε ένα test με μια εργασία μόνο αν μπορεί να συνδεθεί με μία ακριβώς εργασία.
Προς το παρόν, μόνο τα Concept Exercises έχουν καλά ορισμένες εργασίες με τις οποίες μπορείς να συνδέσεις test, αλλά αυτό μπορεί να αλλάξει στο μέλλον.
Για παράδειγμα, δες το παρακάτω αρχείο 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());"
}
Αυτό το test είναι τώρα συνδεδεμένο με την πρώτη εργασία: "Define the expected oven time in minutes". Σημείωσε ότι το όνομα δεν χρειάζεται να ταιριάζει με την περιγραφή της εργασίας.
Υπάρχουν διάφοροι τρόποι με τους οποίους τα track θα μπορούσαν να το υλοποιήσουν:
.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, θα πρέπει να εμφανίζει κάτι σαν αυτό:
Test Code:
<test_code>
Test Result:
<message>
Όταν η λύση περνάει ένα test, θα πρέπει να εμφανίζει κάτι σαν αυτό:
Test Code:
<test_code>
Όλοι οι δρόμοι οδηγούν στη Ρώμη και δεν υπάρχει προκαθορισμένος τρόπος για να φτάσεις εκεί. Μέχρι τώρα έχουν ακολουθηθεί αρκετές προσεγγίσεις: