Automated Testing Framework

Examples

This page provides some examples of tests written using ATF as well as the output of running these tests. The tests verify the functionality of some standard system routines and tools, but you can equally apply these tests to your own applications.

The tests

This section illustrates some sample test programs written using the ATF framework and later shows the results of their execution.

Test programs using the C/C++ binding

The following sample C++ test program does some simple tests on the standard pow and snprintf functions.

// The t_example_1.cpp test program.

#include <atf.hpp>

#include <cmath>
#include <cstdio>
#include <cstring>

ATF_TEST_CASE(pow_func);
ATF_TEST_CASE_HEAD(pow_func)
{
    set("descr", "Checks the pow function");
}
ATF_TEST_CASE_BODY(pow_func)
{
    using std::pow;

    ATF_CHECK_EQUAL(pow(2.0, 0.0), 1);
    ATF_CHECK_EQUAL(pow(2.0, 1.0), 2);
    ATF_CHECK_EQUAL(pow(2.0, 2.0), 4);
    ATF_CHECK_EQUAL(pow(2.0, 3.0), 8);
}

ATF_TEST_CASE(snprintf_func);
ATF_TEST_CASE_HEAD(snprintf_func)
{
    set("descr", "Checks the snprintf function");
}
ATF_TEST_CASE_BODY(snprintf_func)
{
    using std::snprintf;
    using std::strcmp;

    char buf[80];

    snprintf(buf, 80, "Hello");
    ATF_CHECK(strcmp(buf, "Hello") == 0);

    snprintf(buf, 80, "Hello %d", 5);
    ATF_CHECK(strcmp(buf, "Hello 5") == 0);

    snprintf(buf, 80, "Hello %s", "world");
    ATF_CHECK(strcmp(buf, "Hello world") == 0);
}

ATF_INIT_TEST_CASES(tcs)
{
    ATF_ADD_TEST_CASE(tcs, pow_func);
    ATF_ADD_TEST_CASE(tcs, snprintf_func);
}

In order to build the above test program, do:

$ gcc $(pkg-config --cflags atf) \
  -o t_example_1.o -c t_example_1.cpp
$ gcc $(pkg-config --libs-only-L --libs-only-other atf) \
  -o t_example_1 t_example_1.o $(pkg-config --libs-only-l)

Test programs using the POSIX shell binding

Let's assume that we want to write some tests to verify that the standard ls(1) utility works as expected. Our sample test program could look like:

# The t_example_2.sh test program
      
atf_test_case noflags
noflags_head() {
    atf_set "descr" "Checks that ls produces the correct output when not" \
                    "using any option"
}
noflags_body() {
    mkdir dir
    touch dir/a
    touch dir/b
    mkdir dir/c

    echo a >expout
    echo b >>expout
    echo c >>expout
    atf_check 'cd dir && ls' 0 expout null
}

atf_test_case Fflag
Fflag_head() {
    atf_set "descr" "Checks that ls produces the correct output when" \
                    "using the -F option"
}
Fflag_body() {
    mkdir dir
    touch dir/a
    touch dir/b
    mkdir dir/c

    echo a >expout
    echo b >>expout
    echo c/ >>expout
    atf_check 'cd dir && ls -F' 0 expout null
}

atf_init_test_cases() {
    atf_add_test_case noflags
    atf_add_test_case Fflag
}

In order to build the above test program, do:

$ atf-compile -o t_example_2 t_example_2.sh

Test suite definition

To add the above two test programs, t_example_1 and t_example_2 into a test suite, we create an Atffile control file in the same directory they live in with the following contents:

Content-Type: application/X-atf-atffile; version="1"

prop: test-suite = "examples"

tp: t_example_1
tp: t_example_2

Execution

To run the above test suite, we use the atf-run utility. It produces a machine-parseable output with the results of the execution:

$ atf-run
Content-Type: application/X-atf-tps; version="1"

tps-count: 2
tp-start: t_example_1, 2
tc-start: pow_func
tc-end: pow_func, passed
tc-start: snprintf_func
tc-end: snprintf_func, passed
tp-end: t_example_1
tp-start: t_example_2, 2
tc-start: noflags
tc-so: Checking command [cd dir && ls]
tc-end: noflags, passed
tc-start: Fflag
tc-so: Checking command [cd dir && ls -F]
tc-end: Fflag, passed
tp-end: t_example_2

However, we can pipe the above command through atf-report to get something more readable:

$ atf-run | atf-report
t_example_1 (1/2): 2 test cases
    pow_func: Passed.
    snprintf_func: Passed.

t_example_2 (2/2): 2 test cases
    noflags: Passed.
    Fflag: Passed.

Summary for 2 test programs:
    4 passed test cases.
    0 failed test cases.
    0 skipped test cases.

Similarly, we can also generate multiple different reports at once. For example, we could generate a CSV file while showing the above output on the console:

$ atf-run | atf-report -o csv:test.log -o ticker:-
t_example_1 (1/2): 2 test cases
    pow_func: Passed.
    snprintf_func: Passed.

t_example_2 (2/2): 2 test cases
    noflags: Passed.
    Fflag: Passed.

Summary for 2 test programs:
    4 passed test cases.
    0 failed test cases.
    0 skipped test cases.
$ cat test.log
t_example_1, pow_func, passed
t_example_1, snprintf_func, passed
t_example_2, noflags, passed
t_example_2, Fflag, passed