7  Examples and Templates

7 Examples and Templates

The following example test suite shows some tests of a database server:

 -module(db_data_type_SUITE).

 -include_lib("common_test/include/ct.hrl").

 %% Test server callbacks
 -export([suite/0, all/0, 
	  init_per_suite/1, end_per_suite/1,
	  init_per_testcase/2, end_per_testcase/2]).

 %% Test cases
 -export([string/1, integer/1]).

 -define(CONNECT_STR, "DSN=sqlserver;UID=alladin;PWD=sesame").

 %%--------------------------------------------------------------------
 %% COMMON TEST CALLBACK FUNCTIONS
 %%--------------------------------------------------------------------

 %%--------------------------------------------------------------------
 %% Function: suite() -> Info
 %%
 %% Info = [tuple()]
 %%   List of key/value pairs.
 %%
 %% Description: Returns list of tuples to set default properties
 %%              for the suite.
 %%--------------------------------------------------------------------
 suite() -> 
     [{timetrap,{minutes,1}}].  

 %%--------------------------------------------------------------------
 %% Function: init_per_suite(Config0) -> Config1
 %%
 %% Config0 = Config1 = [tuple()]
 %%   A list of key/value pairs, holding the test case configuration.
 %%
 %% Description: Initialization before the suite.
 %%--------------------------------------------------------------------
 init_per_suite(Config) -> 
     {ok, Ref} = db:connect(?CONNECT_STR, []),
     TableName = db_lib:unique_table_name(),	
     [{con_ref, Ref },{table_name, TableName}| Config]. 

 %%--------------------------------------------------------------------
 %% Function: end_per_suite(Config) -> term()
 %%
 %% Config = [tuple()]
 %%   A list of key/value pairs, holding the test case configuration.
 %%
 %% Description: Cleanup after the suite.
 %%--------------------------------------------------------------------
 end_per_suite(Config) ->    
     Ref = proplists:get_value(con_ref, Config),
     db:disconnect(Ref),
     ok.
 
 %%--------------------------------------------------------------------
 %% Function: init_per_testcase(TestCase, Config0) -> Config1
 %%
 %% TestCase = atom()
 %%   Name of the test case that is about to run.
 %% Config0 = Config1 = [tuple()]
 %%   A list of key/value pairs, holding the test case configuration.
 %%
 %% Description: Initialization before each test case.
 %%--------------------------------------------------------------------
 init_per_testcase(Case, Config) ->
     Ref = proplists:get_value(con_ref, Config),   
     TableName = proplists:get_value(table_name, Config),
     ok = db:create_table(Ref, TableName, table_type(Case)),
     Config.

 %%--------------------------------------------------------------------
 %% Function: end_per_testcase(TestCase, Config) -> term()
 %%
 %% TestCase = atom()
 %%   Name of the test case that is finished.
 %% Config = [tuple()]
 %%   A list of key/value pairs, holding the test case configuration.
 %%
 %% Description: Cleanup after each test case.
 %%--------------------------------------------------------------------
 end_per_testcase(_Case, Config) -> 
     Ref = proplists:get_value(con_ref, Config),   
     TableName = proplists:get_value(table_name, Config),
     ok = db:delete_table(Ref, TableName),   
     ok. 

 %%--------------------------------------------------------------------
 %% Function: all() -> GroupsAndTestCases
 %%
 %% GroupsAndTestCases = [{group,GroupName} | TestCase]
 %% GroupName = atom()
 %%   Name of a test case group.
 %% TestCase = atom()
 %%   Name of a test case.
 %%
 %% Description: Returns the list of groups and test cases that
 %%              are to be executed.
 %%--------------------------------------------------------------------
 all() ->
     [string, integer]. 


 %%--------------------------------------------------------------------
 %% TEST CASES
 %%--------------------------------------------------------------------

 string(Config) -> 
     insert_and_lookup(dummy_key, "Dummy string", Config).

 integer(Config) -> 
     insert_and_lookup(dummy_key, 42, Config).


 insert_and_lookup(Key, Value, Config) ->
     Ref = proplists:get_value(con_ref, Config),   
     TableName = proplists:get_value(table_name, Config),
     ok = db:insert(Ref, TableName, Key, Value),
     [Value] = db:lookup(Ref, TableName, Key),
     ok = db:delete(Ref, TableName, Key),
     [] = db:lookup(Ref, TableName, Key),
     ok.

The Erlang mode for the Emacs editor includes two Common Test test suite templates, one with extensive information in the function headers, and one with minimal information. A test suite template provides a quick start for implementing a suite from scratch and gives a good overview of the available callback functions. The two templates follows:

Large Common Test Suite

 %%%-------------------------------------------------------------------
 %%% File    : example_SUITE.erl
 %%% Author  : 
 %%% Description : 
 %%%
 %%% Created : 
 %%%-------------------------------------------------------------------
 -module(example_SUITE).

 %% Note: This directive should only be used in test suites.
 -compile(export_all).

 -include_lib("common_test/include/ct.hrl").

 %%--------------------------------------------------------------------
 %% COMMON TEST CALLBACK FUNCTIONS
 %%--------------------------------------------------------------------

 %%--------------------------------------------------------------------
 %% Function: suite() -> Info
 %%
 %% Info = [tuple()]
 %%   List of key/value pairs.
 %%
 %% Description: Returns list of tuples to set default properties
 %%              for the suite.
 %%
 %% Note: The suite/0 function is only meant to be used to return
 %% default data values, not perform any other operations.
 %%--------------------------------------------------------------------
 suite() ->
     [{timetrap,{minutes,10}}].

 %%--------------------------------------------------------------------
 %% Function: init_per_suite(Config0) ->
 %%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
 %%
 %% Config0 = Config1 = [tuple()]
 %%   A list of key/value pairs, holding the test case configuration.
 %% Reason = term()
 %%   The reason for skipping the suite.
 %%
 %% Description: Initialization before the suite.
 %%
 %% Note: This function is free to add any key/value pairs to the Config
 %% variable, but should NOT alter/remove any existing entries.
 %%--------------------------------------------------------------------
 init_per_suite(Config) ->
     Config.

 %%--------------------------------------------------------------------
 %% Function: end_per_suite(Config0) -> term() | {save_config,Config1}
 %%
 %% Config0 = Config1 = [tuple()]
 %%   A list of key/value pairs, holding the test case configuration.
 %%
 %% Description: Cleanup after the suite.
 %%--------------------------------------------------------------------
 end_per_suite(_Config) ->
     ok.

 %%--------------------------------------------------------------------
 %% Function: init_per_group(GroupName, Config0) ->
 %%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
 %%
 %% GroupName = atom()
 %%   Name of the test case group that is about to run.
 %% Config0 = Config1 = [tuple()]
 %%   A list of key/value pairs, holding configuration data for the group.
 %% Reason = term()
 %%   The reason for skipping all test cases and subgroups in the group.
 %%
 %% Description: Initialization before each test case group.
 %%--------------------------------------------------------------------
 init_per_group(_GroupName, Config) ->
     Config.

 %%--------------------------------------------------------------------
 %% Function: end_per_group(GroupName, Config0) ->
 %%               term() | {save_config,Config1}
 %%
 %% GroupName = atom()
 %%   Name of the test case group that is finished.
 %% Config0 = Config1 = [tuple()]
 %%   A list of key/value pairs, holding configuration data for the group.
 %%
 %% Description: Cleanup after each test case group.
 %%--------------------------------------------------------------------
 end_per_group(_GroupName, _Config) ->
     ok.

 %%--------------------------------------------------------------------
 %% Function: init_per_testcase(TestCase, Config0) ->
 %%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
 %%
 %% TestCase = atom()
 %%   Name of the test case that is about to run.
 %% Config0 = Config1 = [tuple()]
 %%   A list of key/value pairs, holding the test case configuration.
 %% Reason = term()
 %%   The reason for skipping the test case.
 %%
 %% Description: Initialization before each test case.
 %%
 %% Note: This function is free to add any key/value pairs to the Config
 %% variable, but should NOT alter/remove any existing entries.
 %%--------------------------------------------------------------------
 init_per_testcase(_TestCase, Config) ->
     Config.

 %%--------------------------------------------------------------------
 %% Function: end_per_testcase(TestCase, Config0) ->
 %%               term() | {save_config,Config1} | {fail,Reason}
 %%
 %% TestCase = atom()
 %%   Name of the test case that is finished.
 %% Config0 = Config1 = [tuple()]
 %%   A list of key/value pairs, holding the test case configuration.
 %% Reason = term()
 %%   The reason for failing the test case.
 %%
 %% Description: Cleanup after each test case.
 %%--------------------------------------------------------------------
 end_per_testcase(_TestCase, _Config) ->
     ok.

 %%--------------------------------------------------------------------
 %% Function: groups() -> [Group]
 %%
 %% Group = {GroupName,Properties,GroupsAndTestCases}
 %% GroupName = atom()
 %%   The name of the group.
 %% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
 %%   Group properties that may be combined.
 %% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
 %% TestCase = atom()
 %%   The name of a test case.
 %% Shuffle = shuffle | {shuffle,Seed}
 %%   To get cases executed in random order.
 %% Seed = {integer(),integer(),integer()}
 %% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
 %%              repeat_until_any_ok | repeat_until_any_fail
 %%   To get execution of cases repeated.
 %% N = integer() | forever
 %%
 %% Description: Returns a list of test case group definitions.
 %%--------------------------------------------------------------------
 groups() ->
     [].

 %%--------------------------------------------------------------------
 %% Function: all() -> GroupsAndTestCases | {skip,Reason}
 %%
 %% GroupsAndTestCases = [{group,GroupName} | TestCase]
 %% GroupName = atom()
 %%   Name of a test case group.
 %% TestCase = atom()
 %%   Name of a test case.
 %% Reason = term()
 %%   The reason for skipping all groups and test cases.
 %%
 %% Description: Returns the list of groups and test cases that
 %%              are to be executed.
 %%--------------------------------------------------------------------
 all() -> 
     [my_test_case].


 %%--------------------------------------------------------------------
 %% TEST CASES
 %%--------------------------------------------------------------------

 %%--------------------------------------------------------------------
 %% Function: TestCase() -> Info
 %%
 %% Info = [tuple()]
 %%   List of key/value pairs.
 %%
 %% Description: Test case info function - returns list of tuples to set
 %%              properties for the test case.
 %%
 %% Note: This function is only meant to be used to return a list of
 %% values, not perform any other operations.
 %%--------------------------------------------------------------------
 my_test_case() -> 
     [].

 %%--------------------------------------------------------------------
 %% Function: TestCase(Config0) ->
 %%               ok | exit() | {skip,Reason} | {comment,Comment} |
 %%               {save_config,Config1} | {skip_and_save,Reason,Config1}
 %%
 %% Config0 = Config1 = [tuple()]
 %%   A list of key/value pairs, holding the test case configuration.
 %% Reason = term()
 %%   The reason for skipping the test case.
 %% Comment = term()
 %%   A comment about the test case that will be printed in the html log.
 %%
 %% Description: Test case function. (The name of it must be specified in
 %%              the all/0 list or in a test case group for the test case
 %%              to be executed).
 %%--------------------------------------------------------------------
 my_test_case(_Config) -> 
     ok.

Small Common Test Suite

 %%%-------------------------------------------------------------------
 %%% File    : example_SUITE.erl
 %%% Author  : 
 %%% Description : 
 %%%
 %%% Created : 
 %%%-------------------------------------------------------------------
 -module(example_SUITE).

 -compile(export_all).

 -include_lib("common_test/include/ct.hrl").

 %%--------------------------------------------------------------------
 %% Function: suite() -> Info
 %% Info = [tuple()]
 %%--------------------------------------------------------------------
 suite() ->
     [{timetrap,{seconds,30}}].

 %%--------------------------------------------------------------------
 %% Function: init_per_suite(Config0) ->
 %%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
 %% Config0 = Config1 = [tuple()]
 %% Reason = term()
 %%--------------------------------------------------------------------
 init_per_suite(Config) ->
     Config.

 %%--------------------------------------------------------------------
 %% Function: end_per_suite(Config0) -> term() | {save_config,Config1}
 %% Config0 = Config1 = [tuple()]
 %%--------------------------------------------------------------------
 end_per_suite(_Config) ->
     ok.

 %%--------------------------------------------------------------------
 %% Function: init_per_group(GroupName, Config0) ->
 %%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
 %% GroupName = atom()
 %% Config0 = Config1 = [tuple()]
 %% Reason = term()
 %%--------------------------------------------------------------------
 init_per_group(_GroupName, Config) ->
     Config.

 %%--------------------------------------------------------------------
 %% Function: end_per_group(GroupName, Config0) ->
 %%               term() | {save_config,Config1}
 %% GroupName = atom()
 %% Config0 = Config1 = [tuple()]
 %%--------------------------------------------------------------------
 end_per_group(_GroupName, _Config) ->
     ok.

 %%--------------------------------------------------------------------
 %% Function: init_per_testcase(TestCase, Config0) ->
 %%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
 %% TestCase = atom()
 %% Config0 = Config1 = [tuple()]
 %% Reason = term()
 %%--------------------------------------------------------------------
 init_per_testcase(_TestCase, Config) ->
     Config.

 %%--------------------------------------------------------------------
 %% Function: end_per_testcase(TestCase, Config0) ->
 %%               term() | {save_config,Config1} | {fail,Reason}
 %% TestCase = atom()
 %% Config0 = Config1 = [tuple()]
 %% Reason = term()
 %%--------------------------------------------------------------------
 end_per_testcase(_TestCase, _Config) ->
     ok.

 %%--------------------------------------------------------------------
 %% Function: groups() -> [Group]
 %% Group = {GroupName,Properties,GroupsAndTestCases}
 %% GroupName = atom()
 %% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
 %% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
 %% TestCase = atom()
 %% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}
 %% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
 %%              repeat_until_any_ok | repeat_until_any_fail
 %% N = integer() | forever
 %%--------------------------------------------------------------------
 groups() ->
     [].

 %%--------------------------------------------------------------------
 %% Function: all() -> GroupsAndTestCases | {skip,Reason}
 %% GroupsAndTestCases = [{group,GroupName} | TestCase]
 %% GroupName = atom()
 %% TestCase = atom()
 %% Reason = term()
 %%--------------------------------------------------------------------
 all() -> 
     [my_test_case].

 %%--------------------------------------------------------------------
 %% Function: TestCase() -> Info
 %% Info = [tuple()]
 %%--------------------------------------------------------------------
 my_test_case() -> 
     [].

 %%--------------------------------------------------------------------
 %% Function: TestCase(Config0) ->
 %%               ok | exit() | {skip,Reason} | {comment,Comment} |
 %%               {save_config,Config1} | {skip_and_save,Reason,Config1}
 %% Config0 = Config1 = [tuple()]
 %% Reason = term()
 %% Comment = term()
 %%--------------------------------------------------------------------
 my_test_case(_Config) -> 
     ok.