查看源代码 ct_property_test (common_test v1.27.5)
在 Common Test 中支持运行基于属性的测试。
此模块帮助在 Common Test
框架中运行基于属性的测试。假设已安装一个(或多个)属性测试工具
。
此模块的想法是让 Common Test
测试套件使用该工具定义的特殊属性测试套件来调用属性测试工具。测试收集在应用程序的 test
目录中。test
目录有一个子目录 property_test
,其中收集了属性测试所需的所有内容。假设使用通常的 Erlang 应用程序目录结构。
一个典型的使用 ct_property_test
的 Common Test
测试套件的组织方式如下
-module(my_prop_test_SUITE).
-compile(export_all).
-include_lib("common_test/include/ct.hrl").
all() -> [prop_ftp_case].
init_per_suite(Config) ->
ct_property_test:init_per_suite(Config).
%%%---- test case
prop_ftp_case(Config) ->
ct_property_test:quickcheck(
ftp_simple_client_server:prop_ftp(),
Config
).
,并且属性测试模块(在本示例中为 ftp_simple_client_server.erl
)几乎像一个普通的属性测试模块(更多示例请参见用户指南)
-module(ftp_simple_client_server).
-export([prop_ftp/0...]).
-include_lib("common_test/include/ct_property_test.hrl").
prop_ftp() ->
?FORALL( ....
概要
函数
返回在 Cmnd
序列中生成的命令(函数调用)列表,不包含模块、参数和其他详细信息。
初始化并扩展 Config
以进行基于属性的测试。
返回测试用例中命令调用的次数。
使用 PropEr、QuickCheck 或其他类似属性测试工具中的聚合函数,呈现有状态(statem)属性测试的结果。
调用所选工具的函数以运行 Property
。通常并且由于历史原因,它被称为 quickcheck,这就是为什么在此模块 (ct_property_test
) 中使用该名称的原因。
返回包含有关顺序和并行部分信息的列表。
类型
-type arguments() :: [term()].
-type command() :: set_command() | init_command().
-type command_list() :: [command()].
-type dynamic_state() :: term().
-type function_name() :: atom().
-type history() :: [term()].
-type init_command() :: {init, symbolic_state()}.
-type parallel_testcase() :: {command_list(), [command_list()]}.
-type set_command() :: {set, symbolic_var(), symbolic_call()}.
-type statem_result() :: ok | term().
-type symbolic_call() :: {call, module(), function_name(), arguments()}.
-type symbolic_state() :: term().
-type symbolic_var() :: {var, pos_integer()}.
函数
-spec cmnd_names(Cs) -> Result when Cs :: command_list() | parallel_testcase(), Result :: [function_name()].
返回在 Cmnd
序列中生成的命令(函数调用)列表,不包含模块、参数和其他详细信息。
有关更多信息,请参见:present_result/5
。
-spec init_per_suite(Config) -> Config | {skip, Reason} | {fail, Reason} when Config :: proplists:proplist(), Reason :: string().
初始化并扩展 Config
以进行基于属性的测试。
此函数检查是否支持 QuickCheck、PropEr 或 Triq,并使用找到的第一个工具编译属性。它应该在 CommonTest 测试套件中的 init_per_suite/1
函数中调用。
要检查哪些工具,以及以何种顺序检查可以使用 CommonTest 配置 Config
中的选项 {prop_tools, list(eqc|proper|triq)}
设置。默认值为 [eqc, proper, triq]
,其中 eqc
是第一个搜索到的工具。
如果未找到任何工具的支持,此函数将返回 {skip, Explanation}
。
如果出现其他错误,此函数将返回 {fail, Explanation}
。
如果找到支持,则选项 {property_test_tool,ToolModule}
与所选工具的主模块名称(eqc
、proper
或 triq
)被添加到列表 Config
中,然后返回。
假设属性测试位于名为 property_test
的子目录中。该目录中所有找到的 Erlang 文件都使用宏 'EQC'
、'PROPER'
或 'TRIQ'
之一进行编译,具体取决于首先找到的工具。这可以使 Erlang 属性测试代码的部分使用宏指令 -ifdef(Macro).
或 -ifndef(Macro).
来包含或排除。
property_test
子目录中的文件可以或应该包含 ct_property_test 包含文件
-include_lib("common_test/include/ct_property_test.hrl").
此包含的文件将
- 包含正确的工具的包含文件
- 将宏
'MOD_eqc'
设置为所选工具的正确模块名称。也就是说,宏'MOD_eqc'
设置为eqc
、proper
或triq
。
-spec num_calls(Cs) -> Result when Cs :: command_list() | parallel_testcase(), Result :: [non_neg_integer()].
返回测试用例中命令调用的次数。
有关更多信息,请参见:present_result/5
。
-spec present_result(Module, Cmds, Triple, Config) -> boolean() when Module :: module(), Cmds :: command_list() | parallel_testcase(), Triple :: {H, Sf, Result}, H :: history(), Sf :: dynamic_state(), Result :: statem_result(), Config :: proplists:proplist().
-spec present_result(Module, Cmds, Triple, Config, Options0) -> boolean() when Module :: module(), Cmds :: command_list() | parallel_testcase(), Triple :: {H, Sf, Result}, H :: history(), Sf :: dynamic_state(), Result :: statem_result(), Config :: proplists:proplist(), Options0 :: proplists:proplist().
使用 PropEr、QuickCheck 或其他类似属性测试工具中的聚合函数,呈现有状态(statem)属性测试的结果。
假设它在 quickcheck/2
调用的属性内调用
...
RunResult = run_parallel_commands(?MODULE, Cmds),
ct_property_test:present_result(?MODULE, Cmds, RunResult, Config)
...
有关用法和默认打印输出的示例,请参见用户指南。
StatisticsSpec
是元组的列表
{Title::string(), CollectFun::fun/1}
{Title::string(), FrequencyFun::/0, CollectFun::fun/1}
每个元组将按照它们在列表中的位置顺序生成一个表格。
Title
将是一个结果表格的标题CollectFun
使用一个参数调用:Cmds
。它应返回要计数的列表。存在以下预定义函数ct_property_test:cmnd_names/1
返回在Cmnd
序列中生成的命令(函数调用)列表,不包含模块、参数和其他详细信息。ct_property_test:num_calls/1
返回命令列表长度的列表ct_property_test:sequential_parallel/1
返回包含来自Tool:parallel_commands/1,2
的顺序和并行部分信息的列表
FrequencyFun/0
返回一个 fun/1,它应该将项目列表作为输入,并返回一个 iolist,该 iolist 将作为表格打印。默认情况下,将计算每个项目的数量并打印每个项目的百分比。例如,列表 [a,b,a,a,c] 可以返回["a 60%\n","b 20%\n","c 20%\n"]
这将由
print_fun
打印。默认的print_fun
将其打印为a 60% b 20% c 20%
默认的 StatisticsSpec
是
对于顺序命令
[{"Function calls", fun cmnd_names/1}, {"Length of command sequences", fun print_frequency_ranges/0, fun num_calls/1}]
对于并行命令
[{"Distribution sequential/parallel", fun sequential_parallel/1}, {"Function calls", fun cmnd_names/1}, {"Length of command sequences", fun print_frequency_ranges/0, fun num_calls/1}]
-spec quickcheck(Property, Config) -> true | {fail, Reason} when Property :: term(), Config :: proplists:proplist(), Reason :: term().
调用所选工具的函数以运行 Property
。通常并且由于历史原因,它被称为 quickcheck,这就是为什么在此模块 (ct_property_test
) 中使用该名称的原因。
结果以适合 Common Test
测试套件的形式返回。
此函数旨在在测试套件的测试用例中调用。
-spec sequential_parallel(Cs) -> Result when Cs :: command_list() | parallel_testcase(), Result :: [atom()].
返回包含有关顺序和并行部分信息的列表。
有关更多信息,请参见:present_result/5
。