首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么EUnit要将.beam文件编译成.eunit/ebin?

为什么EUnit要将.beam文件编译成.eunit/ebin?
EN

Stack Overflow用户
提问于 2012-05-18 23:28:02
回答 2查看 624关注 0票数 1

免责声明:本问题的作者大多对Erlang/OTP有理论知识。

我有一个小OTP应用程序,它通过myapp/ebin目录通过open_port()调用一些非Erlang可执行文件。当我运行应用程序本身时,一切顺利,可执行文件的端口被成功打开。

但是,当我试图为应用程序运行单元测试时,依赖于open_port()的测试将失败,因为当使用EUnit启动时,应用程序试图在myapp/.eunit/ebin下找到可执行文件。

在不改变应用程序本身的代码的情况下,我如何才能改变这种行为?如何使用与运行应用程序本身相同的当前目录运行EUnit测试?(我的意思是,修改代码不是个好主意,因为代码提供了通往可执行文件的路径,这样才能运行EUnit)。

编辑:我遵循Erlang 邮寄名单中的建议,但code:priv_dir(myapp_name)返回{error, bad_name}

编辑:我可以看到.eunit/包含modulename.beam文件,ebin/包含modulename.beam文件和modulename_tests.beam文件。现在我完全迷路了。当我运行make test时,rebar运行eunit命令,该命令调用ebin/目录中的每个modulename_tests.beam文件,后者调用.eunit/目录中的相应modulename.beam文件(filename:absname("")清楚地表明,在测试期间,modulename.beam文件是从.eunit/执行的)。为什么会这样呢?为什么我们需要从modulename.beam目录而不是ebin/运行ebin/文件?

为什么我们实际上需要在myapp/ebinmyapp/.eunit/ebin中使用相同的myapp/.eunit/ebin文件?

我读过正式文件,没有找到解决办法。

EN

回答 2

Stack Overflow用户

发布于 2012-05-19 22:02:23

EUnit本身并不能做到这一点-- .eunit目录是Rebar使用的约定。

票数 4
EN

Stack Overflow用户

发布于 2012-05-19 00:37:50

使用erlang启动脚本".erlang“,可以解决您的问题。

在.erlang文件中,使用code:add_pathz/N添加必要的路径。

在阅读couchdb源代码之前,有关于如何使用priv目录的示例。也许这个解决方案对你有帮助。它用open_port函数包装start_port,并在start_port函数中设置目录。

文件中的couch_os_daemon.erl

代码语言:javascript
复制
start_port(Command) ->
    PrivDir = couch_util:priv_dir(),
    Spawnkiller = filename:join(PrivDir, "couchspawnkillable"),
    Port = open_port({spawn, Spawnkiller ++ " " ++ Command}, ?PORT_OPTIONS),
    {ok, Port}.


stop_port(#daemon{port=Port, kill=undefined}=D) ->
    ?LOG_ERROR("Stopping daemon without a kill command: ~p", [D#daemon.name]),
    catch port_close(Port);
stop_port(#daemon{port=Port}=D) ->
    ?LOG_DEBUG("Stopping daemon: ~p", [D#daemon.name]),
    os:cmd(D#daemon.kill),
    catch port_close(Port).

文件中的couch_util.erl

代码语言:javascript
复制
priv_dir() ->
    case code:priv_dir(couch) of
        {error, bad_name} ->
            % small hack, in dev mode "app" is couchdb. Fixing requires
            % renaming src/couch to src/couch. Not really worth the hassle.
            % -Damien
            code:priv_dir(couchdb);
        Dir -> Dir
    end.

start_driver(LibDir) ->
    case erl_ddll:load_driver(LibDir, "couch_icu_driver") of
    ok ->
        ok;
    {error, already_loaded} ->
        ok = erl_ddll:reload_driver(LibDir, "couch_icu_driver");
    {error, Error} ->
        exit(erl_ddll:format_error(Error))
    end.

您可以使用grep priv,可以找到许多示例。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10660962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档