【发布时间】:2020-08-31 15:37:07
【问题描述】:
我正在处理用 Elixir 开发的命令行界面应用程序的覆盖率测试。该应用程序是 tldr-pages 的客户端,其功能包含在使用escript 构建的脚本中。为了执行这些操作,我在 HTTPoison.get/1 函数上使用了 case 结构,我在其中引入了格式化的 url。在这个case 中,我将响应与不同类型的值进行比较,例如页面是否存在,它会显示信息;如果不是,它将报告给用户,然后在另一个case 中继续评估其他可能性。最后,第一个case 完成了两个匹配错误的模式,一个用于缺少互联网连接,另一个用于意外错误。所描述的结构是下一个:
case HTTPoison.get(process_url(os, term)) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
IO.puts(body)
{:ok, %HTTPoison.Response{status_code: 404}} ->
IO.puts(
"Term \"#{term}\" not found on \"#{os}\" pages\nExTldr is looking on \"common\" pages."
)
case HTTPoison.get(process_url("common", term)) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
IO.puts(body)
{:ok, %HTTPoison.Response{status_code: 404}} ->
IO.puts("Term not found on \"common\" pages.")
end
{:error, %HTTPoison.Error{reason: reason}} when reason == :nxdomain ->
raise NoInternetConnectionError
{:error, %HTTPoison.Error{reason: reason}} when reason != :nxdomain ->
raise UnexpectedError, reason
end
NoInternetConnectionError 和 UnexpectedError 是在另一个文件中定义的异常。最后的两种模式显然都很好,至少是第一种:
{:error, %HTTPoison.Error{reason: reason}} when reason == :nxdomain ->
raise NoInternetConnectionError
但是,正如我在问题开头所说的那样,我正在处理使用 GitHub Actions 和 Coveralls 自动执行的覆盖测试,并在依赖项中使用 ExCoveralls。在这个测试中,我收到了两个raise/1 语句的警告。尽管我理解这意味着什么可能是错误的,但我理解工作服报告了这种“遗漏的线条”或未覆盖的线条,因为我没有进行测试来涵盖这种情况。因此,我开始研究如何编写一个涵盖这两种情况的测试。
最重要的问题是如何在测试中模拟互联网连接的缺失来解决这个问题。我虽然即将开发一个模拟,但我在 Elixir 的一些模拟包中找不到对这种情况有用的东西,比如Mox。然后我找到了bypass,这是一个非常有趣的包,我认为它可能很有用,因为它有down/1 和up/1 来关闭和启动TCP 套接字,因此可以测试HTTP 服务器关闭时发生的情况。但是有了这个我有两个问题:
- 服务器宕机与用户部分缺乏互联网连接不同。
- 我尝试应用这种“上下”机制,但没有成功。我不打算分享它,因为我认为它不会是所描述的第一个问题的最终解决方案。
我不是用解决这个问题的代码来假装一个答案,我只是想了解这个测试应该如何工作以及我应该遵循的逻辑来开发它。我什至在研究 Erlang 文档,因为 Erlang 可能会提供本地函数来解决它(例如,我现在正在阅读 Erlang 的 Common Test Reference Manual,因为那里可能有一些有用的东西)。
编辑。我用bypass 尝试过的评论是安装依赖项,用bypass.open/0 编写一个设置,然后编写一个类似下一个的测试,其中我尝试用capture_io/1 断言捕获输出:
test "lack of internet connection", %{bypass: bypass} do
Bypass.down(bypass)
execute_main = fn ->
ExTldr.main([])
end
assert capture_io(execute_main) =~ "There is not internet connection"
end
但是,正如我所想,它不包括可能的缺乏互联网的情况,只是检查服务器何时关闭的可能性。
【问题讨论】:
标签: testing erlang elixir code-coverage coveralls