move dbUnitTest discussion to dbUnitTest.h

This commit is contained in:
Michael Davidsaver
2026-01-08 14:58:10 -08:00
committed by Andrew Johnson
parent d724461f1c
commit 839e7f4959
2 changed files with 58 additions and 73 deletions

View File

@@ -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 <dbUnitTest.h>
* #include <testMain.h>
*
@@ -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(...);

View File

@@ -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("<dbdname>.dbd", 0, 0);
<dbdname>_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 <math.h>
#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 <math.h>
* #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