Testing 有没有办法在长生不老药测试中模拟缺乏互联网连接?

Testing 有没有办法在长生不老药测试中模拟缺乏互联网连接?,testing,erlang,elixir,code-coverage,coveralls,Testing,Erlang,Elixir,Code Coverage,Coveralls,我正在处理用Elixir开发的命令行界面应用程序的覆盖率测试。该应用程序是tldr页面的客户端,其功能由使用escript构建的脚本组成。为了执行这些操作,我在HTTPoison.get/1函数上使用了case结构,在该函数中我引入了格式化的url。在这个案例中我比较了对不同类型值的响应,例如,如果页面存在,它会显示信息;如果没有,它将报告给用户,然后在另一个案例中继续以评估其他可能性。最后,第一个案例以两种模式结束,以匹配错误,一种是由于缺少internet连接,另一种是由于意外错误。所述结构

我正在处理用Elixir开发的命令行界面应用程序的覆盖率测试。该应用程序是tldr页面的客户端,其功能由使用
escript
构建的脚本组成。为了执行这些操作,我在
HTTPoison.get/1
函数上使用了
case
结构,在该函数中我引入了格式化的url。在这个
案例中
我比较了对不同类型值的响应,例如,如果页面存在,它会显示信息;如果没有,它将报告给用户,然后在另一个
案例中继续
以评估其他可能性。最后,第一个
案例
以两种模式结束,以匹配错误,一种是由于缺少internet连接,另一种是由于意外错误。所述结构是下一个结构:

    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
意外错误
是在另一个文件中定义的异常。最后的两种模式显然都很好,至少第一种:

      {:error, %HTTPoison.Error{reason: reason}} when reason == :nxdomain ->
        raise NoInternetConnectionError
但是,正如我在问题开始时所说的,我正在处理一个覆盖率测试,该测试是使用GitHub操作和工作服自动执行的,在依赖项中使用Excworkarks。在本测试中,我收到了关于
raise/1
语句的警告。虽然我可能错误地理解了这意味着什么,但我理解这种“漏线”或未覆盖的线是由工作服报告的,因为我没有进行覆盖此案例的测试。因此,我开始研究如何编写一个涵盖这两种情况的测试

最重要的问题是如何在测试中模拟缺少internet连接来覆盖此问题。我想我将要开发一个mock,但是在一些Elixir的mock包中,我没有发现一些有用的东西,比如。然后我发现了一个非常有趣的包,我认为它可能很有用,因为它有
down/1
up/1
来关闭和启动TCP套接字,所以它可以测试HTTP服务器关闭时会发生什么。但我有两个问题:

  • 服务器停机与用户部分缺少internet连接不同
  • 我试图应用这种“上下”的机制,但没有成功。我不打算分享它,因为我认为它不会是所描述的第一个问题的最终解决方案
  • 我不是在用解决这个问题的代码假装答案,我只是想了解这个测试应该如何工作,以及开发它应该遵循的逻辑。我甚至在研究Erlang文档,因为Erlang可能提供本机函数来解决它(例如,我现在正在阅读Erlang的,因为可能有一些有用的东西)

    编辑。我的评论是,我尝试使用
    旁路
    安装依赖项,使用
    旁路编写安装程序。打开/0
    ,然后编写一个与下一个测试类似的测试,在该测试中,我尝试使用
    捕获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
    
    然而,正如我所想,它并没有涵盖可能出现的缺乏互联网的情况,只是检查服务器何时停机的可能性。

    旁注:我个人一直反对成为有助于开发的工具的奴隶。覆盖率是一个较好的指标,但不应将建议视为必须。无论如何

    我不知道你为什么排除Mox。经验法则是:除非绝对不可避免,否则测试不应涉及跨境通话。尽管如此,互联网上的测试还是不可靠的:报道不会告诉你这一点,我会的。如果测试环境根本没有永久的互联网接入怎么办?临时连接问题?遥控器坏了

    这就是为什么
    Mox
    诞生的原因。幸运的是,
    HTTPoison
    完全可以将
    Mox
    用作模拟库,因为它声明了主操作模块的行为

    您所需要的只是使您的实际HTTP客户机成为一个注入依赖项。大致如下:

    
    @http_客户端应用程序。获取_环境(:my_应用程序,:http_客户端,HTTPoison)
    ...
    case@http_client.get(process_url(os,term))do
    ...
    结束
    
    config/test.exs
    中,您可以指定自己的
    :http_client
    ,瞧,漂亮的模拟测试环境就属于您了


    或者,您可以直接声明模拟:

    Mox.defmock(MyApp.HC,for:HTTPoison.Base)
    

    我还擅长于应用程序级别的边界调用第三方。也就是说,您可以为所需的外部HTTP调用定义自己的行为,并定义实现此行为的包装器。这样模仿就更容易了,你也可以轻松地改变真正的客户
    HTTPoison
    现在远不是最好的客户机(它几乎不支持HTTP2等),明天您可能会决定切换到,比如。如果所有的代码都位于包装器中,那么实现起来会非常容易。

    旁注:我个人一直反对成为那些应该帮助开发的工具的奴隶。覆盖率是一个较好的指标,但不应将建议视为必须。无论如何

    我不知道你为什么排除Mox。经验法则是:除非绝对不可避免,否则测试不应涉及跨境通话。尽管如此,互联网上的测试还是不可靠的:报道不会告诉你这一点,我会的。如果测试环境根本没有永久的互联网接入怎么办?临时连接问题?遥控器坏了

    这就是为什么
    Mox
    诞生的原因。幸运的是,
    HTTPoison
    完全可以将
    Mox
    用作模拟库,因为它声明了主操作模块的行为

    你所需要的就是