了解如何在 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 检查自己实现的类型。你需要完成几个步骤。为此,你必须在题目的mix.exs文件中添加Dialyxir依赖。
defp deps do
# Add this:
[{:dialyxir, "~> 0.4", only: [:dev]}]
end
然后用 mix 任务在命令行上获取并编译:
$ mix deps.get
...
$ mix deps.compile
...
如果你是第一次运行 Dialyzer,很可能还没有plt文件。Dialyzer 使用持久查找表(persistent lookup table,简称 PLT)来缓存内置 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()
第一条警告表示这个函数返回的类型不正确。最后一条说明第二个函数定义永远无法被执行到,因为第一个函数定义总是匹配。