368 lines
12 KiB
C
368 lines
12 KiB
C
/****************************************************************************
|
|
* <Novell-copyright>
|
|
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of version 2 of the GNU General Public License
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, contact Novell, Inc.
|
|
*
|
|
* To contact Novell about this file by physical or electronic mail, you
|
|
* may find current contact information at www.novell.com.
|
|
* </Novell-copyright>
|
|
****************************************************************************/
|
|
|
|
/** \defgroup BongoCheck The Check Framework in the Bongo Project
|
|
* \brief Provides unit testing for C code in the Bongo Project.
|
|
*
|
|
* The Bongo project uses the Check framework for testing C
|
|
* code. For more information on Check consult its project website at
|
|
* http://check.sourceforge.net/ . Many parts of the Check system are
|
|
* wrapped up in macros found in the bongocheck.h header file. Specific
|
|
* parts of the Check framework are to be used directly, and are listed
|
|
* in the section \ref TheCheckFrameWork.
|
|
*
|
|
* Be sure to read the documentation for the \ref TheCheckFrameWork and
|
|
* \ref CheckStyleAndMake modules before attempting to write unit tests.
|
|
*
|
|
* Here is an example of a basic test souce code file to get you started.
|
|
* \code
|
|
* #include <include/bongocheck.h>
|
|
* #ifdef BONGO_HAVE_CHECK
|
|
* START_TEST(test1)
|
|
* {
|
|
* fail_unless(1==1);
|
|
* fail_if(1 == 2);
|
|
* if ( 1 == 2 ) {
|
|
* fail("1 shouldn't equal 2");
|
|
* }
|
|
* }
|
|
* END_TEST
|
|
* // pound-include other tests of your own here.
|
|
* START_CHECK_SUITE_SETUP("My test suite description")
|
|
* CREATE_CHECK_CASE (tc_core , "Core" );
|
|
* CHECK_SUITE_ADD_CASE(top_suite, tc_core );
|
|
* CHECK_CASE_ADD_TEST (tc_core , test1 );
|
|
* // register included tests here.
|
|
* END_CHECK_SUITE_SETUP
|
|
* #else
|
|
* SKIP_CHECK_TESTS
|
|
* #endif
|
|
* \endcode
|
|
*
|
|
* @{
|
|
*/
|
|
|
|
/** \file bongocheck.h
|
|
* \brief Macros that help keep the use of the Check framework consistent.
|
|
*
|
|
* Even if you are adept at Check, please use these macros when
|
|
* writing programmer tests for your code. If you want to access
|
|
* a piece of Check's functionality that is not currently available
|
|
* through these macros or listed in \link TheCheckFrameWork The Check
|
|
* Framework\endlink, then please propose additional macros rather than
|
|
* using Check directly.
|
|
*
|
|
*/
|
|
#include <config.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
/* Just for documentation */
|
|
#ifdef RUNNING_DOXYGEN
|
|
/** Conditionally set by Autoconf in config.h.
|
|
* The \p config.h file contains pound-defines that control the behavior
|
|
* of the compilation process. Among them is the \c BONGO_HAVE_CHECK symbol,
|
|
* which will be defined if and only if Check is installed and located
|
|
* on the build system.
|
|
*
|
|
* When you use the Check framework then be sure to wrap it inside a
|
|
* \code
|
|
* #ifdef BONGO_HAVE_CHECK
|
|
* // use Check here
|
|
* #else
|
|
* SKIP_CHECK_TESTS
|
|
* #endif
|
|
* \endcode
|
|
* block.
|
|
*/
|
|
#define BONGO_HAVE_CHECK
|
|
|
|
/** Set this symbol before including \c bongocheck.h in order to force tests
|
|
* to return successfully. By default, the test program returns a failure
|
|
* code if any of the tests fail. Defining the FORCE_CHECK_SUCCESS
|
|
* symbol causes the test program to always return success. This prevents
|
|
* a "make check" from stopping on test failures.
|
|
*
|
|
* The logging feature is not affected by this option.
|
|
*
|
|
*/
|
|
#define FORCE_CHECK_SUCCESS
|
|
#endif
|
|
|
|
#ifdef _BONGO_BONGO_HAVE_CHECK
|
|
#include <check.h>
|
|
#endif
|
|
|
|
/** Creates a suite that can be used in a suite runner.
|
|
* \hideinitializer
|
|
* \param id regular C identifier.
|
|
* \param description a string in double quotes.
|
|
*
|
|
* The suite is given the id \a id, and \a description is used when
|
|
* printing a summary of how the test went. Programmers will normally
|
|
* use \c top_suite provided by the #START_CHECK_SUITE_SETUP
|
|
* macro.
|
|
*
|
|
*/
|
|
#define CREATE_CHECK_SUITE( id, description ) \
|
|
Suite *id = suite_create( description )
|
|
|
|
/** Creates a test-case that can be added to a suite
|
|
* (#CHECK_SUITE_ADD_CASE) and have tests added to it
|
|
* (#CHECK_CASE_ADD_TEST).
|
|
* \hideinitializer
|
|
* \param id regular C identifier.
|
|
* \param description a string in double quotes.
|
|
*
|
|
* It is given id \a id, and \a description is used in
|
|
* reports to describe it.
|
|
*
|
|
*/
|
|
#define CREATE_CHECK_CASE( id, description ) \
|
|
TCase *id = tcase_create( description )
|
|
|
|
/** Adds a test-case to a suite.
|
|
* \hideinitializer
|
|
* \param sid regular C identifier associated with a suite.
|
|
* \param cid regular C identifier associated with a test-case.
|
|
*
|
|
* The test-case with id \a cid is added to the suite with
|
|
* id \a sid. Normally, you will add all test-cases to the \c top_suite
|
|
* which is automatically created by #START_CHECK_SUITE_SETUP.
|
|
*
|
|
*/
|
|
#define CHECK_SUITE_ADD_CASE( sid, cid ) \
|
|
suite_add_tcase( sid , cid )
|
|
|
|
/** Adds a test to a test-case.
|
|
* \hideinitializer
|
|
* \param cid regular C identifier associated with a test-case.
|
|
* \param tid regular C identifier associated with a test.
|
|
*
|
|
* The test with id \a tid is added to the test-case with
|
|
* id \a cid. Tests must be previously defined in a \code
|
|
* START_TEST (<id>) {
|
|
* // ...
|
|
* } END_TEST \endcode block.
|
|
* Test-cases also must be previously defined (#CREATE_CHECK_CASE).
|
|
*
|
|
* Group similar tests into test-cases. Add all test-cases
|
|
* to the \c top_suite.
|
|
*
|
|
*/
|
|
#define CHECK_CASE_ADD_TEST( cid, tid ) \
|
|
tcase_add_test( cid, tid )
|
|
|
|
/** Creates the \c top_suite and opens the main function.
|
|
* \hideinitializer
|
|
* \param description a string in double quotes.
|
|
*
|
|
* \a description is used to describe the top suite in the results.
|
|
*
|
|
*/
|
|
#define START_CHECK_SUITE_SETUP(description) \
|
|
int main (void) { \
|
|
int nf; \
|
|
CREATE_CHECK_SUITE(top_suite, description);
|
|
|
|
/* Just for documentation */
|
|
#ifdef RUNNING_DOXYGEN
|
|
/** \brief (For framework maintenance) Creates the proper exit code.
|
|
* \param x number of tests failed.
|
|
*
|
|
* It may be desireable to force the "make check" target to return
|
|
* success so that more tests can be run. In this case define the
|
|
* #FORCE_CHECK_SUCCESS symbol.
|
|
*
|
|
* \attention This macro is only used in this header file. It is not
|
|
* part of the public interface.
|
|
* \hideinitializer
|
|
*
|
|
*/
|
|
#define BONGO_CHECK_EXIT(x)
|
|
#else
|
|
/* executed when not running doxygen */
|
|
#ifdef FORCE_CHECK_SUCCESS
|
|
#define BONGO_CHECK_EXIT(x) \
|
|
return EXIT_SUCCESS
|
|
#else
|
|
#define BONGO_CHECK_EXIT(x) \
|
|
return (x == 0) ? EXIT_SUCCESS : EXIT_FAILURE
|
|
#endif
|
|
/* */
|
|
#endif
|
|
|
|
/** Finishes up the main function.
|
|
* \hideinitializer
|
|
* Call this macro after registering all of your tests and test-cases. It
|
|
* runs the tests, outputs an xml log file, and cleans up before exiting.
|
|
*
|
|
*/
|
|
#define END_CHECK_SUITE_SETUP \
|
|
SRunner *sr = srunner_create(top_suite); \
|
|
srunner_set_xml ( sr, "checklog.xml" ); \
|
|
srunner_run_all ( sr, CK_ENV); \
|
|
nf = srunner_ntests_failed(sr); \
|
|
srunner_free(sr); \
|
|
BONGO_CHECK_EXIT(nf); \
|
|
}
|
|
|
|
/** Creates a simple program that informs the user no tests were run.
|
|
* Should be used in the else block of \c #ifdef \c BONGO_HAVE_CHECK.
|
|
* \hideinitializer
|
|
*
|
|
*/
|
|
#define SKIP_CHECK_TESTS \
|
|
int main (void) { \
|
|
printf("#################################\n"); \
|
|
printf("Check not installed, no tests run\n"); \
|
|
printf("#################################\n"); \
|
|
return EXIT_SUCCESS; \
|
|
}
|
|
|
|
/** \ingroup BongoCheck
|
|
* \defgroup TheCheckFrameWork The Check Framework
|
|
* \brief Listing of used bits of the Check framework (a consumed,
|
|
* external project).
|
|
*
|
|
* The Bongo project uses the Check framework for programmer tests on C
|
|
* code; however, developers for the project only access certain parts
|
|
* of the Check framework directly. Other parts of the infrastructure
|
|
* are supposed to be accessed through special macros implemented in
|
|
* the bongocheck.h file.
|
|
*
|
|
* This section does not aim to document Check in full. Instead, it is a
|
|
* quick reference for the pieces of Check that are meant to be accessed
|
|
* directly in the Bongo project. For complete documentation of Check
|
|
* itself refer to the site homepage at http://check.sourceforge.net/ .
|
|
*
|
|
* As you learn more about Check you may find pieces of it that you want
|
|
* to use that are not listed here, nor are they accessbile through our
|
|
* special macros. In that case, please discuss needed functionality
|
|
* with the Bongo QA team. They will either add it to this list of
|
|
* directly accessible bits, or write a macro for it.
|
|
*
|
|
* - Assertion-like functions:
|
|
* - \c fail_unless( expr, msg )
|
|
* - \c fail_if( expr, msg)
|
|
* - \c fail( msg )
|
|
* - Boilerplate Macros
|
|
* - \c START_TEST( testname ) and \c END_TEST
|
|
*
|
|
* Of course, you are also free to set any environment variables that
|
|
* Check honors, such as:
|
|
*
|
|
* - \c CK_VERBOSITY
|
|
* - \c CK_FORK --- good for avoiding fork in the debugger
|
|
*
|
|
* Be sure to look at the example code in \ref BongoCheck to get started.
|
|
*/
|
|
|
|
/** \ingroup BongoCheck
|
|
* \defgroup CheckStyleAndMake Style and Make
|
|
* \brief Style guidlines, and instructions for Makefile.am relative to
|
|
* using Check for unit testing.
|
|
*
|
|
* When writing unit tests please follow these style guidlines.
|
|
* Please direct any suggestions concerning these style guidlines to
|
|
* the Bongo QA team.
|
|
*
|
|
* \par Test all functionality
|
|
* Try to follow the standard "If it isn't tested then it doesn't
|
|
* exist." Writing good tests should take at least as long as writing
|
|
* the code itself.
|
|
*
|
|
* \par Place tests in their own directory
|
|
* If you are testing code in the \p foo directory, then place the tests
|
|
* in the \c foo/tests directory.
|
|
*
|
|
* \par Follow the template for managing the suite
|
|
* Have a file in your \c tests directory named \c checktest.c . In that file use the following template:
|
|
* \code
|
|
* #include <include/bongocheck.h>
|
|
* #ifdef BONGO_HAVE_CHECK
|
|
* START_TEST(test1)
|
|
* {
|
|
* // TODO
|
|
* // fail_unless(1==1);
|
|
* // fail_if(1 == 2);
|
|
* }
|
|
* END_TEST
|
|
* // TODO Write your tests above, and/or
|
|
* // pound-include other tests of your own here.
|
|
* START_CHECK_SUITE_SETUP("TODO Describe the unit you are testing")
|
|
* CREATE_CHECK_CASE (tc_core , "Core" );
|
|
* CHECK_SUITE_ADD_CASE(top_suite, tc_core );
|
|
* CHECK_CASE_ADD_TEST (tc_core , test1 );
|
|
* // TODO register additional tests here
|
|
* END_CHECK_SUITE_SETUP
|
|
* #else
|
|
* SKIP_CHECK_TESTS
|
|
* #endif
|
|
* \endcode
|
|
* Use as many test cases as you want. Be sure to register each test with
|
|
* exactly one test case, then register all test cases with the top_suite.
|
|
*
|
|
* \par Name your test files appropriately
|
|
* If you are testing code in files \p big.c, \p bigger.c, and \p
|
|
* biggest.c, then please put your corresponding test cases in files \p
|
|
* big_test.c, \p bigger_test.c, and \p biggest_test.c, respectively.
|
|
*
|
|
* Remember to pound-include your test source code files in \p
|
|
* checktest.c, and register the tests appropriately.
|
|
*
|
|
* \par Use the template Makefile.am
|
|
* In your \c tests directory, create the file \c Makefile.am with the following contents:
|
|
* \code
|
|
* TESTS = checktest
|
|
* check_PROGRAMS = $(TESTS)
|
|
* checktest_SOURCES = checktest.c
|
|
* checktest_LDADD = @CHECK_LIBS@
|
|
* checktest_CFLAGS = @CHECK_CFLAGS@
|
|
* \endcode
|
|
*
|
|
* \par Modify the parent's Makefile.am
|
|
* Make sure that the parent directory (\c foo in the example above)
|
|
* has a line in its Makefile.am similar to the following:
|
|
* \code
|
|
* SUBDIRS=tests
|
|
* \endcode
|
|
* If not, add it at the top.
|
|
*
|
|
* \par Add your tests directory to the top configure.in file
|
|
* If the path to the code you are testing is \c bongo/src/apps/foo,
|
|
* then your test code will be in directory \c bongo/src/apps/foo/tests.
|
|
* You need to make sure its Makefile is in the list of makefiles
|
|
* generated in \c configure.in (generally the one located in the \c
|
|
* bongo directory). In this example, you would go to the end of \c
|
|
* configure.in and look for the line
|
|
* \code
|
|
* src/apps/foo/tests/Makefile
|
|
* \endcode
|
|
* inside the \c AC_OUTPUT command. If the line is missing, then add it.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|