test.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. /**
  2. \ingroup lub
  3. \defgroup lub_test test
  4. @{
  5. \brief This utiltiy provides a simple unittest facility.
  6. \par Unit Testing Philosophy
  7. The tests are used during development as a means of
  8. exercising and debugging the new code, and once developed serve as
  9. a means of regression-testing to ensure that changes or additions
  10. have not introduced defects. Unit testing in this manner offers
  11. many benefits:
  12. \li Well designed unit tests allow for more complete exercise & test
  13. coverage of new code.
  14. \li They do not require product hardware or even a product simulator;
  15. they are compact, standalone executables.
  16. \li It is easy to instrument the unit tests with commercial tools such
  17. as Purify/PureCoverage.
  18. \li Use as regression tests increases code maintainability.
  19. \li They can be run during builds as ``sanity-checks'' that components
  20. are functional.
  21. \par What is the unit test interface?
  22. The Unit Test Interface provide a set of basic capabilities that
  23. all unit tests need, and which are trivially easy to incorporate
  24. into a test. They make it easy to do things such as:
  25. \li Log output to the screen and/or to a logfile
  26. \li Test values of various types and record the results
  27. \li Provide well-formatted, concise output with controllable verbosity
  28. \li Track test status.
  29. \li Have a consistent set of command-line options for controlling
  30. the unit test behavior. (see unitTestCL() below)
  31. \par Verbosity
  32. Depending on the length of a test, why it is being run, and the
  33. stage of development, it is desirable to have different levels of
  34. detail output. The Unit Test Utilities provide three levels of
  35. detail:
  36. \li \b Terse output is the minimal set. Only test failures, serious
  37. errors, and final results are logged.
  38. \li \b Normal output is the default. All test results, sequence headers,
  39. etc. are logged.
  40. \li \b Verbose output includes all output messages. This level is not
  41. used by the Utilities themselves but is useful for providing
  42. additional, detailed messages within unit tests.
  43. Most Utility functions handle verbosity issues automatically; for
  44. example, Tests automatically log failures as ``terse'' and pass
  45. results as ``normal''. The only time a user needs to specify
  46. verbosity is with Log messages.
  47. All output has an associated Verbosity level, and will only be
  48. output if the current Verbosity setting is equal to or greater
  49. than that level.
  50. \par Sequences
  51. Simple numbering of tests is adequate only for very small unit
  52. tests. More commonly, there are groups of related tests covering
  53. a particular function or set of functionality. This gives rise to
  54. the concept of Sequences. A Sequence assigns a name and number to
  55. a group of tests; within the sequence, tests are numbered
  56. automatically. While their use is not strictly required, the use
  57. of Sequences is encouraged as a means of organizing test output
  58. for easy understanding.
  59. Sequences are begun with a function call specifying their sequence
  60. number and a printf-style format specification of their name.
  61. This outputs a sequence header (at 'normal' verbosity) and
  62. resets the test counter. Another call ends the sequence.
  63. \par Tests
  64. Tests are the heart of the unit test. Every test has
  65. a pass/fail result, which is returned as well as affecting the
  66. overall pass/fail status of the unit test. Every test also
  67. accepts a ``name'' argument (in printf style), and generates
  68. appropriate log output. Although null strings are accepted as
  69. names, naming each test is encouraged as it makes the output much
  70. more readable.
  71. At the Terse verbosity level, only failing tests generate log output.
  72. Test functions are provided for testing:
  73. \li \b Expressions: the expression's true/false value is evaluated. This
  74. is the most basic test, similar to an assert(). Virtually
  75. anything can be tested using this, but the log output is minimal;
  76. only a Pass/Fail result and the test name are logged.
  77. \li \b Integer \b Comparison: the test function is passed an expected and
  78. actual value. The test passes if the values are the same. The
  79. log includes Pass/Fail, expected & actual values, and the test
  80. name; because the values appear in the log, failures may be more
  81. easily investigated.
  82. \li \b Float \b Comparison: the test function is passed minimum, maximum,
  83. and actual values. The test passes if the actual value is less
  84. than or equal to maximum, and greater than or equal to minimum.
  85. Like the integer comparison, the min, max, and actual values are
  86. all logged in addition to the Pass/Fail result and test name.
  87. The overall unit test pass/fail result can be requested at any
  88. time via a function call.
  89. \par Logging
  90. Three different logging functions are provided. All are similar
  91. but each is appropriate for different purposes. Each function
  92. takes as its first argument a verbosity level, specifying the
  93. minimum verbosity at which the message should be logged. Each
  94. also takes a printf-style specification of format and arguments,
  95. which is used to generate the output. In this way anything can be
  96. output: strings, variables, formatted floats, whatever the unit
  97. test needs to record.
  98. Note that it is not required to use any logging function; the
  99. Utilities will generate a reasonable log based on the sequence and
  100. test calls. However, additional logging may add significant value
  101. and human readability to the test results.
  102. \author Graeme McKerrell
  103. \author Brett B. Bonner
  104. \date Created On Thu Feb 28 11:25:44 2002
  105. \date Last Revised 03-Oct-2002 (BBB)
  106. \version UNTESTED
  107. */
  108. /**************************************************************
  109. HISTORY
  110. 7-Dec-2004 Graeme McKerrell
  111. Updated to use the "lub_test_" prefix rather than "unittest_"
  112. 18-Mar-2002 Graeme McKerrell
  113. added unittest_stop_here() prototype
  114. 16-Mar-2002 Graeme McKerrell
  115. LINTed...
  116. 4-Mar-2002 Graeme McKerrell
  117. Ported across for use in Garibaldi
  118. 28-Feb-2002 Graeme McKerrell
  119. Created based on implentation header file.
  120. ---------------------------------------------------------------
  121. Copyright (c) 3Com Corporation. All Rights Reserved
  122. ***************************************************************/
  123. #ifndef _lub_test_h
  124. #define _lub_test_h
  125. #include <stdarg.h>
  126. #include "lub/types.h"
  127. #ifdef __cplusplus
  128. extern "C"
  129. {
  130. #endif /* __cplusplus */
  131. /** Status codes */
  132. typedef enum {
  133. LUB_TEST_PASS, /*!< Indicates a test has passed */
  134. LUB_TEST_FAIL /*!< Indicates a test has failed */
  135. } lub_test_status_t;
  136. /** Message priority/verbosity levels */
  137. typedef enum {
  138. LUB_TEST_TERSE=0,/*!< Only output test failures, errors and final result */
  139. LUB_TEST_NORMAL, /*!< Output all test results, sequence headers, errors and results */
  140. LUB_TEST_VERBOSE /*!< Output everything */
  141. } lub_test_verbosity_t;
  142. /*
  143. ************************************************************
  144. UNIT-TEST LEVEL FUNCTIONS
  145. ************************************************************
  146. */
  147. /**
  148. This function is responsible for parsing all the command line
  149. options, setting run time variables, and opening a log file if
  150. necessary.
  151. \par Supported Command Line Switches:
  152. <em> Set the Verbosity level </em>
  153. \li -terse
  154. \li -normal (default)
  155. \li -verbose
  156. <em> Set behaviour upon failure </em>
  157. \li -stoponfail
  158. \li -continueonfail (default)
  159. <em> Logging:</em>
  160. Enable and disable logging to stdout
  161. \li -stdout (default)
  162. \li -nostdout
  163. Log to file named FILENAME (if no filename is specified
  164. "test.log" is used), or disable logging to a file
  165. \li -logfile [FILENAME] (default)
  166. \li -nologfile
  167. <em> Prints usage message and exit </em>
  168. -usage
  169. -help
  170. \pre
  171. Must be the first unitTest function called.
  172. \returns
  173. none
  174. \post
  175. If there are conflicting command line options it will exit(1)
  176. If the log file cannot be opened it will exit(1)
  177. */
  178. void lub_test_parse_command_line(/** The number of command line arguments */
  179. int argc,
  180. /** An array of command line arguments */
  181. const char * const *argv);
  182. /**
  183. This starts and specifies the name for the unit-test.
  184. \pre
  185. - lub_test_CL() must have been called.
  186. \returns
  187. none
  188. \post
  189. - The begining of the test is reported in the logfile and/or stdout
  190. - The overall pass/fail status is reset.
  191. */
  192. void lub_test_begin(/** a printf style format string to specify the name
  193. of the test */
  194. const char *fmt,
  195. /** any further arguments required by the format
  196. string */
  197. ...);
  198. /**
  199. This is the most generic of the logging functions. No addition
  200. formating is performed.
  201. \pre
  202. - lub_test_begin() must have been called.
  203. - lub_test_end() must not have been called.
  204. \returns
  205. none
  206. \post
  207. - If the specified verbosity is higher than that specified
  208. on the command line then the message will not be logged
  209. to the logfile and/or stdout.
  210. - If lub_test_begin() has not been called then behaviour is undefined
  211. */
  212. void
  213. lub_test_log(/** the verbosity level for this message */
  214. lub_test_verbosity_t level,
  215. /** a printf style format string to specify the
  216. message to log */
  217. const char *fmt,
  218. /** any further arguments required by the format string */
  219. ...);
  220. /**
  221. This function provide the current overall status for the
  222. unit-test. If any tests have failed then the unit-test is deemed
  223. to have failed.
  224. \pre
  225. - lub_test_begin() must have been called.
  226. - lub_test_end() must not have been called.
  227. \returns
  228. The current overall status. (TESTPASS/TESTFAIL)
  229. \post
  230. - If lub_test_begin() has not been called then behaviour is undefined
  231. - If lub_test_end() has been called the behaviour is undefined
  232. */
  233. lub_test_status_t
  234. lub_test_get_status(void);
  235. /**
  236. The test utilities maintain internal counts for all the tests
  237. that have been performed since the unittest_begin() call.
  238. This function lets a client get the number of failures so far.
  239. \pre
  240. - lub_test_begin() must have been called.
  241. - lub_test_end() must not have been called.
  242. \returns
  243. The current number of failed tests.
  244. \post
  245. - If lub_test_begin() has not been called then behaviour is undefined
  246. - If lub_test_end() has been called the behaviour is undefined
  247. */
  248. int
  249. lub_test_failure_count(void);
  250. /**
  251. This function ends the unit-test and closes the log file.
  252. \pre
  253. - lub_test_begin() must have been called.
  254. - lub_test_end() must not have been called.
  255. \returns
  256. none
  257. \post
  258. - The overall pass/fail status is reported to the log file and/or
  259. stdout.
  260. - The log file is closed.
  261. - If lub_test_begin() has not been called then behaviour is undefined
  262. - If lub_test_end() has been called the behaviour is undefined
  263. */
  264. void
  265. lub_test_end(void);
  266. /**
  267. This function is provided as a DEBUG aid. A breakpoint set on this
  268. function will be reached everytime a test fails, with the failure case in context.
  269. \pre
  270. none
  271. \returns
  272. none
  273. \post
  274. none
  275. */
  276. void
  277. lub_test_stop_here(void);
  278. /*
  279. ************************************************************
  280. SEQUENCE LEVEL FUNCTIONS
  281. ************************************************************
  282. */
  283. /**
  284. This function starts a new test sequence.
  285. \pre
  286. - lub_test_begin() must have been called.
  287. - lub_test_end() must not have been called.
  288. \returns
  289. none
  290. \post
  291. - The test count is reset to zero.
  292. - The current sequence number and description is updated.
  293. - The begining of the sequence is reported in the logfile and/or stdout.
  294. - If lub_test_begin() has not been called the behaviour is undefined
  295. - If lub_test_end() has been called the behaviour is undefined
  296. */
  297. void
  298. lub_test_seq_begin(/** a user specified sequence number */
  299. int seq,
  300. /** a printf style format string to specify the sequence
  301. name*/
  302. const char *fmt,
  303. /** any further arguments required by the format string */
  304. ...);
  305. /**
  306. This is a good general purpose logging function. It parameters
  307. are the same as unittest_log, but this will log the provided
  308. information with the current sequence number, properly indented
  309. to provide nicely formatted output within a test.
  310. \pre
  311. - lub_test_seq_begin() must have been called.
  312. \returns
  313. none
  314. \post
  315. - The formatted message is reported in the logfile and/or stdout.
  316. - If lub_test_seq_begin() has not been called the behaviour is undefined
  317. */
  318. void
  319. lub_test_seq_log(/** The verbosity level of the message */
  320. lub_test_verbosity_t level,
  321. /** a printf style format string to specify the message */
  322. const char *fmt,
  323. /** any further arguments required by the format string */
  324. ...);
  325. /**
  326. This function marks the end of the current sequence.
  327. \pre
  328. - lub_test_seq_begin() must have been called.
  329. \returns
  330. none
  331. \post
  332. - An end of sequence message is reported to the log file and/or
  333. stdout.
  334. - The current sequence number and description remains unchanged
  335. until the next call to unittest_seq_begin()
  336. - If lub_test_seq_begin() has not been called then behaviour is undefined
  337. */
  338. void
  339. lub_test_seq_end(void);
  340. /*
  341. ************************************************************
  342. TEST LEVEL FUNCTIONS
  343. ************************************************************
  344. */
  345. /*lint -esym(534,lub_test_check,lub_test_check_int,lub_test_check_float)
  346. Make LINT not moan about people ignoring the return values for
  347. certain files, the value return is for utility purpose rather than
  348. a value that ought to be used.
  349. ************************************************************/
  350. /**
  351. The most basic test function, this simply evaluates an expression
  352. for BOOL_TRUE/BOOL_FALSE and passes/fails as a result. Like all test functions
  353. it accepts a printf-style format and parameters to describe the test.
  354. \pre
  355. - lub_test_begin() must have been called
  356. \returns
  357. A status code (LUB_TEST_PASS/LUB_TEST_FAIL)
  358. \post
  359. - The formatted scenario and result is reported in the logfile
  360. and/or stdout.
  361. - The test count is incremented by one.
  362. - If the tests fails then the overall unit-test status is changed
  363. to LUB_TEST_FAIL
  364. - If lub_test_begin() has not been called the behaviour is undefined
  365. */
  366. lub_test_status_t
  367. lub_test_check(/** a boolean expression to evaluate */
  368. bool_t expr,
  369. /** a printf style format string to specify the test
  370. scenario */
  371. const char *fmt,
  372. /** any further arguments required by the format string */
  373. ...);
  374. /**
  375. This function is almost identical to test() except it accepts an
  376. exepcted and actual value to compares them. Equal values cause the
  377. test to pass, unequal cause the test to fail. Both values are
  378. recorded in the log output making it easier to understand failures.
  379. \pre
  380. - lub_test_begin() must have been called
  381. \returns
  382. A status code (LUB_TEST_PASS/LUB_TEST_FAIL)
  383. \post
  384. - The formatted scenario and result is reported in the logfile
  385. and/or stdout.
  386. - The test count is incremented by one.
  387. - If the tests fails then the overall unit-test status is changed
  388. to LUB_TEST_FAIL
  389. - If lub_test_begin() has not been called the behaviour is undefined
  390. */
  391. lub_test_status_t
  392. lub_test_check_int(/** the expected integer value */
  393. int expect,
  394. /** the actual integer value*/
  395. int actual,
  396. /** a printf style format string to specify the test scenario */
  397. const char *fmt,
  398. /** any further arguments required by the format string */
  399. ... );
  400. /**
  401. This function is designed to ensure that a floating point value
  402. is within acceptible limits. It takes a minimum, maximum and
  403. actual value. The test passes if the actual value is greater or
  404. equal than the minimum, and less than or equal to the maximum.
  405. All three values are recorded in the log output.
  406. \pre
  407. - lub_test_begin() must have been called
  408. \returns
  409. A status code (LUB_TEST_PASS/LUB_TEST_FAIL)
  410. \post
  411. - The formatted scenario and result is reported in the logfile
  412. and/or stdout.
  413. - The test count is incremented by one.
  414. - If the tests fails then the overall unit-test status is changed
  415. to LUB_TEST_FAIL
  416. - If lub_test_begin() has not been called the behaviour is undefined
  417. */
  418. lub_test_status_t
  419. lag_test_test_float(/** the minimum acceptible value */
  420. double min,
  421. /** the maximum acceptible value */
  422. double max,
  423. /** the actual value */
  424. double actual,
  425. /** a printf style format string to specify the test scenario */
  426. const char *fmt,
  427. /** any further arguments required by the format string */
  428. ...);
  429. #ifdef __cplusplus
  430. }
  431. #endif /* __cplusplus */
  432. #endif /* _lub_test_h */
  433. /** @} test */