Handlers: Add test failure handler to allow selftest.

Niklas Hauser 2015-12-10 11:44:23 +00:00 committed by Martin Kojtal
parent 105d07b552
commit 633588dc35
5 changed files with 96 additions and 14 deletions

View File

@ -24,6 +24,7 @@ using namespace utest::v1;
const handlers_t utest::v1::verbose_continue_handlers = {
verbose_test_setup_handler,
verbose_test_teardown_handler,
ignore_handler,
verbose_case_setup_handler,
verbose_case_teardown_handler,
verbose_case_failure_handler
@ -31,6 +32,7 @@ const handlers_t utest::v1::verbose_continue_handlers = {
const handlers_t utest::v1::greentea_abort_handlers = {
greentea_test_setup_handler,
greentea_test_teardown_handler,
ignore_handler,
verbose_case_setup_handler,
verbose_case_teardown_handler,
greentea_case_failure_handler
@ -38,6 +40,23 @@ const handlers_t utest::v1::greentea_abort_handlers = {
const handlers_t utest::v1::greentea_continue_handlers = {
greentea_test_setup_handler,
greentea_test_teardown_handler,
ignore_handler,
verbose_case_setup_handler,
verbose_case_teardown_handler,
verbose_case_failure_handler
};
static void selftest_failure_handler(const failure_t reason) {
if (reason == FAILURE_ASSERTION) {
printf(">>> failure with reason '%s (in selftest)'\n{{failure}}\n{{end}}\n", stringify(reason));
while(1) ;
}
}
const handlers_t utest::v1::selftest_handlers = {
greentea_test_setup_handler,
greentea_test_teardown_handler,
selftest_failure_handler,
verbose_case_setup_handler,
verbose_case_teardown_handler,
verbose_case_failure_handler

View File

@ -22,7 +22,6 @@
using namespace utest::v1;
namespace
{
const Case *test_cases = NULL;
@ -67,11 +66,12 @@ bool Harness::run(const Specification& specification, std::size_t start_case)
if (is_busy())
return false;
test_cases = specification.cases;
test_cases = specification.cases;
test_length = specification.length;
defaults = specification.defaults;
handlers.test_setup = defaults.get_handler(specification.setup_handler);
defaults = specification.defaults;
handlers.test_setup = defaults.get_handler(specification.setup_handler);
handlers.test_teardown = defaults.get_handler(specification.teardown_handler);
handlers.test_failure = defaults.get_handler(specification.failure_handler);
test_index_of_case = 0;
test_passed = 0;
@ -83,6 +83,7 @@ bool Harness::run(const Specification& specification, std::size_t start_case)
case_current = &test_cases[start_case];
if (handlers.test_setup && (handlers.test_setup(test_length) != STATUS_CONTINUE)) {
if (handlers.test_failure) handlers.test_failure(FAILURE_SETUP);
if (handlers.test_teardown) handlers.test_teardown(0, 0, FAILURE_SETUP);
test_cases = NULL;
return true;
@ -98,6 +99,7 @@ void Harness::raise_failure(failure_t reason)
{
mbed::util::CriticalSectionLock lock;
if (handlers.test_failure) handlers.test_failure(reason);
if (handlers.case_failure) fail_status = handlers.case_failure(case_current, reason);
if (!(fail_status & STATUS_IGNORE)) case_failed++;

View File

@ -37,10 +37,11 @@ namespace v1 {
{
operator test_setup_handler_t() const { return test_setup_handler_t(1); }
operator test_teardown_handler_t() const { return test_teardown_handler_t(1); }
operator test_failure_handler_t() const { return test_failure_handler_t(1); }
operator case_setup_handler_t() const { return case_setup_handler_t(1); }
operator case_teardown_handler_t() const { return case_teardown_handler_t(1); }
operator case_failure_handler_t() const { return case_failure_handler_t(1); }
operator case_failure_handler_t() const { return case_failure_handler_t(1); }
} default_handler;
/** Ignore handler hint.
@ -56,10 +57,11 @@ namespace v1 {
operator test_setup_handler_t() const { return test_setup_handler_t(NULL); }
operator test_teardown_handler_t() const { return test_teardown_handler_t(NULL); }
operator test_failure_handler_t() const { return test_failure_handler_t(NULL); }
operator case_setup_handler_t() const { return case_setup_handler_t(NULL); }
operator case_teardown_handler_t() const { return case_teardown_handler_t(NULL); }
operator case_failure_handler_t() const { return case_failure_handler_t(NULL); }
operator case_failure_handler_t() const { return case_failure_handler_t(NULL); }
} ignore_handler;
/** A table of handlers.
@ -88,6 +90,7 @@ namespace v1 {
{
test_setup_handler_t test_setup;
test_teardown_handler_t test_teardown;
test_failure_handler_t test_failure;
case_setup_handler_t case_setup;
case_teardown_handler_t case_teardown;
@ -101,6 +104,10 @@ namespace v1 {
if (handler == default_handler) return test_teardown;
return handler;
}
inline test_failure_handler_t get_handler(test_failure_handler_t handler) const {
if (handler == default_handler) return test_failure;
return handler;
}
inline case_setup_handler_t get_handler(case_setup_handler_t handler) const {
if (handler == default_handler) return case_setup;
@ -146,6 +153,9 @@ namespace v1 {
/// The greentea default handlers that always continue on failure
extern const handlers_t greentea_continue_handlers;
/// The selftest default handlers that always abort on _any_ assertion failure, otherwise continue
extern const handlers_t selftest_handlers;
/// The greentea aborting handlers are the default
const handlers_t default_handlers = greentea_abort_handlers;

View File

@ -48,16 +48,36 @@ namespace v1 {
public:
template< size_t N >
Specification(const Case (&cases)[N],
const test_teardown_handler_t teardown_handler = default_handler,
const handlers_t defaults = default_handlers) :
setup_handler(default_handler), teardown_handler(teardown_handler),
setup_handler(default_handler), teardown_handler(default_handler), failure_handler(default_handler),
cases(cases), length(N),
defaults(defaults)
{}
template< size_t N >
Specification(const Case (&cases)[N], const handlers_t defaults) :
setup_handler(default_handler), teardown_handler(default_handler),
Specification(const Case (&cases)[N],
const test_failure_handler_t failure_handler,
const handlers_t defaults = default_handlers) :
setup_handler(default_handler), teardown_handler(default_handler), failure_handler(failure_handler),
cases(cases), length(N),
defaults(defaults)
{}
template< size_t N >
Specification(const Case (&cases)[N],
const test_teardown_handler_t teardown_handler,
const handlers_t defaults = default_handlers) :
setup_handler(default_handler), teardown_handler(teardown_handler), failure_handler(default_handler),
cases(cases), length(N),
defaults(defaults)
{}
template< size_t N >
Specification(const Case (&cases)[N],
const test_teardown_handler_t teardown_handler,
const test_failure_handler_t failure_handler,
const handlers_t defaults = default_handlers) :
setup_handler(default_handler), teardown_handler(teardown_handler), failure_handler(failure_handler),
cases(cases), length(N),
defaults(defaults)
{}
@ -65,9 +85,8 @@ namespace v1 {
template< size_t N >
Specification(const test_setup_handler_t setup_handler,
const Case (&cases)[N],
const test_teardown_handler_t teardown_handler = default_handler,
const handlers_t defaults = default_handlers) :
setup_handler(setup_handler), teardown_handler(teardown_handler),
setup_handler(setup_handler), teardown_handler(default_handler), failure_handler(default_handler),
cases(cases), length(N),
defaults(defaults)
{}
@ -75,8 +94,30 @@ namespace v1 {
template< size_t N >
Specification(const test_setup_handler_t setup_handler,
const Case (&cases)[N],
const handlers_t defaults) :
setup_handler(setup_handler), teardown_handler(default_handler),
const test_failure_handler_t failure_handler,
const handlers_t defaults = default_handlers) :
setup_handler(setup_handler), teardown_handler(default_handler), failure_handler(failure_handler),
cases(cases), length(N),
defaults(defaults)
{}
template< size_t N >
Specification(const test_setup_handler_t setup_handler,
const Case (&cases)[N],
const test_teardown_handler_t teardown_handler,
const handlers_t defaults = default_handlers) :
setup_handler(setup_handler), teardown_handler(teardown_handler), failure_handler(default_handler),
cases(cases), length(N),
defaults(defaults)
{}
template< size_t N >
Specification(const test_setup_handler_t setup_handler,
const Case (&cases)[N],
const test_teardown_handler_t teardown_handler,
const test_failure_handler_t failure_handler,
const handlers_t defaults = default_handlers) :
setup_handler(setup_handler), teardown_handler(teardown_handler), failure_handler(failure_handler),
cases(cases), length(N),
defaults(defaults)
{}
@ -84,6 +125,7 @@ namespace v1 {
private:
const test_setup_handler_t setup_handler;
const test_teardown_handler_t teardown_handler;
const test_failure_handler_t failure_handler;
const Case *const cases;
const size_t length;
const handlers_t defaults;

View File

@ -163,6 +163,15 @@ namespace v1 {
*/
typedef void (*test_teardown_handler_t)(const size_t passed, const size_t failed, const failure_t failure);
/** Test failure handler.
*
* This handler is called anytime a failure occurs during the execution of a test speficication.
* The handler only allows logging of failures and cannot influence test execution.
*
* @param failure the reason why this handler was called
*/
typedef void (*test_failure_handler_t)(const failure_t reason);
/** Test case setup handler.
*
* This handler is called before execution of each test case and