Elixir:集成测试误报,为什么会失败以及如何防止进一步的误报?
Elixir: Integration test false positive, why is it failing and how to prevent further false positives?
我刚开始使用 Elixir,所以我冒着风险问一些应该直截了当的问题。很抱歉,如果这应该是显而易见或简单的事情。
我将省略一些代码以保持问题简洁,代码实际上是用于 Elixir in Action 第 4 章的练习。
我写了一个结构如下:
%TodoList{auto_id: Integer, entries: %{}}
我为该结构实现了 CRUD 功能,练习是实际从 csv 文件导入数据以创建具有预定义数据的结构。
我写了以下测试:
...
describe "import/1" do
test "import csv file" do
result = %TodoList{
auto_id: 4,
entries: %{ 1 => %{date: ~D[2018-12-19], title: "Dentist"},
2 => %{date: ~D[2018-12-20], title: "Shopping"},
3 => %{date: ~D[2018-12-19], title: "Movies"}}}
assert result = TodoList.CsvImporter.import("todos.csv")
end
end
...
由于一个错误,代码目前还没有生成正确的结构,如果我在 repl 中 运行 import/1 函数,你可以看到我得到的结果:
Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> TodoList.CsvImporter.import("todos.csv")
%TodoList{
auto_id: 4,
entries: %{
1 => %{date: {:ok, ~D[2018-12-19]}, title: "Dentist"},
2 => %{date: {:ok, ~D[2018-12-20]}, title: "Shopping"},
3 => %{date: {:ok, ~D[2018-12-19]}, title: "Movies"}
}
}
iex(2)>
如您所见,错误是在地图中生成 {:ok, DATE} 而不是 DATE 日期 字段。
我知道问题出在哪里,以及如何纠正它,因为这是解析文件的步骤之一中的一个简单错误。
问题是,当我 运行 测试时,我得到了误报。
我运行是这样的:
elixir -r TodoList.CsvImporter.ex todo_tests.exs
我想展示这个是因为书中建议在同一个文件中创建两个模块(TodoList 和 TodoList.CsvImporter),我不知道这是否也是 ExUnit 套装的任何错误来源.所以我 运行 调用其中包含两个模块的单个文件和包含已编写测试的第二个文件。
我得到的是多个(假的!)警告,所有测试都通过了,而这个显然应该失败,对吧?
- 为什么测试没有失败?
- 如何防止像这样的误报?
(我想这最后一个问题很主观,可能不适合 Whosebug,但是如果有任何关于测试的书籍或资源推荐,我们将不胜感激?)
如果你刚开始使用 Elixir,这是一个典型的错误,所以不要责备自己。阅读 this chapter to catch up, especially the part about the pin operator.
所以这里你只是将测试结果分配给 result
:
assert result = TodoList.CsvImporter.import("todos.csv")
试试这个:
assert ^result = TodoList.CsvImporter.import("todos.csv")
现在应该有一个 MatchError
,如您所料。
也可以使用==
运算符使测试失败:
assert result == TodoList.CsvImporter.import("todos.csv")
两种方法都有用,就看你想怎么比较了。 ==
更严格,因为您必须准确指定输出应该是什么。 =
可能会更宽松,因为有时您只能指定所需输出的一部分,例如比较地图或地图列表时。
如,应该使用pin运算符或相等运算符
assert ^result = %{foo: "bar"}
assert result == %{foo: "bar"}
有一种方法可以防止这些误报,即使用 --warnings-as-errors
标志。如果您有警告,这将不会编译您的代码:
MIX_ENV=test mix do compile --warning-as-errors, test
或者可以将其添加到 mix.exs
文件中:
elixirc_options: [warnings_as_errors: true]
我刚开始使用 Elixir,所以我冒着风险问一些应该直截了当的问题。很抱歉,如果这应该是显而易见或简单的事情。
我将省略一些代码以保持问题简洁,代码实际上是用于 Elixir in Action 第 4 章的练习。
我写了一个结构如下:
%TodoList{auto_id: Integer, entries: %{}}
我为该结构实现了 CRUD 功能,练习是实际从 csv 文件导入数据以创建具有预定义数据的结构。
我写了以下测试:
...
describe "import/1" do
test "import csv file" do
result = %TodoList{
auto_id: 4,
entries: %{ 1 => %{date: ~D[2018-12-19], title: "Dentist"},
2 => %{date: ~D[2018-12-20], title: "Shopping"},
3 => %{date: ~D[2018-12-19], title: "Movies"}}}
assert result = TodoList.CsvImporter.import("todos.csv")
end
end
...
由于一个错误,代码目前还没有生成正确的结构,如果我在 repl 中 运行 import/1 函数,你可以看到我得到的结果:
Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> TodoList.CsvImporter.import("todos.csv")
%TodoList{
auto_id: 4,
entries: %{
1 => %{date: {:ok, ~D[2018-12-19]}, title: "Dentist"},
2 => %{date: {:ok, ~D[2018-12-20]}, title: "Shopping"},
3 => %{date: {:ok, ~D[2018-12-19]}, title: "Movies"}
}
}
iex(2)>
如您所见,错误是在地图中生成 {:ok, DATE} 而不是 DATE 日期 字段。 我知道问题出在哪里,以及如何纠正它,因为这是解析文件的步骤之一中的一个简单错误。
问题是,当我 运行 测试时,我得到了误报。
我运行是这样的:
elixir -r TodoList.CsvImporter.ex todo_tests.exs
我想展示这个是因为书中建议在同一个文件中创建两个模块(TodoList 和 TodoList.CsvImporter),我不知道这是否也是 ExUnit 套装的任何错误来源.所以我 运行 调用其中包含两个模块的单个文件和包含已编写测试的第二个文件。
我得到的是多个(假的!)警告,所有测试都通过了,而这个显然应该失败,对吧?
- 为什么测试没有失败?
- 如何防止像这样的误报?
(我想这最后一个问题很主观,可能不适合 Whosebug,但是如果有任何关于测试的书籍或资源推荐,我们将不胜感激?)
如果你刚开始使用 Elixir,这是一个典型的错误,所以不要责备自己。阅读 this chapter to catch up, especially the part about the pin operator.
所以这里你只是将测试结果分配给 result
:
assert result = TodoList.CsvImporter.import("todos.csv")
试试这个:
assert ^result = TodoList.CsvImporter.import("todos.csv")
现在应该有一个 MatchError
,如您所料。
也可以使用==
运算符使测试失败:
assert result == TodoList.CsvImporter.import("todos.csv")
两种方法都有用,就看你想怎么比较了。 ==
更严格,因为您必须准确指定输出应该是什么。 =
可能会更宽松,因为有时您只能指定所需输出的一部分,例如比较地图或地图列表时。
如
assert ^result = %{foo: "bar"}
assert result == %{foo: "bar"}
有一种方法可以防止这些误报,即使用 --warnings-as-errors
标志。如果您有警告,这将不会编译您的代码:
MIX_ENV=test mix do compile --warning-as-errors, test
或者可以将其添加到 mix.exs
文件中:
elixirc_options: [warnings_as_errors: true]