ct
Main user interface for the Common Test framework.
Main user interface for the Common Test framework.
This module implements the command line interface for running tests and some basic functions for common test case issues such as configuration and logging.
Test Suite Support Macros
The config
macro is defined in ct.hrl
. This
macro should be used to retrieve information from the
Config
variable sent to all test cases. It is used with two
arguments, where the first is the name of the configuration
variable you wish to retrieve, and the second is the Config
variable supplied to the test case.
Possible configuration variables include:
data_dir
- Data file directory.priv_dir
- Scratch file directory.Whatever added by
init_per_suite/1
orinit_per_testcase/2
in the test suite.
DATA TYPES
handle() = handle() (see module ct_gen_conn) | term()
The identity of a specific connection.
target_name() = var_name()
The name of a target.
var_name() = atom()
A variable name which is specified when
ct:require/2
is called,
e.g. ct:require(mynodename,{node,[telnet]})
Functions
install(Opts) -> ok | {error, Reason}
Opts = [Opt]
Opt = {config, ConfigFiles} | {event_handler, Modules}
ConfigFiles = [ConfigFile]
ConfigFile = string()
Modules = [atom()]
Install config files and event handlers.
Run this function once before first test.
Example:
install([{config,["config_node.ctc","config_user.ctc"]}])
.
Note that this function is automatically run by the
run_test
script.
run(TestDir, Suite, Cases) -> Result
TestDir = string()
Suite = atom()
Cases = atom() | [atom()]
Result = [TestResult] | {error, Reason}
Run the given testcase(s).
Requires that ct:install/1
has been run first.
Suites (*_SUITE.erl) files must be stored in
TestDir
or TestDir/test
. All suites
will be compiled when test is run.
run(TestDir, Suite) -> Result
run(TestDirs) -> Result
TestDirs = TestDir | [TestDir]
run_test(Opts) -> Result
Opts = [OptTuples]
OptTuples = {config, CfgFiles} | {dir, TestDirs} | {suite, Suites} | {testcase, Cases} | {spec, TestSpecs} | {allow_user_terms, Bool} | {logdir, LogDir} | {silent_connections, Conns} | {cover, CoverSpecFile} | {event_handler, EventHandlers} | {repeat, N} | {duration, DurTime} | {until, StopTime} | {force_stop, Bool}
CfgFiles = [string()] | string()
TestDirs = [string()] | string()
Suites = [string()] | string()
Cases = [atom()] | atom()
TestSpecs = [string()] | string()
LogDir = string()
EventHandlers = EH | [EH]
EH = atom() | {atom(), InitArgs} | {[atom()], InitArgs}
InitArgs = [term()]
Conns = all | [atom()]
CoverSpecFile = string()
N = integer()
DurTime = string(HHMMSS)
StopTime = string(YYMoMoDDHHMMSS) | string(HHMMSS)
Result = [TestResult] | {error, Reason}
Run tests as specified by the combination of options in Opts
.
The options are the same as those used with the run_test
script.
Note that here a TestDir
can be used to point out the path to
a Suite
. Note also that the option testcase
corresponds to the -case
option in the run_test
script. Configuration files specified in Opts
will be
installed automatically at startup.
run_testspec(TestSpec) -> Result
TestSpec = [term()]
Run test specified by TestSpec
. The terms are
the same as those used in test specification files.
step(TestDir, Suite, Case) -> Result
Case = atom()
start_interactive() -> ok
Start CT in interactive mode.
From this mode all test case support functions can be executed
directly from the erlang shell. The interactive mode can also be
started from the unix command line with run_test -shell
[-config File...]
.
If any functions using "required config data" (e.g. telnet or
ftp functions) are to be called from the erlang shell, config data
must first be required with ct:require/2
.
Example:
> ct:require(a,{unix,[telnet]}).
ok
> ct:cmd(a,"ls").
{ok,["ls","file1 ...",...]}
stop_interactive() -> ok
require(Required) -> ok | {error, Reason}
Required = Key | {Key, SubKeys}
Key = atom()
SubKeys = SubKey | [SubKey]
SubKey = atom()
Check if the required configuration is available.
Example: require the variable myvar
:
ok = ct:require(myvar)
In this case the config file must at least contain:
{myvar,Value}.
Example: require the variable myvar
with
subvariable sub1
:
ok = ct:require({myvar,sub1})
In this case the config file must at least contain:
{myvar,[{sub1,Value}]}.
See also: get_config/1, get_config/2, require/2.
require(Name, Required) -> ok | {error, Reason}
Name = atom()
Required = Key | {Key, SubKeys}
Key = atom()
SubKeys = SubKey | [SubKey]
SubKey = atom()
Check if the required configuration is available, and give it a name.
If the requested data is available, the main entry will be
marked as allocated. An allocated element can only be used if the
correct name is given. This means that to read the value of the
element with get_config/1,2
, you need to provide the
Name
instead of the Key
.
Example: Require one node with a telnet connection and an
ftp connection. Name the node a
:
ok =
ct:require(a,{node,[telnet,ftp]}).
All references
to this node must then use the node name. E.g. you can fetch a
file over ftp like this:
ok = ct:ftp_get(a,RemoteFile,LocalFile).
For this to work, the config file must at least contain:
{node,[{telnet,IpAddr}, {ftp,IpAddr}]}.
See also: get_config/1, get_config/2, require/1.
get_config(Required) -> Value
Equivalent to get_config(Required, undefined).
get_config(Required, Default) -> Value
Required = KeyOrName | {KeyOrName, SubKey}
KeyOrName = atom()
SubKey = atom()
Default = term()
Value = term() | Default
Get the value of config data.
This function returns the value of the requested config element.
Example, given the following config file:
{unix,[{telnet,IpAddr}, {username,Username}, {password,Password}]}.
get_config(unix,Default) ->
[{telnet,IpAddr},
{username,Username},
{password,Password}]
get_config({unix,telnet},Default) -> IpAddr
get_config({unix,ftp},Default) -> Default
get_config(unknownkey,Default) -> Default
If you want to access a config variable which has been given a
name by require/2
, the name must be used instead of
the key when reading the value:
require(myhost,unix) -> ok
get_config(myhost,Default) ->
[{telnet,IpAddr},
{username,Username},
{password,Password}]
See also: get_config/1, require/1, require/2.
log(Format) -> ok
Equivalent to log(default, Format, []).
log(X1, X2) -> ok
X1 = Category | Format
X2 = Format | Args
Equivalent to log(Category, Format, Args).
log(Category, Format, Args) -> ok
Category = atom()
Format = string()
Args = list()
Printout from a testcase to the log.
This function is meant for printing stuff directly from a testcase (i.e. not from within the CT framework) in the test log.
Default Category
is default
and
default Args
is []
.
print(Format) -> ok
Equivalent to print(default, Format, []).
print(X1, X2) -> term()
Equivalent to print(Category, Format, Args).
print(Category, Format, Args) -> ok
Category = atom()
Format = string()
Args = list()
Printout from a testcase to the console.
This function is meant for printing stuff from a testcase on the console.
Default Category
is default
and
default Args
is []
.
pal(Format) -> ok
Equivalent to pal(default, Format, []).
pal(X1, X2) -> ok
X1 = Category | Format
X2 = Format | Args
Equivalent to pal(Category, Format, Args).
pal(Category, Format, Args) -> ok
Category = atom()
Format = string()
Args = list()
Print and log from a testcase.
This function is meant for printing stuff from a testcase both in the log and on the console.
Default Category
is default
and
default Args
is []
.
fail(Reason) -> void()
Reason = term()
Terminate a test case with the given error
Reason
.
comment(Comment) -> void()
Comment = term()
Print the given Comment
in the comment field of
the table on the test suite result page.
If called several times, only the last comment is printed.
comment/1
is also overwritten by the return value
{comment,Comment}
or by the function
fail/1
(which prints Reason
as a
comment).
get_target_name(Handle) -> {ok, TargetName} | {error, Reason}
Handle = handle()
TargetName = target_name()
Return the name of the target that the given connection belongs to.
parse_table(Data) -> {Heading, Table}
Data = [string()]
Heading = tuple()
Table = [tuple()]
Parse the printout from an SQL table and return a list of tuples.
The printout to parse would typically be the result of a
select
command in SQL. The returned
Table
is a list of tuples, where each tuple is a row
in the table.
Heading
is a tuple of strings representing the
headings of each column in the table.
listenv(Telnet) -> [Env]
Telnet = term()
Env = {Key, Value}
Key = string()
Value = string()
Performs the listenv command on the given telnet connection and returns the result as a list of Key-Value pairs.
testcases(TestDir, Suite) -> Testcases | {error, Reason}
TestDir = string()
Suite = atom()
Testcases = list()
Reason = term()
Returns all testcases in the specified suite.
userdata(TestDir, Suite) -> SuiteUserData | {error, Reason}
TestDir = string()
Suite = atom()
SuiteUserData = [term()]
Reason = term()
Returns any data specified with the tag userdata
in the list of tuples returned from Suite:suite/0
.
userdata(TestDir, Suite, Case) -> TCUserData | {error, Reason}
TestDir = string()
Suite = atom()
Case = atom()
TCUserData = [term()]
Reason = term()
Returns any data specified with the tag userdata
in the list of tuples returned from Suite:Case/0
.
get_status() -> TestStatus | {error, Reason}
TestDir = term()
Reason = term()
Returns status of ongoing tests.
abort_current_testcase(Reason) -> ok | {error, no_testcase_running}
Reason = term()
When calling this function, the currently executing test case will be aborted. It is the user's responsibility to know for sure which test case is currently executing. The function is therefore only safe to call from a function which has been called (or synchronously invoked) by the test case.
Reason
, the reason for aborting the test case, is printed
in the test case log.
- install/1
- run/3
- run/2
- run/1
- run_test/1
- run_testspec/1
- step/3
- start_interactive/0
- stop_interactive/0
- require/1
- require/2
- get_config/1
- get_config/2
- log/1
- log/2
- log/3
- print/1
- print/2
- print/3
- pal/1
- pal/2
- pal/3
- fail/1
- comment/1
- get_target_name/1
- parse_table/1
- listenv/1
- testcases/2
- userdata/2
- userdata/3
- get_status/0
- abort_current_testcase/1