当我在项目上运行mix test
时,我会收到以下错误,我不明白为什么:
$ mix test
Compiling 2 files (.ex)
== Compilation error in file lib/myproject_web/controllers/email_controller_test.ex ==
** (RuntimeError) cannot use ExUnit.Case without starting the ExUnit application, please call ExUnit.start() or explicitly start the :ex_unit app
expanding macro: ExUnit.Case.__using__/1
lib/myproject_web/controllers/email_controller_test.ex:2: MyProjectWeb.EmailControllerTest (module)
(elixir 1.10.1) expanding macro: Kernel.use/2
lib/myproject_web/controllers/email_controller_test.ex:2: MyProjectWeb.EmailControllerTest (module)
我在lib/
中已经有一个test_helper.exs
文件,它调用ExUnit.start()
。我的设置很不寻常,因为我希望测试放在模块旁边,而不是放在单独的test
文件夹中。
原来这个错误来自扩展名为.ex
而不是.exs
的测试文件。对于.ex
,mix
在运行测试之前尝试将其与其他所有内容一起编译,然后由于在编译时未调用ExUnit.start()
而抱怨。
使用.exs
扩展名,则不编译该文件,而是在从test_helpers.exs
调用ExUnit.start()
之后由mix test
运行该文件。
如果您阅读了mix test
:的文档
此任务启动当前应用程序,加载
test/test_helper.exs
,然后要求所有与CCD_ 17模式并行。
您说得对,.exs
文件没有编译,但如果它们已经编译,这也不是问题。测试是作为脚本运行的,以避免重复编译,因为它们每次都会得到随机顺序,具有不同的输出编译。
该任务首先编译所有文件,然后启动ExUnit
并展开*_test.exs
脚本中的所有宏。要证明这一点,请查看以下代码:
defmacro __using__(opts) do
unless Process.whereis(ExUnit.Server) do
raise "cannot use ExUnit.Case without starting the ExUnit application, " <>
"please call ExUnit.start() or explicitly start the :ex_unit app"
end
这意味着,在使用use ExUnit.Case
的文件中,ExUnit
服务器应该在解释这些脚本时启动并运行。
一般来说,在您的情况下,即使更改为.exs
,您的测试也不应该工作,因为使用默认配置,测试的路径是:
defp default_test_paths do
if File.dir?("test") do
["test"]
else
[]
end
相反,你应该用调用测试
mix test test/some/particular/file_test.exs