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_NAME(name);
ATF_TEST_CASE_USE(name);
ATF_TEST_CASE_WITH_CLEANUP(name);
ATF_TEST_CASE_WITHOUT_HEAD(name);
void
atf::utils::cat_file(const std::string& path, const std::string& prefix);
bool
atf::utils::compare_file(const std::string& path, const std::string& contents);
void
atf::utils::copy_file(const std::string& source, const std::string& destination);
void
atf::utils::create_file(const std::string& path, const std::string& contents);
void
atf::utils::file_exists(const std::string& path);
pid_t
atf::utils::fork(void);
bool
atf::utils::grep_collection(const std::string& regexp, const Collection& collection);
bool
atf::utils::grep_file(const std::string& regexp, const std::string& path);
bool
atf::utils::grep_string(const std::string& regexp, const std::string& path);
void
atf::utils::redirect(const int fd, const std::string& path);
void
atf::utils::wait(const pid_t pid, const int expected_exit_status, const std::string& expected_stdout, const std::string& expected_stderr);
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.
Additionally, the ATF_TEST_CASE_NAME() macro can be used to obtain the name of the class corresponding to a particular test case, as the name is internally manged by the library to prevent clashes with other user identifiers. Similarly, the ATF_TEST_CASE_USE() macro can be executed on a particular test case to mark it as "used" and thus prevent compiler warnings regarding unused symbols. Note that you should never have to use these macros during regular operation.
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_RE() 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.
void atf::utils::cat_file(const std::string& path, const std::string& prefix);
bool atf::utils::compare_file(const std::string& path, const std::string& contents);
void atf::utils::copy_file(const std::string& source, const std::string& destination);
void atf::utils::create_file(const std::string& path, const std::string& contents);
void atf::utils::file_exists(const std::string& path);
pid_t atf::utils::fork(void);
bool atf::utils::grep_collection(const std::string& regexp, const Collection& collection);
bool atf::utils::grep_file(const std::string& regexp, const std::string& path);
bool atf::utils::grep_string(const std::string& regexp, const std::string& str);
void atf::utils::wait(const pid_t pid, const int expected_exit_status, const std::string& expected_stdout, const std::string& expected_stderr);
If any of the expected_stdout or expected_stderr strings are prefixed with ‘save:’, then they specify the name of the file into which to store the stdout or stderr of the subprocess, and no comparison is performed.
#include <atf-c++.hpp> ATF_TEST_CASE(addition); ATF_TEST_CASE_HEAD(addition) { set_md_var("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_md_var("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_md_var("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); }
November 15, 2013 | NetBSD 7.2 |