<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">

<chapter>
  <header>
    <copyright>
      <year>2003</year><year>2013</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
 
          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.

    </legalnotice>

    <title>Examples and Templates</title>
    <prepared>Peter Andersson</prepared>
    <docno></docno>
    <date></date>
    <rev></rev>
    <file>example_chapter.xml</file>
  </header>
  
  <marker id="top"></marker>

  <section>
    <title>Test Suite Example</title>
    <p>The following example test suite shows some tests of a database server:
    </p>

<code>
 -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 = ?config(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 = ?config(con_ref, Config),   
     TableName = ?config(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 = ?config(con_ref, Config),   
     TableName = ?config(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 = ?config(con_ref, Config),   
     TableName = ?config(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.</code>
  </section>

  <section>
    <title>Test Suite Templates</title>
    <p>The Erlang mode for the Emacs editor includes two <c>Common Test</c> 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:
    </p>

    <p><em>Large Common Test Suite</em></p>
<code>
 %%%-------------------------------------------------------------------
 %%% 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.</code>
    <br></br>
    <p><em>Small Common Test Suite</em></p>
<code>
 %%%-------------------------------------------------------------------
 %%% 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.</code>
    </section>
</chapter>