Added SetUp/TearDown functions for test suites.
This commit is contained in:
parent
0eb354cef4
commit
3efe0fed79
4 changed files with 157 additions and 50 deletions
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2011 Markus Kauppila <markus.kauppila@gmail.com>
|
Copyright (C) 2011 Markus Kauppila <markus.kauppila@gmail.com>
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
|
@ -36,7 +36,7 @@ int _testAssertsFailed;
|
||||||
int _testAssertsPassed;
|
int _testAssertsPassed;
|
||||||
|
|
||||||
void
|
void
|
||||||
_TestCaseInit()
|
_InitTestEnvironment() // InitTestEnvironment
|
||||||
{
|
{
|
||||||
_testReturnValue = 0;
|
_testReturnValue = 0;
|
||||||
_testAssertsFailed = 0;
|
_testAssertsFailed = 0;
|
||||||
|
@ -44,7 +44,7 @@ _TestCaseInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_TestCaseQuit()
|
_QuitTestEnvironment()
|
||||||
{
|
{
|
||||||
AssertSummary(_testAssertsFailed + _testAssertsPassed,
|
AssertSummary(_testAssertsFailed + _testAssertsPassed,
|
||||||
_testAssertsFailed, _testAssertsPassed, time(0));
|
_testAssertsFailed, _testAssertsPassed, time(0));
|
||||||
|
@ -76,7 +76,6 @@ AssertEquals(const int expected, const int actual, char *message, ...)
|
||||||
AssertWithValues("AssertEquals", 1, buf,
|
AssertWithValues("AssertEquals", 1, buf,
|
||||||
actual, expected, time(0));
|
actual, expected, time(0));
|
||||||
|
|
||||||
_testReturnValue = 0;
|
|
||||||
_testAssertsPassed++;
|
_testAssertsPassed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +97,6 @@ AssertTrue(int condition, char *message, ...)
|
||||||
} else {
|
} else {
|
||||||
Assert("AssertTrue", 1, buf, time(0));
|
Assert("AssertTrue", 1, buf, time(0));
|
||||||
|
|
||||||
_testReturnValue = 0;
|
|
||||||
_testAssertsPassed++;
|
_testAssertsPassed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +113,6 @@ AssertPass(char *message, ...)
|
||||||
|
|
||||||
Assert("AssertPass", 1, buf, time(0));
|
Assert("AssertPass", 1, buf, time(0));
|
||||||
|
|
||||||
_testReturnValue = 0;
|
|
||||||
_testAssertsPassed++;
|
_testAssertsPassed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,10 @@
|
||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "common/images.h"
|
||||||
|
|
||||||
|
|
||||||
extern int _testReturnValue;
|
extern int _testReturnValue;
|
||||||
extern int _testAssertsFailed;
|
extern int _testAssertsFailed;
|
||||||
extern int _testAssertsPassed;
|
extern int _testAssertsPassed;
|
||||||
|
@ -52,18 +56,18 @@ typedef struct TestCaseReference {
|
||||||
} TestCaseReference;
|
} TestCaseReference;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Initialized the test case. Must be called at
|
* Initialized the test environment such as asserts. Must be called at
|
||||||
* the beginning of every test case, before doing
|
* the beginning of every test case, before doing anything else.
|
||||||
* anything else.
|
|
||||||
*/
|
*/
|
||||||
void _TestCaseInit();
|
void _InitTestEnvironment();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Deinitializes and exits the test case
|
* Deinitializes the test environment and
|
||||||
|
* returns the result of the test (pass or failure)
|
||||||
*
|
*
|
||||||
* \return 0 if test succeeded, otherwise 1
|
* \return 0 if test succeeded, otherwise 1
|
||||||
*/
|
*/
|
||||||
int _TestCaseQuit();
|
int _QuitTestEnvironment();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Assert function. Tests if the expected value equals the actual value, then
|
* Assert function. Tests if the expected value equals the actual value, then
|
||||||
|
@ -74,6 +78,7 @@ int _TestCaseQuit();
|
||||||
* \param message Message that will be printed if assert fails
|
* \param message Message that will be printed if assert fails
|
||||||
*/
|
*/
|
||||||
void AssertEquals(const int expected, const int actual, char *message, ...);
|
void AssertEquals(const int expected, const int actual, char *message, ...);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Assert function. Tests if the given condition is true. True in
|
* Assert function. Tests if the given condition is true. True in
|
||||||
* this case means non-zero value. If the condition is true, the
|
* this case means non-zero value. If the condition is true, the
|
||||||
|
|
|
@ -39,9 +39,13 @@
|
||||||
//!< Function pointer to a test case function
|
//!< Function pointer to a test case function
|
||||||
typedef void (*TestCaseFp)(void *arg);
|
typedef void (*TestCaseFp)(void *arg);
|
||||||
//!< Function pointer to a test case init function
|
//!< Function pointer to a test case init function
|
||||||
typedef void (*TestCaseInitFp)(void);
|
typedef void (*InitTestInvironmentFp)(void);
|
||||||
//!< Function pointer to a test case quit function
|
//!< Function pointer to a test case quit function
|
||||||
typedef int (*TestCaseQuitFp)(void);
|
typedef int (*QuitTestInvironmentFp)(void);
|
||||||
|
//!< Function pointer to a test case set up function
|
||||||
|
typedef void (*TestCaseSetUpFp)(void *arg);
|
||||||
|
//!< Function pointer to a test case tear down function
|
||||||
|
typedef void (*TestCaseTearDownFp)(void *arg);
|
||||||
|
|
||||||
|
|
||||||
//!< Flag for executing tests in-process
|
//!< Flag for executing tests in-process
|
||||||
|
@ -105,20 +109,24 @@ typedef struct TestCaseItem {
|
||||||
long requirements;
|
long requirements;
|
||||||
long timeout;
|
long timeout;
|
||||||
|
|
||||||
TestCaseInitFp testCaseInit;
|
InitTestInvironmentFp initTestEnvironment;
|
||||||
|
TestCaseSetUpFp testSetUp;
|
||||||
TestCaseFp testCase;
|
TestCaseFp testCase;
|
||||||
TestCaseQuitFp testCaseQuit;
|
TestCaseTearDownFp testTearDown;
|
||||||
|
QuitTestInvironmentFp quitTestEnvironment;
|
||||||
|
|
||||||
struct TestCaseItem *next;
|
struct TestCaseItem *next;
|
||||||
} TestCase;
|
} TestCase;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! Some function prototypes. Add the rest of functions and move to runner.h */
|
/*! Some function prototypes. Add the rest of functions and move to runner.h */
|
||||||
TestCaseFp LoadTestCaseFunction(void *suite, char *testName);
|
TestCaseFp LoadTestCaseFunction(void *suite, char *testName);
|
||||||
TestCaseInitFp LoadTestCaseInitFunction(void *suite);
|
InitTestInvironmentFp LoadInitTestInvironmentFunction(void *suite);
|
||||||
TestCaseQuitFp LoadTestCaseQuitFunction(void *suite);
|
QuitTestInvironmentFp LoadQuitTestInvironmentFunction(void *suite);
|
||||||
TestCaseReference **QueryTestCaseReferences(void *library);
|
TestCaseReference **QueryTestCaseReferences(void *library);
|
||||||
|
TestCaseSetUpFp LoadTestSetUpFunction(void *suite);
|
||||||
|
TestCaseTearDownFp LoadTestTearDownFunction(void *suite);
|
||||||
|
|
||||||
|
|
||||||
/*! Pointers to selected logger implementation */
|
/*! Pointers to selected logger implementation */
|
||||||
RunStartedFp RunStarted = NULL;
|
RunStartedFp RunStarted = NULL;
|
||||||
|
@ -159,18 +167,26 @@ LoadTestCases(TestSuiteReference *suites)
|
||||||
void *suite = suiteReference->library;
|
void *suite = suiteReference->library;
|
||||||
|
|
||||||
// Load test case functions
|
// Load test case functions
|
||||||
TestCaseInitFp testCaseInit = LoadTestCaseInitFunction(suiteReference->library);
|
InitTestInvironmentFp initTestEnvironment = LoadInitTestInvironmentFunction(suiteReference->library);
|
||||||
TestCaseQuitFp testCaseQuit = LoadTestCaseQuitFunction(suiteReference->library);
|
QuitTestInvironmentFp quitTestEnvironment = LoadQuitTestInvironmentFunction(suiteReference->library);
|
||||||
TestCaseFp testCase = (TestCaseFp) LoadTestCaseFunction(suiteReference->library, testReference->name);
|
|
||||||
|
TestCaseSetUpFp testSetUp = LoadTestSetUpFunction(suiteReference->library);
|
||||||
|
TestCaseTearDownFp testTearDown = LoadTestTearDownFunction(suiteReference->library);
|
||||||
|
|
||||||
|
TestCaseFp testCase = LoadTestCaseFunction(suiteReference->library, testReference->name);
|
||||||
|
|
||||||
// Do the filtering
|
// Do the filtering
|
||||||
if(FilterTestCase(testReference)) {
|
if(FilterTestCase(testReference)) {
|
||||||
TestCase *item = SDL_malloc(sizeof(TestCase));
|
TestCase *item = SDL_malloc(sizeof(TestCase));
|
||||||
memset(item, 0, sizeof(TestCase));
|
memset(item, 0, sizeof(TestCase));
|
||||||
|
|
||||||
item->testCaseInit = testCaseInit;
|
item->initTestEnvironment = initTestEnvironment;
|
||||||
|
item->quitTestEnvironment = quitTestEnvironment;
|
||||||
|
|
||||||
|
item->testSetUp = testSetUp;
|
||||||
|
item->testTearDown = testTearDown;
|
||||||
|
|
||||||
item->testCase = testCase;
|
item->testCase = testCase;
|
||||||
item->testCaseQuit = testCaseQuit;
|
|
||||||
|
|
||||||
// copy suite name
|
// copy suite name
|
||||||
int length = SDL_strlen(suiteReference->name) + 1;
|
int length = SDL_strlen(suiteReference->name) + 1;
|
||||||
|
@ -287,7 +303,9 @@ ScanForTestSuites(char *directoryName, char *extension)
|
||||||
|
|
||||||
Entry *entry = NULL;
|
Entry *entry = NULL;
|
||||||
if(!directory) {
|
if(!directory) {
|
||||||
perror("Couldn't open test suite directory!");
|
fprintf(stderr, "Failed to open test suite directory: %s\n", directoryName);
|
||||||
|
perror("Error message");
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(entry = readdir(directory)) {
|
while(entry = readdir(directory)) {
|
||||||
|
@ -458,42 +476,82 @@ LoadTestCaseFunction(void *suite, char *testName)
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Loads function that initialises the test case from the
|
* Loads function that sets up a fixture for a test case. Note: if there's
|
||||||
* given test suite.
|
* no SetUp function present in the suite the function will return NULL.
|
||||||
*
|
*
|
||||||
* \param suite Used test suite
|
* \param suite Used test suite
|
||||||
*
|
*
|
||||||
* \return Function pointer (TestCaseInit) which points to loaded init function. NULL if function fails.
|
* \return Function pointer to test case's set up function
|
||||||
*/
|
*/
|
||||||
TestCaseInitFp
|
TestCaseSetUpFp
|
||||||
LoadTestCaseInitFunction(void *suite) {
|
LoadTestSetUpFunction(void *suite) {
|
||||||
TestCaseInitFp testCaseInit = (TestCaseInitFp) SDL_LoadFunction(suite, "_TestCaseInit");
|
TestCaseSetUpFp testSetUp = (TestCaseSetUpFp) SDL_LoadFunction(suite, "SetUp");
|
||||||
if(testCaseInit == NULL) {
|
if(testSetUp == NULL) {
|
||||||
fprintf(stderr, "Loading TestCaseInit function failed, testCaseInit == NULL\n");
|
fprintf(stderr, "Loading SetUp function failed, testSetUp == NULL\n");
|
||||||
fprintf(stderr, "%s\n", SDL_GetError());
|
fprintf(stderr, "%s\n", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
return testCaseInit;
|
return testSetUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Loads function that deinitialises the executed test case from the
|
* Loads function that tears down a fixture for a test case. Note: if there's
|
||||||
* given test suite.
|
* no TearDown function present in the suite the function will return NULL.
|
||||||
*
|
*
|
||||||
* \param suite Used test suite
|
* \param suite Used test suite
|
||||||
*
|
*
|
||||||
* \return Function pointer (TestCaseInit) which points to loaded init function. NULL if function fails.
|
* \return Function pointer to test case's tear down function
|
||||||
*/
|
*/
|
||||||
TestCaseQuitFp
|
TestCaseTearDownFp
|
||||||
LoadTestCaseQuitFunction(void *suite) {
|
LoadTestTearDownFunction(void *suite) {
|
||||||
TestCaseQuitFp testCaseQuit = (TestCaseQuitFp) SDL_LoadFunction(suite, "_TestCaseQuit");
|
TestCaseTearDownFp testTearDown = (TestCaseTearDownFp) SDL_LoadFunction(suite, "TearDown");
|
||||||
if(testCaseQuit == NULL) {
|
if(testTearDown == NULL) {
|
||||||
fprintf(stderr, "Loading TestCaseQuit function failed, testCaseQuit == NULL\n");
|
fprintf(stderr, "Loading TearDown function failed, testTearDown == NULL\n");
|
||||||
fprintf(stderr, "%s\n", SDL_GetError());
|
fprintf(stderr, "%s\n", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
return testCaseQuit;
|
return testTearDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Loads function that initialises the test environment for
|
||||||
|
* a test case in the given suite.
|
||||||
|
*
|
||||||
|
* \param suite Used test suite
|
||||||
|
*
|
||||||
|
* \return Function pointer (InitTestInvironmentFp) which points to loaded init function. NULL if function fails.
|
||||||
|
*/
|
||||||
|
InitTestInvironmentFp
|
||||||
|
LoadInitTestInvironmentFunction(void *suite) {
|
||||||
|
InitTestInvironmentFp testEnvInit = (InitTestInvironmentFp) SDL_LoadFunction(suite, "_InitTestEnvironment");
|
||||||
|
if(testEnvInit == NULL) {
|
||||||
|
fprintf(stderr, "Loading _InitTestInvironment function failed, testEnvInit == NULL\n");
|
||||||
|
fprintf(stderr, "%s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return testEnvInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Loads function that deinitialises the test environment (and returns
|
||||||
|
* the test case's result) created for the test case in the given suite.
|
||||||
|
*
|
||||||
|
* \param suite Used test suite
|
||||||
|
*
|
||||||
|
* \return Function pointer (QuitTestInvironmentFp) which points to loaded init function. NULL if function fails.
|
||||||
|
*/
|
||||||
|
QuitTestInvironmentFp
|
||||||
|
LoadQuitTestInvironmentFunction(void *suite) {
|
||||||
|
QuitTestInvironmentFp testEnvQuit = (QuitTestInvironmentFp) SDL_LoadFunction(suite, "_QuitTestEnvironment");
|
||||||
|
if(testEnvQuit == NULL) {
|
||||||
|
fprintf(stderr, "Loading _QuitTestEnvironment function failed, testEnvQuit == NULL\n");
|
||||||
|
fprintf(stderr, "%s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return testEnvQuit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -536,19 +594,37 @@ int
|
||||||
ExecuteTest(TestCase *testItem) {
|
ExecuteTest(TestCase *testItem) {
|
||||||
int retVal = 1;
|
int retVal = 1;
|
||||||
if(execute_inproc) {
|
if(execute_inproc) {
|
||||||
testItem->testCaseInit();
|
testItem->initTestEnvironment();
|
||||||
|
|
||||||
|
if(testItem->testSetUp) {
|
||||||
|
testItem->testSetUp(0x0);
|
||||||
|
}
|
||||||
|
|
||||||
testItem->testCase(0x0);
|
testItem->testCase(0x0);
|
||||||
|
|
||||||
retVal = testItem->testCaseQuit();
|
if(testItem->testTearDown) {
|
||||||
|
testItem->testTearDown(0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
retVal = testItem->quitTestEnvironment();
|
||||||
} else {
|
} else {
|
||||||
int childpid = fork();
|
int childpid = fork();
|
||||||
if(childpid == 0) {
|
if(childpid == 0) {
|
||||||
testItem->testCaseInit();
|
testItem->initTestEnvironment();
|
||||||
|
|
||||||
|
if(testItem->testSetUp) {
|
||||||
|
testItem->testSetUp(0x0);
|
||||||
|
}
|
||||||
|
|
||||||
testItem->testCase(0x0);
|
testItem->testCase(0x0);
|
||||||
|
|
||||||
exit(testItem->testCaseQuit());
|
// note: if test case is is aborted by some signal
|
||||||
|
// then TearDown function won't be called
|
||||||
|
if(testItem->testTearDown) {
|
||||||
|
testItem->testTearDown(0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(testItem->quitTestEnvironment());
|
||||||
} else {
|
} else {
|
||||||
int stat_lock = -1;
|
int stat_lock = -1;
|
||||||
int child = wait(&stat_lock);
|
int child = wait(&stat_lock);
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
/*! \file
|
/*! \file
|
||||||
* Dummy test suite for test runner. This can be used as a base for
|
* Dummy test suite for test runner. This can be used as a base for
|
||||||
* writing new tests. Dummy suite also works as reference to using
|
* writing new tests. Dummy suite also works as reference to using
|
||||||
* various asserts and (possible) other utilities.
|
* various asserts and other (possible) utilities.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -30,8 +30,6 @@
|
||||||
|
|
||||||
#include "../SDL_test.h"
|
#include "../SDL_test.h"
|
||||||
|
|
||||||
// \todo add some helpful commenting for possible test writers?
|
|
||||||
|
|
||||||
/* Test case references */
|
/* Test case references */
|
||||||
static const TestCaseReference test1 =
|
static const TestCaseReference test1 =
|
||||||
(TestCaseReference){ "dummycase1", "description", TEST_ENABLED, 0, 0};
|
(TestCaseReference){ "dummycase1", "description", TEST_ENABLED, 0, 0};
|
||||||
|
@ -52,6 +50,37 @@ TestCaseReference **QueryTestSuite() {
|
||||||
return (TestCaseReference **)testSuite;
|
return (TestCaseReference **)testSuite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create test fixture */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* SetUp function can be used to create a test fixture for test cases.
|
||||||
|
* The function will be called right before executing the test case.
|
||||||
|
*
|
||||||
|
* Note: this function is optional.
|
||||||
|
*
|
||||||
|
* \param arg parameters given to test. Usually NULL
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SetUp(void *arg)
|
||||||
|
{
|
||||||
|
// create test fixture,
|
||||||
|
// for example, set up static variables used by test cases here
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* TearDown function can be used to destroy a test fixture for test cases.
|
||||||
|
* The function will be called right after executing the test case.
|
||||||
|
*
|
||||||
|
* Note: this function is optional.
|
||||||
|
*
|
||||||
|
* \param arg parameters given to test. Usually NULL
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TearDown(void *arg)
|
||||||
|
{
|
||||||
|
// destroy test fixture
|
||||||
|
}
|
||||||
|
|
||||||
/* Test case functions */
|
/* Test case functions */
|
||||||
void
|
void
|
||||||
dummycase1(void *arg)
|
dummycase1(void *arg)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue