原因:在 erl 控制台中运行常见测试时 undef [Erlang]

问题描述

我正在运行应用程序,并在交互式控制台中尝试运行位于 test/common 目录中的常见测试套件:

ct:run("test/common").

但是我得到了一堆错误

Reason: undef

并且所有测试都失败了。 我试图从 linux shell 运行它们

ct_run -dir test/common

或者像这样:

ct_run -boot start_sasl -spec test/common/app_ct.spec -erl_args -config env/dev.config

结果相同。

但是当我使用 rebar(第二个版本,而不是 rebar3)运行它们时

rebar ct

一切正常,测试通过。但是编译应用程序并启动它需要太多时间。

在 rebar.config 我有

{ct_dir,"test/common"}.
{ct_log_dir,"test/logs"}.
{ct_extra_params,"-boot start_sasl -pa deps/*/ebin -pa ebin -spec test/common/app_ct.spec -erl_args -config env/dev.config"}.

在 test/common/app_ct.spec 中我有

{verbosity,100}.
{init,{eval,[{application,ensure_all_started,[app]},{timer,sleep,[30000]}]}}.
{alias,common,"./test/common/"}.
{suites,"",[app_srv_SUITE,app_client_SUITE]}.

如何使用 ct:run("test/common") 从 erl 控制台运行测试?

我的目标是能够单独重新编译单个测试文件并从工作应用程序控制台运行测试,而无需停止和重新编译所有应用程序。

我重新编译了单一的测试模块,没有出现这样的问题:

c("test/common/new_mod_SUITE.erl",[{i,"include"},{i,"deps"},{outdir,"test/common"}]). 

但在那之后我仍然无法运行测试。

解决方法

首先,需要确保所有测试都已编译,并且它们位于作为参数放入 ct:run/1 的文件夹中。如果只需要从特定文件夹运行一个测试,可以使用 ct:run/2。如果需要从特定文件夹运行特定测试用例,可以使用特定文件夹ct:run/3。示例:

1> ct:run("test/common").
2> ct:run("test/common","some_SUITE").

但是我建议使用 rebar3,在 rebar3 中添加了像 --dir 这样的选项,并且可以像这样运行来自特定文件夹的测试:

$ ./rebar3 ct --dir="test/common"
,

这可能无济于事,但这是我使用 rebar3 时发生的情况:

~/erlang_programs/myrebar/myapp$ ls
LICENSE     _build      rebar.lock  test
README.md   rebar.config    src

~/erlang_programs/myrebar/myapp$ cd src
~/erlang_programs/myrebar/myapp/src$ ls
a.erl       myapp_app.erl   rebar.lock
myapp.app.src   myapp_sup.erl

~/erlang_programs/myrebar/myapp/src$ cat a.erl
-module(a).
-compile(export_all).
%%-include("eunit.hrl").


hello() -> io:format("hello").

~/erlang_programs/myrebar/myapp/src$ cd ../test
~/erlang_programs/myrebar/myapp/test$ ls
a_SUITE.erl

~/erlang_programs/myrebar/myapp/test$ cat a_SUITE.erl 
-module(a_SUITE).
-compile(export_all).

all() -> [go].

go(_Config) ->
   1 = 1. 

~/erlang_programs/myrebar/myapp/test$ cd ..
~/erlang_programs/myrebar/myapp$ rebar3 compile
===> Verifying dependencies...
===> Compiling myapp
~/erlang_programs/myrebar/myapp$ rebar3 shell
===> Verifying dependencies...
===> Compiling myapp
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [kernel-poll:false]

Eshell V9.3  (abort with ^G)
1> ===> The rebar3 shell is a development tool; to deploy applications in production,consider using releases (http://www.rebar3.org/docs/releases)
===> Booted myapp
 
1> ct:run("test").

Common Test: Running make in test directories...
Recompile: a_SUITE
a_SUITE.erl:2: Warning: export_all flag enabled - all functions will be exported

CWD set to: "/Users/7stud/erlang_programs/myrebar/myapp/[email protected]_14.26.08"

TEST INFO: 1 test(s),1 case(s) in 1 suite(s)

Testing myrebar.myapp: Starting test,1 test cases
Testing myrebar.myapp: TEST COMPLETE,1 ok,0 failed of 1 test cases

Updating /Users/7stud/erlang_programs/myrebar/myapp/index.html ... done
Updating /Users/7stud/erlang_programs/myrebar/myapp/all_runs.html ... done
{1,{0,0}}
2> 

然后在退出shell后:

~/erlang_programs/myrebar/myapp$ 

~/erlang_programs/myrebar/myapp$ rebar3 ct
===> Verifying dependencies...
===> Compiling myapp
test/a_SUITE.erl:2: Warning: export_all flag enabled - all functions will be exported

===> Running Common Test suites...
%%% a_SUITE: .
All 1 tests passed.

~/erlang_programs/myrebar/myapp$ 

我没有碰rebar.config,它是rebar3默认生成的:

{erl_opts,[debug_info]}.
{deps,[{eleveldb,"2.2.20"}]
}.

{shell,[
  % {config,"config/sys.config"},{apps,[myapp]}
]}.

当您在 shell 中时,我会尝试打印您当前的工作目录:

2> pwd().
/Users/7stud/erlang_programs/myrebar/myapp
ok

然后尝试使用该目录的完整路径或相对路径,例如:

"./test/common"
"Users/../../test/common"

然后,我会将除一个之外的所有 *_SUITE.erl 文件移动到您的应用程序之外的目录中,并且只处理一个测试文件。然后,我会删除所有配置文件内容并重试。