Skip to content

Commit 710bb58

Browse files
committed
Allow user-defined TEST_PROTECT & TEST_ABORT macros
However rare, this update covers real-world use cases where: - Unity is used to provide the assertion macros only, and an external test harness/runner is used for test orchestration/reporting. - Calling longjmp on a given platform is possible, but has a platform-specific (or implementation-specific) set of prerequisites, e.g. privileged access level. Enable project-specific customisation of TEST_PROTECT and TEST_ABORT macros. - Use the user-defined UNITY_TEST_ABORT if available; fall back to default behaviour otherwise. - Use the user-defined UNITY_TEST_PROTECT if available; fall back to default behaviour otherwise. - These may be defined independently.
1 parent cb03c3a commit 710bb58

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

docs/UnityConfigurationGuide.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,68 @@ _Example:_
399399
#define UNITY_EXCLUDE_SETJMP
400400
```
401401
402+
#### `UNITY_TEST_PROTECT`
403+
404+
#### `UNITY_TEST_ABORT`
405+
406+
Unity handles test failures via `setjmp`/`longjmp` pair by default. As mentioned above, you can disable this with `UNITY_EXCLUDE_SETJMP`. You can also customise what happens on every `TEST_PROTECT` and `TEST_ABORT` call. This can be accomplished by providing user-defined `UNITY_TEST_PROTECT` and `UNITY_TEST_ABORT` macros (and these may be defined independently).
407+
408+
`UNITY_TEST_PROTECT` is used as an `if` statement expression, and has to evaluate to `true` on the first call (when saving stack environment with `setjmp`), and to `false` when it returns as a result of a `TEST_ABORT` (when restoring the stack environment with `longjmp`).
409+
410+
Whenever an assert macro fails, `TEST_ABORT` is used to restore the stack environment previously set by `TEST_PROTECT`. This part may be overriden with `UNITY_TEST_ABORT`, e.g. if custom failure handling is needed.
411+
412+
_Example 1:_
413+
414+
Calling `longjmp` on your target is possible, but has a platform-specific (or implementation-specific) set of prerequisites, e.g. privileged access level. You can extend the default behaviour of `TEST_PROTECT` and `TEST_ABORT` as:
415+
416+
`unity_config.h`:
417+
418+
```C
419+
#include "my_custom_test_handlers.h"
420+
421+
#define UNITY_TEST_PROTECT() custom_test_protect()
422+
#define UNITY_TEST_ABORT() custom_test_abort()
423+
```
424+
425+
`my_custom_test_handlers.c`:
426+
427+
```C
428+
int custom_test_protect(void) {
429+
platform_specific_code();
430+
return setjmp(Unity.AbortFrame) == 0;
431+
}
432+
433+
UNITY_NORETURN void custom_test_abort(void) {
434+
more_platform_specific_code();
435+
longjmp(Unity.AbortFrame, 1);
436+
}
437+
```
438+
439+
_Example 2:_
440+
441+
Unity is used to provide the assertion macros only, and an external test harness/runner is used for test orchestration/reporting. In this case you can easily plug your code by overriding `TEST_ABORT` as:
442+
443+
`unity_config.h`:
444+
445+
```C
446+
#include "my_custom_test_handlers.h"
447+
448+
#define UNITY_TEST_PROTECT() 1
449+
#define UNITY_TEST_ABORT() custom_test_abort()
450+
```
451+
452+
`my_custom_test_handlers.c`:
453+
454+
```C
455+
void custom_test_abort(void) {
456+
if (Unity.CurrentTestFailed == 1) {
457+
custom_failed_test_handler();
458+
} else if (Unity.CurrentTestIgnored == 1) {
459+
custom_ignored_test_handler();
460+
}
461+
}
462+
```
463+
402464
#### `UNITY_OUTPUT_COLOR`
403465
404466
If you want to add color using ANSI escape codes you can use this define.

src/unity_internals.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,13 +759,25 @@ extern const char UnityStrErrShorthand[];
759759
* Test Running Macros
760760
*-------------------------------------------------------*/
761761

762+
#ifdef UNITY_TEST_PROTECT
763+
#define TEST_PROTECT() UNITY_TEST_PROTECT()
764+
#else
762765
#ifndef UNITY_EXCLUDE_SETJMP_H
763766
#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0)
764-
#define TEST_ABORT() longjmp(Unity.AbortFrame, 1)
765767
#else
766768
#define TEST_PROTECT() 1
769+
#endif
770+
#endif
771+
772+
#ifdef UNITY_TEST_ABORT
773+
#define TEST_ABORT() UNITY_TEST_ABORT()
774+
#else
775+
#ifndef UNITY_EXCLUDE_SETJMP_H
776+
#define TEST_ABORT() longjmp(Unity.AbortFrame, 1)
777+
#else
767778
#define TEST_ABORT() return
768779
#endif
780+
#endif
769781

770782
/* Automatically enable variadic macros support, if it not enabled before */
771783
#ifndef UNITY_SUPPORT_VARIADIC_MACROS

0 commit comments

Comments
 (0)