檢視原始碼 Common Test 的屬性測試支援:ct_property_test
一般
Common Test 屬性測試支援 (ct_property_test) 是一個輔助工具,用於在 Common Test 測試套件中執行基於屬性的測試工具。
以下內容假設您已具備基於屬性的測試的基本知識。同時也假設您已安裝下列至少一個基於屬性的測試工具,並可在程式庫路徑中取得:
支援的功能
ct_property_test 模組會執行下列操作:
- 編譯
property_test
子目錄中包含屬性測試的檔案 - 使用第一個找到的屬性測試工具測試這些檔案中的屬性。
- 將結果(即輸出)儲存在常見的 Common Test 日誌中
入門範例
假設我們要測試 lists:sort/1 函式。
我們需要一個屬性來測試該函式。一般來說,我們會在應用程式的 test
目錄中建立 property_test/ct_prop.erl
模組
-module(ct_prop).
-export([prop_sort/0]).
%%% This will include the .hrl file for the installed testing tool:
-include_lib("common_test/include/ct_property_test.hrl").
%%% The property we want to check:
%%% For all possibly unsorted lists,
%%% the result of lists:sort/1 is sorted.
prop_sort() ->
?FORALL(UnSorted, list(),
is_sorted(lists:sort(UnSorted))
).
%%% Function to check that a list is sorted:
is_sorted([]) ->
true;
is_sorted([_]) ->
true;
is_sorted([H1,H2|SortedTail]) when H1 =< H2 ->
is_sorted([H2|SortedTail]);
is_sorted(_) ->
false.
我們也需要一個 CommonTest 測試套件
-module(ct_property_test_SUITE).
-compile(export_all). % Only in tests!
-include_lib("common_test/include/ct.hrl").
all() -> [prop_sort
].
%%% First prepare Config and compile the property tests for the found tool:
init_per_suite(Config) ->
ct_property_test:init_per_suite(Config).
end_per_suite(Config) ->
Config.
%%%================================================================
%%% Test suites
%%%
prop_sort(Config) ->
ct_property_test:quickcheck(
ct_prop:prop_sort(),
Config
).
我們像往常一樣執行它,例如使用 OS shell 中的 ct_run
..../test$ ct_run -suite ct_property_test_SUITE
.....
Common Test: Running make in test directories...
TEST INFO: 1 test(s), 1 case(s) in 1 suite(s)
Testing lib.common_test.ct_property_test_SUITE: Starting test, 1 test cases
----------------------------------------------------
2019-12-18 10:44:46.293
Found property tester proper
at "/home/X/lib/proper/ebin/proper.beam"
----------------------------------------------------
2019-12-18 10:44:46.294
Compiling in "/home/..../test/property_test"
Deleted: ["ct_prop.beam"]
ErlFiles: ["ct_prop.erl"]
MacroDefs: [{d,'PROPER'}]
Testing lib.common_test.ct_property_test_SUITE: TEST COMPLETE, 1 ok, 0 failed of 1 test cases
....
一個具狀態測試的範例
假設有一個測試會產生一些平行的具狀態命令,並執行 300 個測試
prop_parallel(Config) ->
numtests(300,
?FORALL(Cmds, parallel_commands(?MODULE),
begin
RunResult = run_parallel_commands(?MODULE, Cmds),
ct_property_test:present_result(?MODULE, Cmds, RunResult, Config)
end)).
ct_property_test:present_result/4
是一個輔助函式,用於在 CommonTest 日誌檔案中列印一些統計資訊。
我們的範例測試可以是一個簡單的 FTP 伺服器測試,我們執行 get、put 和 delete 請求,其中一些是平行執行的。預設情況下,結果有三個部分
*** User 2019-12-11 13:28:17.504 ***
Distribution sequential/parallel
57.7% sequential
28.0% parallel_2
14.3% parallel_1
*** User 2019-12-11 13:28:17.505 ***
Function calls
44.4% get
39.3% put
16.3% delete
*** User 2019-12-11 13:28:17.505 ***
Length of command sequences
Range : Number in range
-------:----------------
0 - 4: 8 2.7% <-- min=3
5 - 9: 44 14.7%
10 - 14: 74 24.7%
15 - 19: 60 20.0% <-- mean=18.7 <-- median=16.0
20 - 24: 38 12.7%
25 - 29: 26 8.7%
30 - 34: 19 6.3%
35 - 39: 19 6.3%
40 - 44: 8 2.7%
45 - 49: 4 1.3% <-- max=47
------
300
第一部分 - 分佈循序/平行 - 顯示 parallel_commands/1 結果的循序和平行部分的分配。有關此函式的說明,請參閱任何屬性測試工具。該表顯示,在所有命令(在本例中為 get 和 put)中,57.7% 在平行部分之前的循序部分執行,28.0% 在第一個平行清單中執行,其餘在第二個平行清單中執行。
第二部分 - 函式呼叫 - 顯示產生的命令清單中三個呼叫的分佈。我們看到所有三個呼叫都已執行。如果我們認為我們也產生了第四個呼叫,像這樣的表格會顯示我們失敗了。
第三個也是最後一個部分 - 命令序列的長度 - 顯示產生命令序列的統計資訊。我們看到最短的清單有三個元素,而最長的清單有 47 個元素。還會顯示平均值和中位數。此外,例如我們可以看到只有 2.7% 的清單(即八個清單)只有三個或四個元素。