Eunit断言报错模块
Eunit assertions error reporting the wrong module
我开始编写一些函数来帮助测试地图上的断言。
假设我有以下地图:
#{a => 0, b => 2}
在我的业务逻辑中调用一个函数后,我希望地图看起来像这样:
#{a => 1, b => 2}
换句话说,我预计
- 地图更新后键数相同
a
的值从 0 变为 1
b
的值不变
我可以把这个测试留给模式匹配,但是,如果我有一个包含很多键的大地图(甚至可能有很多子地图),那么问题可能在哪里并不明显 - 至少它需要一些时间才能找到问题(也许我希望更新的某些值没有 - 或者可能有一些额外的键等等 - 我希望你明白这一点)。
因此,作为开始,我在我的模块中提出了以下辅助函数:
-module(asserts).
-include_lib("eunit/include/eunit.hrl").
maps_assert_map_has_updated_values(BaseMap, Updates, ResultingMap) ->
BaseMapKeys = lists:sort(maps:keys(BaseMap)),
ResultingMapKeys = lists:sort(maps:keys(ResultingMap)),
UpdatesKeys = lists:sort(maps:keys(Updates)),
BaseMapWithoutUpdates = maps:without(UpdatesKeys, BaseMap),
BaseMapKeysWithoutUpdates = lists:sort(maps:keys(BaseMapWithoutUpdates)),
ResultingMapWithoutUpdates = maps:without(UpdatesKeys, ResultingMap),
[
?_assertEqual(BaseMapKeys, ResultingMapKeys),
lists:foldl(
fun(Key, Acc) -> [?_assertEqual({Key, maps:get(Key, Updates)},
{Key, maps:get(Key, ResultingMap)}) | Acc] end,
[],
UpdatesKeys
),
lists:foldl(
fun(Key, Acc) -> [?_assertEqual({Key, true},
{Key, maps:is_key(Key, ResultingMap)}) | Acc] end,
[],
UpdatesKeys
),
lists:foldl(
fun(Key, Acc) -> [?_assertEqual({Key, maps:get(Key, BaseMapWithoutUpdates)},
{Key, maps:get(Key, ResultingMapWithoutUpdates)}) | Acc] end,
[],
BaseMapKeysWithoutUpdates
)
].
我从另一个模块调用它,它由 eunit 执行:
-module(map_tests).
-include_lib("eunit/include/eunit.hrl").
simple_map_test_() ->
asserts:maps_assert_map_has_updated_values(
#{a => 0, b => 2},
#{a => 1},
#{a => 1, b => 3}).
我收到以下错误消息:
asserts:30: maps_assert_map_has_updated_values...*failed* in function asserts:'-maps_assert_map_has_updated_values/3-fun-8-'/3 (test/asserts.erl, line 31)
**error:{assertEqual_failed,[{module,asserts},
{line,31},
{expression,"{ Key , maps : get ( Key , ResultingMapWithoutUpdates ) }"},
{expected,{b,2}},
{value,{b,3}}]}
几乎我想要的是它报告映射中有问题的键和有问题的值,但是它报告了asserts
模块中出现错误,尽管我有兴趣查看失败的实际测试,而不是对断言模块的引用。我认为测试生成器正好适合这个,但我无法以这种方式让它工作。
有什么方法可以让 eunit
报告实际测试模块(map_tests
、function/test simple_map_test
第 X 行)而不是我的 asserts
模块?
问题是,?_assert...
宏被编译到 asserts
模块中,这就是 EUnit 发挥其魔力找出模块和行号的地方(即在编译时)。如果您将 maps_assert_map_has_updated_values
函数替换为放入包含的头文件中的宏,您应该会看到正确的堆栈跟踪。
我开始编写一些函数来帮助测试地图上的断言。
假设我有以下地图:
#{a => 0, b => 2}
在我的业务逻辑中调用一个函数后,我希望地图看起来像这样:
#{a => 1, b => 2}
换句话说,我预计
- 地图更新后键数相同
a
的值从 0 变为 1b
的值不变
我可以把这个测试留给模式匹配,但是,如果我有一个包含很多键的大地图(甚至可能有很多子地图),那么问题可能在哪里并不明显 - 至少它需要一些时间才能找到问题(也许我希望更新的某些值没有 - 或者可能有一些额外的键等等 - 我希望你明白这一点)。
因此,作为开始,我在我的模块中提出了以下辅助函数:
-module(asserts).
-include_lib("eunit/include/eunit.hrl").
maps_assert_map_has_updated_values(BaseMap, Updates, ResultingMap) ->
BaseMapKeys = lists:sort(maps:keys(BaseMap)),
ResultingMapKeys = lists:sort(maps:keys(ResultingMap)),
UpdatesKeys = lists:sort(maps:keys(Updates)),
BaseMapWithoutUpdates = maps:without(UpdatesKeys, BaseMap),
BaseMapKeysWithoutUpdates = lists:sort(maps:keys(BaseMapWithoutUpdates)),
ResultingMapWithoutUpdates = maps:without(UpdatesKeys, ResultingMap),
[
?_assertEqual(BaseMapKeys, ResultingMapKeys),
lists:foldl(
fun(Key, Acc) -> [?_assertEqual({Key, maps:get(Key, Updates)},
{Key, maps:get(Key, ResultingMap)}) | Acc] end,
[],
UpdatesKeys
),
lists:foldl(
fun(Key, Acc) -> [?_assertEqual({Key, true},
{Key, maps:is_key(Key, ResultingMap)}) | Acc] end,
[],
UpdatesKeys
),
lists:foldl(
fun(Key, Acc) -> [?_assertEqual({Key, maps:get(Key, BaseMapWithoutUpdates)},
{Key, maps:get(Key, ResultingMapWithoutUpdates)}) | Acc] end,
[],
BaseMapKeysWithoutUpdates
)
].
我从另一个模块调用它,它由 eunit 执行:
-module(map_tests).
-include_lib("eunit/include/eunit.hrl").
simple_map_test_() ->
asserts:maps_assert_map_has_updated_values(
#{a => 0, b => 2},
#{a => 1},
#{a => 1, b => 3}).
我收到以下错误消息:
asserts:30: maps_assert_map_has_updated_values...*failed* in function asserts:'-maps_assert_map_has_updated_values/3-fun-8-'/3 (test/asserts.erl, line 31)
**error:{assertEqual_failed,[{module,asserts},
{line,31},
{expression,"{ Key , maps : get ( Key , ResultingMapWithoutUpdates ) }"},
{expected,{b,2}},
{value,{b,3}}]}
几乎我想要的是它报告映射中有问题的键和有问题的值,但是它报告了asserts
模块中出现错误,尽管我有兴趣查看失败的实际测试,而不是对断言模块的引用。我认为测试生成器正好适合这个,但我无法以这种方式让它工作。
有什么方法可以让 eunit
报告实际测试模块(map_tests
、function/test simple_map_test
第 X 行)而不是我的 asserts
模块?
问题是,?_assert...
宏被编译到 asserts
模块中,这就是 EUnit 发挥其魔力找出模块和行号的地方(即在编译时)。如果您将 maps_assert_map_has_updated_values
函数替换为放入包含的头文件中的宏,您应该会看到正确的堆栈跟踪。