測試執行器的單一職責,是接收一份解答、執行所有測試,並回傳標準化的輸出。 與 Exercism 網站的所有互動都會自動處理,不屬於本規格的內容。
two-fer)。/tmp。results.json 檔案。每個解答,測試執行器會獲得 100% CPU 與 3GB 記憶體,時間視窗為 20 秒。 20 秒後,行程會遭到中止並回報逾時。
我們強烈建議遵循我們的效能最佳實務文件,以降低逾時的機率。
results.json 檔案支援以下欄位:
鍵:
version,型別:number,存在性:必填
版本:1、2、3
此檔案所遵循的規格版本:
1:適用於測試執行器無法提供個別測試資訊的 track。2:適用於測試執行器能輸出個別測試資訊的 track。具有 Concept Exercise 的 track 所需的最低版本。3:適用於測試執行器能將個別測試連結至任務的 track。鍵:
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 的方式在測試檔案中排序,而且對於 Practice Exercise,學生會在編輯器中看到測試檔案,因此將結果與測試檔案對齊至關重要。
鍵:
name,型別:string,存在性:必填
版本:2、3
這是測試的名稱,以人類可讀的格式呈現。
鍵:
test_code,型別:string,當練習為 Concept Exercise 時為必填
版本:2、3
對於 Concept Exercise 這是必須存在的,對於 Practice Exercise 則應該存在。這項要求之所以不同,是因為學生在 Concept Exercise 中不會看到測試,因此若不顯示 test_code,可能無法完成練習;相對地,Practice Exercise 則會顯示測試。
這是受測試之指令的主體。例如,以下這個 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 鍵用於回傳 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 是任務標題開頭所用的數字。只有在測試能精確連結至_一個_任務時,才將它連結至該任務。
目前只有 Concept Exercise 具有定義完善的任務可供連結測試,但未來可能會改變。
例如,請看以下這個 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());"
}
這個測試現在會連結至第一個任務:「定義預期的烤箱時間(分鐘)」。請注意,名稱_不_必與任務的描述相符。
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 Code:
<test_code>
Test Result:
<message>
當解答通過某個測試時,應顯示類似以下的內容:
Test Code:
<test_code>
條條大路通羅馬,沒有規定必須採用哪種模式來達成。目前為止已採用過幾種做法: