【问题标题】:How can I avoid the "warning: redefining module Foo" when running ExUnit tests multiple times in one process在一个进程中多次运行 ExUnit 测试时如何避免“警告:重新定义模块 Foo”
【发布时间】:2016-08-23 21:49:47
【问题描述】:

我希望能够在一个正在运行的进程中多次运行 ExUnit 测试,例如 iex

为此,我的代码看起来有点像这样:

def test do
  # Unload test files
  ["test"]
  |> Mix.Utils.extract_files("*")
  |> Enum.map(&Path.expand/1)
  |> Code.unload_files

  # Reenable tasks
  ~w(loadpaths deps.loadpaths test)
  |> Enum.map(&Mix.Task.reenable/1)

  # Run the test suite
  Mix.Task.run("test", args)

  # Cleanup
  :elixir_config.put(:at_exit, [])
end

这可行,但会为我的测试文件中定义的每个模块打印test/my_app/foo_test.exs:1 warning: redefining module FooTest

我以为我已经从 :elixir_code_server 卸载了这些文件,因此不会引发这些警告,但事实并非如此。

如果不采用诸如使 stderr 静音之类的方法,我如何才能使这些警告静音或避免这些警告?

似乎有一个编译器标志可以用来抑制这些警告,但没有明确的公共 API 来设置这个标志。 看来我们可以禁用这些警告消息,没有明确的 API 可以这样做。

elixir_compiler:get_opt/1
https://github.com/elixir-lang/elixir/blob/master/lib/elixir/src/elixir_compiler.erl#L8-L13

查看elixir_module:check_module_availability/3 检查elixir_compiler:get_opt(ignore_module_conflict)
https://github.com/elixir-lang/elixir/blob/master/lib/elixir/src/elixir_module.erl#L408-L418

【问题讨论】:

  • 卸载没有帮助,因为加载的模块和定义的模块是两个不同的东西。如果您打开新的控制台并输入Ex <tab>,它不会显示ExUnit,因为它没有加载,但它已定义。如果您键入ExUnit.non_existent_fun,它将加载ExUnit,并将在shell 中。我认为您最好的选择是跳过混合并直接运行 ExUnit。反正iex里面有一个recompile命令,所以你只需要开始测试。
  • 如果我直接运行 ExUnit,我仍然需要处理测试文件的重新编译,这仍然会导致相同的警告消息。你知道如何避免这些吗?

标签: elixir elixir-mix


【解决方案1】:

经过反复试验,这是适合我的解决方案:

Code.compiler_options(ignore_module_conflict: true)

干杯!

【讨论】:

  • 这是正确的答案,虽然当你需要暂时关闭它时应该是ignore_module_conflict:true,当你想重新打开它时应该是false
【解决方案2】:

这可能会做到:

mix test --no-compile

或者在您的情况下,将 args 设置为包含 --no-compile,如下所示:

 # Run the test suite
 Mix.Task.run("test","--no-compile")

注意:我现在无法测试该代码的正确性,所以如果有误,请提前道歉。

【讨论】:

  • 如果模块没有被重新编译,那么多次运行测试是没有意义的,因为什么都不会改变。我卸载文件以便第二次触发重新编译。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 2018-03-16
  • 2023-03-31
  • 2017-04-09
  • 2014-05-13
相关资源
最近更新 更多