<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html xmlns:fn="http://www.w3.org/2005/02/xpath-functions"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" href="../../../../doc/otp_doc.css" type="text/css"> <title>Erlang -- Examples and Templates</title> </head> <body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container"> <script id="js" type="text/javascript" language="JavaScript" src="../../../../doc/js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../../../../doc/js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript"> <!-- function getWinHeight() { var myHeight = 0; if( typeof( window.innerHeight ) == 'number' ) { //Non-IE myHeight = window.innerHeight; } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { //IE 6+ in 'standards compliant mode' myHeight = document.documentElement.clientHeight; } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { //IE 4 compatible myHeight = document.body.clientHeight; } return myHeight; } function setscrollpos() { var objf=document.getElementById('loadscrollpos'); document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2; } function addEvent(obj, evType, fn){ if (obj.addEventListener){ obj.addEventListener(evType, fn, true); return true; } else if (obj.attachEvent){ var r = obj.attachEvent("on"+evType, fn); return r; } else { return false; } } addEvent(window, 'load', setscrollpos); //--></script><div id="leftnav"><div class="innertube"> <img alt="Erlang logo" src="../../../../doc/erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="index.html">Reference Manual</a><br><a href="release_notes.html">Release Notes</a><br><a href="../pdf/common_test-1.4.7.pdf">PDF</a><br><a href="../../../../doc/index.html">Top</a></small><p><strong>Common Test</strong><br><strong>User's Guide</strong><br><small>Version 1.4.7</small></p> <br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p> <ul class="flipMenu" imagepath="../../../../doc/js/flipmenu"> <li id="no" title="Common Test Basics" expanded="false">Common Test Basics<ul> <li><a href="basics_chapter.html"> Top of chapter </a></li> <li title="Introduction"><a href="basics_chapter.html#id2257382">Introduction</a></li> <li title="Test Suite Organisation"><a href="basics_chapter.html#id2262699">Test Suite Organisation</a></li> <li title="Support Libraries"><a href="basics_chapter.html#id2262725">Support Libraries</a></li> <li title="Suites and Test Cases"><a href="basics_chapter.html#id2252225">Suites and Test Cases</a></li> <li title="External Interfaces"><a href="basics_chapter.html#id2252025">External Interfaces</a></li> </ul> </li> <li id="no" title="Installation" expanded="false">Installation<ul> <li><a href="install_chapter.html"> Top of chapter </a></li> <li title="General information"><a href="install_chapter.html#id2259791">General information</a></li> <li title="Unix/Linux"><a href="install_chapter.html#id2259969">Unix/Linux</a></li> <li title="Windows"><a href="install_chapter.html#id2252127">Windows</a></li> </ul> </li> <li id="no" title="Writing Test Suites" expanded="false">Writing Test Suites<ul> <li><a href="write_test_chapter.html"> Top of chapter </a></li> <li title="Support for test suite authors"><a href="write_test_chapter.html#id2263189">Support for test suite authors</a></li> <li title="Test suites"><a href="write_test_chapter.html#id2263446">Test suites</a></li> <li title="Init and end per suite"><a href="write_test_chapter.html#id2252033">Init and end per suite</a></li> <li title="Init and end per test case"><a href="write_test_chapter.html#id2263397">Init and end per test case</a></li> <li title="Test cases"><a href="write_test_chapter.html#id2252705">Test cases</a></li> <li title="Test case info function"><a href="write_test_chapter.html#id2252952">Test case info function</a></li> <li title="Test suite info function"><a href="write_test_chapter.html#id2264301">Test suite info function</a></li> <li title="Test case groups"><a href="write_test_chapter.html#id2264393">Test case groups</a></li> <li title="The parallel property and nested groups"><a href="write_test_chapter.html#id2264666">The parallel property and nested groups</a></li> <li title="Repeated groups"><a href="write_test_chapter.html#id2264711">Repeated groups</a></li> <li title="Shuffled test case order"><a href="write_test_chapter.html#id2264872">Shuffled test case order</a></li> <li title="Data and Private Directories"><a href="write_test_chapter.html#id2264941">Data and Private Directories</a></li> <li title="Execution environment"><a href="write_test_chapter.html#id2265020">Execution environment</a></li> <li title="Illegal dependencies"><a href="write_test_chapter.html#id2265070">Illegal dependencies</a></li> </ul> </li> <li id="no" title="Test Structure" expanded="false">Test Structure<ul> <li><a href="test_structure_chapter.html"> Top of chapter </a></li> <li title="Test structure"><a href="test_structure_chapter.html#id2265289">Test structure</a></li> <li title="Skipping test cases"><a href="test_structure_chapter.html#id2265306">Skipping test cases</a></li> <li title="Definition of terms"><a href="test_structure_chapter.html#id2265390">Definition of terms</a></li> </ul> </li> <li id="loadscrollpos" title="Examples and Templates" expanded="true">Examples and Templates<ul> <li><a href="example_chapter.html"> Top of chapter </a></li> <li title="Test suite example"><a href="example_chapter.html#id2266177">Test suite example</a></li> <li title="Test suite templates"><a href="example_chapter.html#id2266264">Test suite templates</a></li> </ul> </li> <li id="no" title="Running Test Suites" expanded="false">Running Test Suites<ul> <li><a href="run_test_chapter.html"> Top of chapter </a></li> <li title="Using the Common Test Framework"><a href="run_test_chapter.html#id2266562">Using the Common Test Framework</a></li> <li title="Automatic compilation of test suites and help modules"><a href="run_test_chapter.html#id2266607">Automatic compilation of test suites and help modules</a></li> <li title="Running tests from the UNIX command line"><a href="run_test_chapter.html#id2266741">Running tests from the UNIX command line</a></li> <li title="Running tests from the Web based GUI"><a href="run_test_chapter.html#id2267056">Running tests from the Web based GUI</a></li> <li title="Running tests from the Erlang shell or from an Erlang program"><a href="run_test_chapter.html#id2267143">Running tests from the Erlang shell or from an Erlang program</a></li> <li title="Running the interactive shell mode"><a href="run_test_chapter.html#id2267199">Running the interactive shell mode</a></li> <li title="Step by step execution of test cases with the Erlang Debugger"><a href="run_test_chapter.html#id2267375">Step by step execution of test cases with the Erlang Debugger</a></li> <li title="Using test specifications"><a href="run_test_chapter.html#id2267476">Using test specifications</a></li> <li title="Log files"><a href="run_test_chapter.html#id2267715">Log files</a></li> <li title="HTML Style Sheets"><a href="run_test_chapter.html#id2267921">HTML Style Sheets</a></li> <li title="Repeating tests"><a href="run_test_chapter.html#id2268107">Repeating tests</a></li> <li title="Silent Connections"><a href="run_test_chapter.html#id2268354">Silent Connections</a></li> </ul> </li> <li id="no" title="Config Files" expanded="false">Config Files<ul> <li><a href="config_file_chapter.html"> Top of chapter </a></li> <li title="General"><a href="config_file_chapter.html#id2268593">General</a></li> <li title="Syntax"><a href="config_file_chapter.html#id2268633">Syntax</a></li> <li title="Requiring and reading configuration data"><a href="config_file_chapter.html#id2268657">Requiring and reading configuration data</a></li> <li title="Using configuration variables defined in multiple files"><a href="config_file_chapter.html#id2268807">Using configuration variables defined in multiple files</a></li> <li title="Encrypted configuration files"><a href="config_file_chapter.html#id2268839">Encrypted configuration files</a></li> <li title="Opening connections by using configuration data"><a href="config_file_chapter.html#id2268904">Opening connections by using configuration data</a></li> <li title="Examples"><a href="config_file_chapter.html#id2268977">Examples</a></li> </ul> </li> <li id="no" title="Code Coverage Analysis" expanded="false">Code Coverage Analysis<ul> <li><a href="cover_chapter.html"> Top of chapter </a></li> <li title="General"><a href="cover_chapter.html#id2269096">General</a></li> <li title="Usage"><a href="cover_chapter.html#id2269123">Usage</a></li> <li title="The cover specification file"><a href="cover_chapter.html#id2269250">The cover specification file</a></li> <li title="Logging"><a href="cover_chapter.html#id2269317">Logging</a></li> </ul> </li> <li id="no" title="Using Common Test for Large Scale Testing" expanded="false">Using Common Test for Large Scale Testing<ul> <li><a href="ct_master_chapter.html"> Top of chapter </a></li> <li title="General"><a href="ct_master_chapter.html#id2269392">General</a></li> <li title="Usage"><a href="ct_master_chapter.html#id2269436">Usage</a></li> <li title="Test Specifications"><a href="ct_master_chapter.html#id2269594">Test Specifications</a></li> </ul> </li> <li id="no" title="Event Handling" expanded="false">Event Handling<ul> <li><a href="event_handler_chapter.html"> Top of chapter </a></li> <li title="General"><a href="event_handler_chapter.html#id2269865">General</a></li> <li title="Usage"><a href="event_handler_chapter.html#id2269911">Usage</a></li> </ul> </li> <li id="no" title="Dependencies between Test Cases and Suites" expanded="false">Dependencies between Test Cases and Suites<ul> <li><a href="dependencies_chapter.html"> Top of chapter </a></li> <li title="General"><a href="dependencies_chapter.html#id2270845">General</a></li> <li title="Saving configuration data"><a href="dependencies_chapter.html#id2271007">Saving configuration data</a></li> <li title="Sequences"><a href="dependencies_chapter.html#id2271201">Sequences</a></li> </ul> </li> <li id="no" title="Some thoughts about testing" expanded="false">Some thoughts about testing<ul> <li><a href="why_test_chapter.html"> Top of chapter </a></li> <li title="Goals"><a href="why_test_chapter.html#id2271413">Goals</a></li> <li title="What to test?"><a href="why_test_chapter.html#id2271438">What to test?</a></li> </ul> </li> </ul> </div></div> <div id="content"> <div class="innertube"> <h1>5 Examples and Templates</h1> <h3><a name="id2266177">5.1 Test suite example</a></h3> <p>This example test suite shows some tests of a database server. </p> <div class="example"><pre> -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) -> void() %% %% 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) -> void() %% %% 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. </pre></div> <h3><a name="id2266264">5.2 Test suite templates</a></h3> <p>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 you a good overview of the available callback functions. Here are the templates in question: </p> <p><strong>Large Common Test suite</strong></p> <div class="example"><pre> %%%------------------------------------------------------------------- %%% 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) -> void() | {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) -> %% void() | {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) -> %% void() | {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. </pre></div> <br> <p><strong>Small Common Test suite</strong></p> <div class="example"><pre> %%%------------------------------------------------------------------- %%% 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) -> void() | {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) -> %% void() | {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) -> %% void() | {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. </pre></div> </div> <div class="footer"> <hr> <p>Copyright © 2003-2010 Ericsson AB. All Rights Reserved.</p> </div> </div> </div></body> </html>