了解如何在 Exercism 上測試你的 Elixir 練習
從終端機切換到練習的基底目錄,然後用以下指令執行測試:
$ mix test
這會執行 test 子資料夾裡的測試檔,也就是以 _test.exs 結尾的檔案。
在練習題的測試套件中,除了第一個測試之外,其餘的測試都被標記為略過。
當你讓一個測試通過後,只要用 # 符號把相關的 @tag :pending 註解掉,就能取消略過下一個測試。
例如:
# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end
如果你想一次執行所有測試,可以在 mix test 指令加上 --include 參數,把所有被略過的測試都納入:
$ mix test --include pending
或者,你也可以把測試套件裡的 ExUnit.configure 那一行註解掉,來啟用所有測試。
# ExUnit.configure exclude: :pending, trace: true
ExUnit 和 mix test 提供了不少分組、標記與執行測試的方法,也有各種控制測試執行方式的做法,以下大致整理了其中一部分。
文件:
只要指定檔案,就能用 mix test 執行單一檔案裡的所有測試:
$ mix test test/<FILE>.exs
注意:使用這種方式時,
tagging可能會影響實際執行了哪些測試。
個別測試可以透過指定測試在檔案中的行號來執行:
$ mix test test/<FILE>.exs:LINENUM
可以用 : 分隔多個行號,來執行多個測試。
例如,假設有個檔案內容如下,並標上行號:
test "Test 1" do # 1
# test implementation # 2-6
end # 7
# 8
test "Test 2" do # 9
# test implementation # 10-21
end # 22
# 23
test "Test 3" do # 24
# test implementation # 25-35
end # 36
第 1 個和第 3 個測試可以這樣執行:
$ mix test test/FILE.exs:1:24
注意:透過行號指定測試時,
tagging會被忽略。
測試可以用 describe 分組:
describe "short test group description" do
test "test description" do
# test implementation
end
test "another test description" do
# test implementation
end
end
群組中的所有測試都能透過指定它在檔案中的行號來執行,就像指定並執行個別測試一樣。
文件:
mix test 選項--include 和 --exclude - 根據測試的 @tag 決定要不要執行特定測試--failed - 只執行上次執行時失敗的測試--max-failures - 當測試失敗數達到這個數字時,測試套件就會停止評估測試--seed - 為用來隨機排序測試的隨機數產生器設定種子
--seed 0 會停用隨機化,這樣單一檔案裡的測試就會永遠按照定義的順序執行--stale - 只執行那些參照到自從上次用 --stale 執行測試後有變動的模組的測試--only task_id:1 - 或是換成其他數字;在學習練習中,只執行與特定任務相關的測試文件:
Elixir 練習的 lib 子目錄裡會有一份骨架實作檔。這個檔案大致列出了你預期要實作的模組與函式。在大多數練習中,你會在函式宣告上方看到型別規格。這些規格以 @spec 標籤開頭,通常遵循 @spec function_name(type1, type2) :: return_type 的格式。這些在 Elixir 和 Erlang 中作為文件使用,也會搭配一個叫做 Dialyzer 的工具,用來找出型別不一致和可能的 bug。想了解更多資訊,請參閱型別規格文件。關於 Dialyzer 的文件,請參閱 Erlang -- dialyzer。
你也可以選擇用 Dialyzer 來檢查實作的型別。這需要幾個步驟。為此,你必須把 Dialyxir 相依套件加到你這個題目的 mix.exs 檔案中。
defp deps do
# Add this:
[{:dialyxir, "~> 0.4", only: [:dev]}]
end
接著用 mix 任務從命令列取得並編譯:
$ mix deps.get
...
$ mix deps.compile
...
如果你是第一次執行 Dialyzer,很可能還沒有 plt 檔案。持久查詢表,也就是 PLT,是 Dialyzer 用來快取 Elixir 和 Erlang 內建型別資訊的。要建立一份有合理預設值的 plt,請執行:
$ mix dialyzer --plt
最後,可以用以下指令執行:
$ mix dialyzer
請務必把路徑改成你系統上 Elixir 函式庫的路徑。例如,如果你用 homebrew 安裝 Elixir,大概會放在 /usr/local/Cellar/elixir/1.3.2。
要再次強調的是,完成練習時,執行 Dialyzer 並移除所有警告是選擇性的步驟。Dialyzer 的警告可能很難解讀。舉例來說,看看這個 Bob 練習的荒唐實作所產生的警告。
defmodule Bob do
@spec hey(input :: String.t()) :: String.t()
def hey(input) do
1
end
def hey(input) do
end
end
這會產生以下警告。
bob.exs:2: Invalid type specification for function 'Elixir.Bob':hey/1. The success typing is (_) -> 1
bob.exs:7: The variable _input@1 can never match since previous clauses completely covered the type any()
第一個警告表示這個函式沒有回傳正確的型別。最後一個警告表示第二個函式定義永遠不會被執行到,因為第一個函式定義總是符合。