use*_*184 13 unit-testing functional-programming elixir teardown ex-unit
我想测试一个与主机系统交互的Elixir模块,并且具有副作用的方法.对于这个问题并保持简短,假设它是几个目录的创建.这些目录当然应该在运行测试后删除,如果测试(很长时间)由于任何原因(坏的模块代码,错误的测试代码等)而失败.
我想知道如何最好/最优雅地解决这个清理步骤.我查看了ExUnit.Callbacks.on_exit/2的文档,但它的示例仅用于设置和简单拆解(不涉及传递状态).我也在线搜索,但没有发现任何有用的东西,所以可能是我的想法本身并不好 - 我也愿意接受重构问题的建议.
defmodule SimpleTest do
use ExUnit.Case
setup_all do
ts = Time.utc_now |> Time.to_string
{:ok, [timestamp: ts]}
# paths to be cleaned are not yet known here
end
test "first test", context do
path = "/tmp/dir" <> context[:timestamp]
assert :ok == SimpleModule.mkdir(path)
assert :eexist == SimpleModule.mkdir(path)
# [path] should be passed on to cleanup
end
test "second test", context do
path = "/tmp/dir" <> context[:timestamp]
path2 = "/tmp/dir2" <> context[:timestamp]
SimpleModule.mkdir(path)
SimpleModule.mkdir(path2)
assert File.exists?(path)
assert File.exists?(path2)
# [path, path2] should be passed on to cleanup
end
defp cleanup(context) do
Enum.each(context[:dirs], fn(x) -> File.rmdir(x) end)
end
end
defmodule SimpleModule do
def mkdir(path) do
File.mkdir(path)
end
end
Run Code Online (Sandbox Code Playgroud)
我现在想要cleanup/1
在每次测试后添加一个要删除的目录列表的调用.以下想法是我尝试过的事情:
on_exit(fn -> cleanup(context) end)
在每个测试中调用更新的上下文:这似乎有效,但我无法确定是否推荐它,如果它将调用放在测试中(开始/结束)会有所不同.on_exit(fn -> cleanup(context) end)
的setup context
功能:文件这样做,但我不知道如何将任何新的状态/上下文传递给它.它似乎只有在设置函数中已经完全定义了所有上下文时才有用.也许我也在过度思考这个问题...我只是有一些糟糕的调试经验,不完全清理并导致无休止的递归(应该已经被我的代码捕获,但还没有),所以我只是想确保我这样做正确的事情,并以正确的方式学习它.除了那些测试,Elixir到目前为止是一个非常愉快和完美的体验!
在这种特殊情况下,我只会on_exit
在您的 setup 函数(您的第三个解决方案)中注册回调。
不是单独删除路径,而是删除父目录:
@test_dir "/tmp/base_test"
setup do
File.mkdir(@test_dir)
on_exit fn ->
File.rm_rf @test_dir
end
end
Run Code Online (Sandbox Code Playgroud)
然后@test_dir
在您的测试中用作您的基本目录