6 Examples

6.1  Test suite

-module(my_SUITE).

-export([all/1,
         not_started/1, not_started_func1/1, not_started_func2/1,
         start/1, stop/1,
         func1/1, func2/1 
        ]).

-export([init_per_testcase/2, end_per_testcase/2]).

-include("test_server.hrl").

-define(default_timeout, ?t:minutes(1)).

init_per_testcase(_Case, Config) ->
    ?line Dog=?t:timetrap(?default_timeout),
    [{watchdog, Dog}|Config].
end_per_testcase(_Case, Config) ->
    Dog=?config(watchdog, Config),
    ?t:timetrap_cancel(Dog),
    ok.

all(suite) -> 
    %% Test specification on test suite level
    [not_started,
     {conf, start, [func1, func2], stop}].

not_started(suite) ->
    %% Test specification on test case level
    [not_started_func1, not_started_func2];
not_started(doc) ->
    ["Testing all functions when application is not started"].
%% No execution clause unless the specification clause returns [].


not_started_func1(suite) ->
    [];
not_started_func1(doc) ->
    ["Testing function 1 when application is not started"].
not_started_func1(Config) when list(Config) ->
    ?line {error, not_started} = myapp:func1(dummy_ref,1),
    ?line {error, not_started} = myapp:func1(dummy_ref,2),
    ok.

not_started_func2(suite) ->
    [];
not_started_func2(doc) ->
    ["Testing function 2 when application is not started"].
not_started_func2(Config) when list(Config) ->
    ?line {error, not_started} = myapp:func2(dummy_ref,1),
    ?line {error, not_started} = myapp:func2(dummy_ref,2),
    ok.


%% No specification clause needed for an init function in a conf case!!!
start(doc) ->
    ["Testing start of my application."];
start(Config) when list(Config) ->
    ?line Ref = myapp:start(),
    case erlang:whereis(my_main_process) of
      Pid when pid(Pid) -> 
         [{myapp_ref,Ref}|Config];
      undefined -> 
         %% Since this is the init function in a conf case, the rest of the 
         %% cases in the conf case will be skipped if this case fails.
         ?t:fail("my_main_process did not start")
    end.

func1(suite) ->
    [];
func1(doc) ->
    ["Test that func1 returns ok when argument is 1 and error if argument is 2"];
func1(Config) when list(Config) ->
    ?line Ref = ?config(myapp_ref,Config),
    ?line ok = myapp:func1(Ref,1),
    ?line error = myapp:func1(Ref,2),
    ok.

func2(suite) ->
    [];
func2(doc) ->
    ["Test that func1 returns ok when argument is 3 and error if argument is 4"];
func2(Config) when list(Config) ->
    ?line Ref = ?config(myapp_ref,Config),
    ?line ok = myapp:func2(Ref,3),
    ?line error = myapp:func2(Ref,4),
    ok.

%% No specification clause needed for a cleanup function in a conf case!!!
stop(doc) ->
    ["Testing termination of my application"];
stop(Config) when list(Config) ->
    ?line Ref = ?config(myapp_ref,Config),
    ?line ok = myapp:stop(Ref),
    case erlang:whereis(my_main_process) of
      undefined -> 
         lists:keydelete(myapp_ref,1,Config);
      Pid when pid(Pid) -> 
         ?t:fail("my_main_process did not stop")
    end.
    

6.2  Test specification file

myapp.spec:

{topcase, {dir, "../myapp_test"}}. % Test specification on top level    

myapp.spec.vxworks:

{topcase, {dir, "../myapp_test"}}. % Test specification on top level
{skip,{my_SUITE,func2,"Not applicable on VxWorks"}}.