| ATF-C++-API(3) | Library Functions Manual | ATF-C++-API(3) |
ATF_ADD_TEST_CASE(tcs, name);
ATF_CHECK_ERRNO(exp_errno, bool_expression);
ATF_FAIL(reason);
ATF_INIT_TEST_CASES(tcs);
ATF_PASS();
ATF_REQUIRE(expression);
ATF_REQUIRE_EQ(expression_1, expression_2);
ATF_REQUIRE_ERRNO(exp_errno, bool_expression);
ATF_REQUIRE_IN(element, collection);
ATF_REQUIRE_MATCH(regexp, string_expression);
ATF_REQUIRE_NOT_IN(element, collection);
ATF_REQUIRE_THROW(expected_exception, statement);
ATF_REQUIRE_THROW_RE(expected_exception, regexp, statement);
ATF_SKIP(reason);
ATF_TEST_CASE(name);
ATF_TEST_CASE_BODY(name);
ATF_TEST_CASE_CLEANUP(name);
ATF_TEST_CASE_HEAD(name);
ATF_TEST_CASE_WITH_CLEANUP(name);
ATF_TEST_CASE_WITHOUT_HEAD(name);
C++-based test programs always follow this template:
extern "C" {
... C-specific includes go here ...
}
... C++-specific includes go here ...
#include <atf-c++.hpp>
ATF_TEST_CASE(tc1);
ATF_TEST_CASE_HEAD(tc1)
{
... first test case's header ...
}
ATF_TEST_CASE_BODY(tc1)
{
... first test case's body ...
}
ATF_TEST_CASE_WITH_CLEANUP(tc2);
ATF_TEST_CASE_HEAD(tc2)
{
... second test case's header ...
}
ATF_TEST_CASE_BODY(tc2)
{
... second test case's body ...
}
ATF_TEST_CASE_CLEANUP(tc2)
{
... second test case's cleanup ...
}
ATF_TEST_CASE(tc3);
ATF_TEST_CASE_BODY(tc3)
{
... third test case's body ...
}
... additional test cases ...
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, tc1);
ATF_ADD_TEST_CASE(tcs, tc2);
ATF_ADD_TEST_CASE(tcs, tc3);
... add additional test cases ...
}
Later on, one must define the three parts of the body by means of three functions. Their headers are given by the ATF_TEST_CASE_HEAD(), ATF_TEST_CASE_BODY() and ATF_TEST_CASE_CLEANUP() macros, all of which take the test case's name. Following each of these, a block of code is expected, surrounded by the opening and closing brackets.
After the macro, you are supposed to provide the body of a function, which should only use the ATF_ADD_TEST_CASE() macro to register the test cases the test program will execute. The first parameter of this macro matches the name you provided in the former call.
ATF_PASS() does not take any parameters. ATF_FAIL() and ATF_SKIP() take a single string that describes why the test case failed or was skipped, respectively. It is very important to provide a clear error message in both cases so that the user can quickly know why the test did not pass.
Each test case has an internal state called ‘expect' that describes what the test case expectations are at any point in time. The value of this property can change during execution by any of:
This mode is useful to reproduce actual known bugs in tests. Whenever the developer fixes the bug later on, the test case will start reporting a failure, signaling the developer that the test case must be adjusted to the new conditions. In this situation, it is useful, for example, to set reason as the bug number for tracking purposes.
ATF_REQUIRE() takes an expression and raises a failure if it evaluates to false.
ATF_REQUIRE_EQ() takes two expressions and raises a failure if the two do not evaluate to the same exact value.
ATF_REQUIRE_IN() takes an element and a collection and validates that the element is present in the collection.
ATF_REQUIRE_MATCH() takes a regular expression and a string and raises a failure if the regular expression does not match the string.
ATF_REQUIRE_NOT_IN() takes an element and a collection and validates that the element is not present in the collection.
ATF_REQUIRE_THROW() takes the name of an exception and a statement and raises a failure if the statement does not throw the specified exception. ATF_REQUIRE_THROW_EQ() takes the name of an exception, a regular expresion and a statement and raises a failure if the statement does not throw the specified exception and if the message of the exception does not match the regular expression.
ATF_CHECK_ERRNO() and ATF_REQUIRE_ERRNO() take, first, the error code that the check is expecting to find in the errno variable and, second, a boolean expression that, if evaluates to true, means that a call failed and errno has to be checked against the first value.
#include <atf-c++.hpp>
ATF_TEST_CASE(addition);
ATF_TEST_CASE_HEAD(addition)
{
set("descr", "Sample tests for the addition operator");
}
ATF_TEST_CASE_BODY(addition)
{
ATF_REQUIRE_EQ(0 + 0, 0);
ATF_REQUIRE_EQ(0 + 1, 1);
ATF_REQUIRE_EQ(1 + 0, 1);
ATF_REQUIRE_EQ(1 + 1, 2);
ATF_REQUIRE_EQ(100 + 200, 300);
}
ATF_TEST_CASE(open_failure);
ATF_TEST_CASE_HEAD(open_failure)
{
set("descr", "Sample tests for the open function");
}
ATF_TEST_CASE_BODY(open_failure)
{
ATF_REQUIRE_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
}
ATF_TEST_CASE(known_bug);
ATF_TEST_CASE_HEAD(known_bug)
{
set("descr", "Reproduces a known bug");
}
ATF_TEST_CASE_BODY(known_bug)
{
expect_fail("See bug number foo/bar");
ATF_REQUIRE_EQ(3, 1 + 1);
expect_pass();
ATF_REQUIRE_EQ(3, 1 + 2);
}
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, addition);
ATF_ADD_TEST_CASE(tcs, open_failure);
ATF_ADD_TEST_CASE(tcs, known_bug);
}
| December 10, 2010 | NetBSD 6.1 |