diff --git a/modules/database/src/ioc/db/dbUnitTest.h b/modules/database/src/ioc/db/dbUnitTest.h index c1e4fcd89..ba19684e0 100644 --- a/modules/database/src/ioc/db/dbUnitTest.h +++ b/modules/database/src/ioc/db/dbUnitTest.h @@ -203,13 +203,13 @@ DBCORE_API void testGlobalUnlock(void); * * @section dbunittest Unit testing of record processing * - * @see @ref epicsUnitTest.h + * @see @ref unittest * * @section dbtestskel Test skeleton * * For the impatient, the skeleton of a test: * - * @code + * @code{.c} * #include * #include * @@ -233,7 +233,7 @@ DBCORE_API void testGlobalUnlock(void); * } * @endcode * - * @code + * @code{make} * TOP = .. * include $(TOP)/configure/CONFIG * @@ -251,6 +251,27 @@ DBCORE_API void testGlobalUnlock(void); * include $(TOP)/configure/RULES * @endcode * + * Discussion: + * + * Some tests require the context of an IOC to be run. This conflicts with the + * idea of running multiple tests within a test harness, as iocInit() is only + * allowed to be called once, and some parts of the full IOC (e.g. the rsrv CA + * server) can not be shut down cleanly. The function iocBuildIsolated() allows + * to start an IOC without its Channel Access parts, so that it can be shutdown + * quite cleanly using iocShutdown(). This feature is only intended to be used + * from test programs, do not use it on production IOCs. After building the + * IOC using iocBuildIsolated() or iocBuild(), it has to be started by calling + * iocRun(). + * + * The part from iocBuildIsolated() to iocShutdown() can be repeated to + * execute multiple tests within one executable or harness. + * + * To make it easier to create a single test program that can be built for + * both the embedded and workstation operating system harnesses, the header file + * testMain.h provides a convenience macro MAIN() that adjusts the name of the + * test program according to the platform it is running on: main() on + * workstations and a regular function name on embedded systems. + * * @section dbtestactions Actions * * Several helper functions are provided to interact with a running database. @@ -273,7 +294,7 @@ DBCORE_API void testGlobalUnlock(void); * * @see enum dbfType in dbFldTypes.h * - * @code + * @code{.c} * testdbPutFieldOk("pvname", DBF_ULONG, (unsigned int)5); * testdbPutFieldOk("pvname", DBF_FLOAT, (double)4.1); * testdbPutFieldOk("pvname", DBF_STRING, "hello world"); @@ -321,7 +342,7 @@ DBCORE_API void testGlobalUnlock(void); * When possible, the best way to avoid this race would be to join the worker * before destroying the event. * - * @code + * @code{.c} * epicsEventId evt; * void thread1() { * epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT; @@ -343,7 +364,7 @@ DBCORE_API void testGlobalUnlock(void); * that epicsEventMustSignal() has returned before destroying the event. * testGlobalLock() and testGlobalUnlock() provide access to such a mutex. * - * @code + * @code{.c} * epicsEventId evt; * void thread1() { * evt = epicsEventMustCreate(...); diff --git a/modules/libcom/src/misc/epicsUnitTest.h b/modules/libcom/src/misc/epicsUnitTest.h index 1f51eeeb2..4251788bb 100644 --- a/modules/libcom/src/misc/epicsUnitTest.h +++ b/modules/libcom/src/misc/epicsUnitTest.h @@ -11,6 +11,8 @@ * \brief Unit test routines * \author Andrew Johnson * + * @section unittest Unit test routines + * * The unit test routines make it easy for a test program to generate output * that is compatible with the Test Anything Protocol and can thus be used with * Perl's automated Test::Harness as well as generating human-readable output. @@ -72,78 +74,40 @@ * mechanism to generate its result outputs (from an epicsAtExit() callback * routine). * - * ### IOC Testing + * @see @ref dbunittest * - * Some tests require the context of an IOC to be run. This conflicts with the - * idea of running multiple tests within a test harness, as iocInit() is only - * allowed to be called once, and some parts of the full IOC (e.g. the rsrv CA - * server) can not be shut down cleanly. The function iocBuildIsolated() allows - * to start an IOC without its Channel Access parts, so that it can be shutdown - * quite cleanly using iocShutdown(). This feature is only intended to be used - * from test programs, do not use it on production IOCs. After building the - * IOC using iocBuildIsolated() or iocBuild(), it has to be started by calling - * iocRun(). The suggested call sequence in a test program that needs to run the - * IOC without Channel Access is: -\code -#include "iocInit.h" - -MAIN(iocTest) -{ - testPlan(0); - testdbPrepare(); - testdbReadDatabase(".dbd", 0, 0); - _registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("some.db", 0, 0); - ... test code before iocInit(). eg. dbGetString() ... - testIocInitOk(); - ... test code with IOC running. eg. dbGet() - testIocShutdownOk(); - testdbCleanup(); - return testDone(); -} -\endcode - - * The part from iocBuildIsolated() to iocShutdown() can be repeated to - * execute multiple tests within one executable or harness. - * - * To make it easier to create a single test program that can be built for - * both the embedded and workstation operating system harnesses, the header file - * testMain.h provides a convenience macro MAIN() that adjusts the name of the - * test program according to the platform it is running on: main() on - * workstations and a regular function name on embedded systems. - * - * ### Example + * @section unittestexample Example * * The following is a simple example of a test program using the epicsUnitTest * routines: -\code -#include -#include "epicsUnitTest.h" -#include "testMain.h" - -MAIN(mathTest) -{ - testPlan(3); - testOk(sin(0.0) == 0.0, "Sine starts"); - testOk(cos(0.0) == 1.0, "Cosine continues"); - if (!testOk1(M_PI == 4.0*atan(1.0))) - testDiag("4 * atan(1) = %g", 4.0 * atan(1.0)); - return testDone(); -} -\endcode - + * \code{.c} + * #include + * #include "epicsUnitTest.h" + * #include "testMain.h" + * + * MAIN(mathTest) + * { + * testPlan(3); + * testOk(sin(0.0) == 0.0, "Sine starts"); + * testOk(cos(0.0) == 1.0, "Cosine continues"); + * if (!testOk1(M_PI == 4.0*atan(1.0))) + * testDiag("4 * atan(1) = %g", 4.0 * atan(1.0)); + * return testDone(); + * } + * \endcode + * * The output from running the above program looks like this: -\code -1..3 -ok 1 - Sine starts -ok 2 - Cosine continues -ok 3 - M_PI == 4.0*atan(1.0) - - Results - ======= - Tests: 3 - Passed: 3 = 100% -\endcode + * \code + * 1..3 + * ok 1 - Sine starts + * ok 2 - Cosine continues + * ok 3 - M_PI == 4.0*atan(1.0) + * + * Results + * ======= + * Tests: 3 + * Passed: 3 = 100% + * \endcode */ #ifndef INC_epicsUnitTest_H