erlang的单元测试相信很多人都用过,体验不好,但是elixir出现后,似乎这个体验有机会赶超rspec,那哈哈哈了。
  初学elixir/mix,苦于没有用武之地,其实可以从测试用例开始,毕竟erlang和elixir编译出来的代码是可以完整互相调用的,那么混合在一起也什么困难的。
  新建一个rebar工程
  在erlang中我是这样尝试写用例的。
rebar create-app appid=rebar_mix_test
==> rebar_mix_test (create-app)
Writing src/rebar_mix_test.app.src
Writing src/rebar_mix_test_app.erl
Writing src/rebar_mix_test_sup.erl
  现在这个简单的otp应用下面挂一个工作者进程,这个进程有一点简单的api函数
  mix_worker.erl 简单易懂,实现了add和double函数。
-module(mix_worker).
-behaviour(gen_server).
%% API
-export([start_link/0]).
-export([add/2]).
-export([double/1]).
-record(state, {}).
-define(SERVER, MODULE).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
start_link() ->
gen_server:start_link({local, SERVER}, MODULE, [], []).
add(A, B) ->
gen_server:call(MODULE, {add, A, B}).
double(A) ->
gen_server:call(MODULE, {double, A}).
init([]) ->
{ok, #state{}}.
handle_call({add, X, Y}, _From, State) ->
{reply, X+Y, State};
handle_call({double, X}, _From, State) ->
{reply, X*2, State};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
  接下来挂到监督者下面
  init([]) ->
  {ok, { {one_for_one, 5, 10}, [CHILD(mix_worker, worker)]} }.
  编译测试:
rebar compile
==> rebar_mix_test (compile)
Compiled src/rebar_mix_test_sup.erl
Compiled src/mix_worker.erl
erl -pa deps/*/ebin ebin/
zsh: no matches found: deps/*/ebin
erl -pa ebin/
Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Eshell V7.3  (abort with ^G)
1> application:start(rebar_mix_test).
ok
2> observer:start().
ok
3> mix_worker:add(3,3).
6
4> mix_worker:double(232).
464
5>
  这个mix_worker如果想在eunit里面写单元测试用例是比较难的,我尝试写一个:
  test/mix_worker_tests.erl
  -module(mix_worker_tests).
  -compile([export_all]).
  -include_lib("eunit/include/eunit.hrl").
  add_test() ->
  3 = mix_worker:add(1,2),
  ok.
  执行测试:
rebar eunit
==> rebar_mix_test (eunit)
Compiled test/mix_worker_tests.erl
mix_worker_tests: add_test (module 'mix_worker_tests')...*failed*
in function gen_server:call/2 (gen_server.erl, line 204)
in call from mix_worker_tests:add_test/0 (test/mix_worker_tests.erl, line 7)
**exit:{noproc,{gen_server,call,[mix_worker,{add,1,2}]}}
output:<<"">>
=======================================================
Failed: 1.  Skipped: 0.  Passed: 0.
ERROR: One or more eunit tests failed.
ERROR: eunit failed while processing /Users/zhuoyikang/source/services/rebar_mix_test: rebar_abort
  抓瞎了,mix_worker没有启动,那么怎么测呢?
  尝试在测试用例中启动rebar_mix_test:
  add_test() ->
  ok = application:start(rebar_mix_test),
  3 = mix_worker:add(1,2),
  ok = application:stop(rebar_mix_test),
  ok.