Testing

Macros: ?assert, ?assertNot, ?assertEqual, ?assertNotEqual, ?assertMatch(Pattern, Expr), ?assertError, ?assertExit, ?assertThrow, ?assertException.

22.1 EUnit — unit tests

Macros: ?assert, ?assertNot, ?assertEqual, ?assertNotEqual, ?assertMatch(Pattern, Expr), ?assertError, ?assertExit, ?assertThrow, ?assertException. Underscore versions (?_assert...) create test objects. Fixtures: setup, foreach, timeout, inparallel.

Run: eunit:test(math_utils, [verbose]). or rebar3 eunit.

-module(math_utils_tests).
-include_lib("eunit/include/eunit.hrl").

add_test() -> ?assertEqual(4, math_utils:add(2, 2)).

reverse_test_() ->                          % test generator: name ends with _test_
    [?_assertEqual([3, 2, 1], lists:reverse([1, 2, 3])),
     ?_assertEqual([], lists:reverse([]))].

error_test() -> ?assertError(badarith, 1 / 0).

setup_test_() ->
    {setup,
     fun() -> ets:new(t, [named_table, public]) end,   % setup
     fun(_) -> ets:delete(t) end,                      % cleanup
     fun(_) -> [?_assert(ets:insert(t, {a, 1}))] end}. % instantiator

22.2 Common Test — integration/system tests

Features: suites, groups, test case config, hooks (CTH), HTML logs, distributed testing, ct_property_test. Run: rebar3 ct.

-module(myapp_SUITE).
-include_lib("common_test/include/ct.hrl").
-export([all/0, init_per_suite/1, end_per_suite/1, groups/0, test_put_get/1]).

all() -> [test_put_get, {group, slow}].
groups() -> [{slow, [parallel], []}].

init_per_suite(Config) ->
    {ok, _} = application:ensure_all_started(myapp),
    Config.
end_per_suite(_Config) -> application:stop(myapp).

test_put_get(_Config) ->
    ok = myapp:put(k, v),
    {ok, v} = myapp:get(k).          % assertive matching = assertion

22.3 Property-based testing (PropEr)

Run: rebar3 proper. Also QuickCheck (Quviq, commercial; pioneered PBT on Erlang) and triq. Stateful PBT models systems as state machines.

-include_lib("proper/include/proper.hrl").

prop_reverse_twice() ->
    ?FORALL(L, list(integer()), lists:reverse(lists:reverse(L)) =:= L).

prop_sort_ordered() ->
    ?FORALL(L, list(integer()), ordered(lists:sort(L))).

22.4 Mocking

meck library:

meck:new(http_client),
meck:expect(http_client, get, fun(_Url) -> {ok, <<"body">>} end),
?assertEqual({ok, <<"body">>}, my_mod:fetch("u")),
meck:validate(http_client), meck:unload(http_client).

22.5 Coverage

rebar3 eunit --cover && rebar3 cover --verbose, or cover:compile_module/1 manually.