Erlang测试 #
一、EUnit #
1.1 基本测试 #
erlang
-module(my_module).
-include_lib("eunit/include/eunit.hrl").
add_test() ->
2 = my_module:add(1, 1).
add_test_() ->
[
?_assertEqual(2, my_module:add(1, 1)),
?_assertEqual(0, my_module:add(-1, 1)),
?_assertEqual(5, my_module:add(2, 3))
].
1.2 断言宏 #
| 宏 | 说明 |
|---|---|
?assert(Expr) |
断言为真 |
?assertNot(Expr) |
断言为假 |
?assertEqual(A, B) |
断言相等 |
?assertNotEqual(A, B) |
断言不等 |
?assertMatch(Pattern, Expr) |
断言匹配 |
?assertException(Class, Pattern, Expr) |
断言异常 |
?assertError(Pattern, Expr) |
断言错误 |
?assertThrow(Pattern, Expr) |
断言抛出 |
?assertExit(Pattern, Expr) |
断言退出 |
1.3 测试生成器 #
erlang
-module(generator_test).
-include_lib("eunit/include/eunit.hrl").
add_test_() ->
[
{"Add positive numbers", ?_assertEqual(3, add(1, 2))},
{"Add negative numbers", ?_assertEqual(-3, add(-1, -2))},
{"Add zero", ?_assertEqual(1, add(1, 0))}
].
add(A, B) -> A + B.
1.4 运行测试 #
bash
rebar3 eunit
或在Shell中:
erlang
eunit:test(my_module).
二、Common Test #
2.1 测试套件结构 #
erlang
-module(my_SUITE).
-include_lib("common_test/include/ct.hrl").
-export([all/0, init_per_suite/1, end_per_suite/1]).
-export([test_case_1/1, test_case_2/1]).
all() -> [test_case_1, test_case_2].
init_per_suite(Config) ->
Config.
end_per_suite(_Config) ->
ok.
test_case_1(_Config) ->
2 = 1 + 1.
test_case_2(_Config) ->
ok = ok.
2.2 测试配置 #
text
my_app/
├── test/
│ ├── my_SUITE.erl
│ └── my_app_SUITE_data/
│ └── config.txt
2.3 测试规格 #
erlang
{suite, my_SUITE}.
{testcase, test_case_1}.
2.4 运行测试 #
bash
rebar3 ct
或:
bash
ct_run -suite my_SUITE
三、测试模式 #
3.1 单元测试 #
erlang
-module(unit_test).
-include_lib("eunit/include/eunit.hrl").
reverse_test() ->
[] = lists:reverse([]),
[1] = lists:reverse([1]),
[3, 2, 1] = lists:reverse([1, 2, 3]).
3.2 集成测试 #
erlang
-module(integration_test).
-include_lib("common_test/include/ct.hrl").
-export([all/0, init_per_suite/1, end_per_suite/1]).
-export([start_stop_test/1]).
all() -> [start_stop_test].
init_per_suite(Config) ->
{ok, Pid} = my_server:start_link(),
[{server, Pid} | Config].
end_per_suite(Config) ->
Pid = ?config(server, Config),
my_server:stop(Pid).
start_stop_test(Config) ->
Pid = ?config(server, Config),
true = is_process_alive(Pid).
3.3 属性测试 #
erlang
-module(prop_test).
-include_lib("proper/include/proper.hrl").
prop_reverse() ->
?FORALL(L, list(integer()),
lists:reverse(lists:reverse(L)) =:= L).
四、Mock #
4.1 使用meck #
erlang
-module(meck_test).
-include_lib("eunit/include/eunit.hrl").
mock_test() ->
meck:new(my_module),
meck:expect(my_module, func, fun() -> mocked end),
?assertEqual(mocked, my_module:func()),
meck:unload(my_module).
五、最佳实践 #
5.1 测试命名 #
erlang
add_positive_numbers_test() -> ok.
add_negative_numbers_test() -> ok.
5.2 测试隔离 #
erlang
init_per_testcase(_TestCase, Config) ->
Config.
end_per_testcase(_TestCase, _Config) ->
ok.
5.3 测试覆盖 #
bash
rebar3 cover
六、总结 #
本章学习了:
- EUnit单元测试
- Common Test集成测试
- 测试模式
- Mock使用
- 最佳实践
最后更新:2026-03-27