1

免責事項:この質問の作者は、主にErlang/OTPの理論的知識を持っています。

myapp/ebinを介してディレクトリ内の非Erlang実行可能ファイルを呼び出す小さなOTPアプリケーションがありますopen_port()。アプリケーション自体を実行すると、すべてがうまくいき、実行可能ファイルへのポートが正常に開かれます。

しかし、アプリケーションの単体テストを実行しようとすると、open_port()失敗に依存するものが失敗します。EUnitこれは、アプリケーションを起動したときに、の下で実行可能ファイルを見つけようとするためmyapp/.eunit/ebinです。

アプリケーション自体のコードを変更せずに、その動作を変更するにはどうすればよいですか?アプリケーション自体を実行するときと同じ現在のディレクトリでEUnitテストを実行するにはどうすればよいですか?(つまり、EUnitを実行できるようにするためだけに、実行可能ファイルへのパスを提供するコードを変更することはお勧めできません)。

編集:Erlangメーリングリストのアドバイスに従いましたが、をcode:priv_dir(myapp_name)返します{error, bad_name}

編集:ファイルが含まれていて、ファイルとファイルの両方が.eunit/含まれていることがわかります。今、私は完全に迷子になっています。を実行すると、コマンドを実行します。このコマンドは、ディレクトリ内の対応するファイルを呼び出すディレクトリ内の各ファイルを呼び出します(ファイルがテスト中に実行されたことを明確に示しています)。なんでそうなの?なぜ代わりにディレクトリからファイルを実行する必要があるのですか?modulename.beamebin/modulename.beammodulename_tests.beammake testrebareunitmodulename_tests.beamebin/modulename.beam.eunit/filename:absname("")modulename.beam.eunit/modulename.beam.eunit/ebin/

myapp/ebinとにまったく同じ.beamファイルが必要なのはなぜmyapp/.eunit/ebinですか?

PS公式ドキュメントを読みましたが、解決策が見つかりませんでした。

4

2 に答える 2

4

EUnit 自体はこれを行いません - .eunit ディレクトリは Rebar によって使用される規則です。

于 2012-05-19T22:02:23.943 に答える
0

起動スクリプト ".erlang"を使用erlangすると、問題を解決できます。

.erlang ファイルで、code:add_pathz/N必要なパスを追加するために使用します。

ソースコードを読む前に、ディレクトリcouchdbの使い方の例があります。priv多分解決策はあなたに役立ちます。関数でラップopen_portし、start_port関数でディレクトリを設定しstart_portます。

ファイル内couch_os_daemon.erl

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).

ファイル cup_util.erl 内

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.

grepprivを実行すると、多くの例が見つかります。

于 2012-05-19T00:37:50.857 に答える