UnityConfigurationGuide.md 20.3 KB
Newer Older
1
# Unity Configuration Guide
T
toby 已提交
2 3

## C Standards, Compilers and Microcontrollers
4

T
toby 已提交
5
The embedded software world contains its challenges. Compilers support different
6 7 8
revisions of the C Standard. They ignore requirements in places, sometimes to
make the language more usable in some special regard. Sometimes it's to simplify
their support. Sometimes it's due to specific quirks of the microcontroller they
T
toby 已提交
9 10
are targeting. Simulators add another dimension to this menagerie.

11 12 13 14
Unity is designed to run on almost anything that is targeted by a C compiler. It
would be awesome if this could be done with zero configuration. While there are
some targets that come close to this dream, it is sadly not universal. It is
likely that you are going to need at least a couple of the configuration options
T
toby 已提交
15 16
described in this document.

17 18 19 20 21
All of Unity's configuration options are `#defines`. Most of these are simple
definitions. A couple are macros with arguments. They live inside the
unity_internals.h header file. We don't necessarily recommend opening that file
unless you really need to. That file is proof that a cross-platform library is
challenging to build. From a more positive perspective, it is also proof that a
D
Deryew 已提交
22
great deal of complexity can be centralized primarily to one place to
T
toby 已提交
23 24
provide a more consistent and simple experience elsewhere.

25 26 27 28 29

### Using These Options

It doesn't matter if you're using a target-specific compiler and a simulator or
a native compiler. In either case, you've got a couple choices for configuring
T
toby 已提交
30 31
these options:

32 33 34 35 36 37 38 39
1. Because these options are specified via C defines, you can pass most of these
options to your compiler through command line compiler flags. Even if you're
using an embedded target that forces you to use their overbearing IDE for all
configuration, there will be a place somewhere in your project to configure
defines for your compiler.
2. You can create a custom `unity_config.h` configuration file (present in your
toolchain's search paths). In this file, you will list definitions and macros
specific to your target. All you must do is define `UNITY_INCLUDE_CONFIG_H` and
T
toby 已提交
40 41
Unity will rely on `unity_config.h` for any further definitions it may need.

42

T
toby 已提交
43 44 45
## The Options

### Integer Types
46 47 48 49 50 51 52 53 54

If you've been a C developer for long, you probably already know that C's
concept of an integer varies from target to target. The C Standard has rules
about the `int` matching the register size of the target microprocessor. It has
rules about the `int` and how its size relates to other integer types. An `int`
on one target might be 16 bits while on another target it might be 64. There are
more specific types in compilers compliant with C99 or later, but that's
certainly not every compiler you are likely to encounter. Therefore, Unity has a
number of features for helping to adjust itself to match your required integer
T
toby 已提交
55 56
sizes. It starts off by trying to do it automatically.

57

T
toby 已提交
58
##### `UNITY_EXCLUDE_STDINT_H`
59 60

The first thing that Unity does to guess your types is check `stdint.h`.
D
Deryew 已提交
61
This file includes defines like `UINT_MAX` that Unity can use to
62 63 64 65
learn a lot about your system. It's possible you don't want it to do this
(um. why not?) or (more likely) it's possible that your system doesn't
support `stdint.h`. If that's the case, you're going to want to define this.
That way, Unity will know to skip the inclusion of this file and you won't
T
toby 已提交
66 67 68
be left with a compiler error.

_Example:_
69 70 71
```C
#define UNITY_EXCLUDE_STDINT_H
```
T
toby 已提交
72

73

T
toby 已提交
74
##### `UNITY_EXCLUDE_LIMITS_H`
75 76 77

The second attempt to guess your types is to check `limits.h`. Some compilers
that don't support `stdint.h` could include `limits.h` instead. If you don't
T
toby 已提交
78 79 80
want Unity to check this file either, define this to make it skip the inclusion.

_Example:_
81 82 83
```C
#define UNITY_EXCLUDE_LIMITS_H
```
84

M
Mark VanderVoord 已提交
85
If you've disabled both of the automatic options above, you're going to have to
86 87
do the configuration yourself. Don't worry. Even this isn't too bad... there are
just a handful of defines that you are going to specify if you don't like the
T
toby 已提交
88 89
defaults.

90

T
toby 已提交
91
##### `UNITY_INT_WIDTH`
92 93

Define this to be the number of bits an `int` takes up on your system. The
T
toby 已提交
94 95 96
default, if not autodetected, is 32 bits.

_Example:_
97 98 99
```C
#define UNITY_INT_WIDTH 16
```
T
toby 已提交
100

101

T
toby 已提交
102
##### `UNITY_LONG_WIDTH`
103 104 105 106 107

Define this to be the number of bits a `long` takes up on your system. The
default, if not autodetected, is 32 bits. This is used to figure out what kind
of 64-bit support your system can handle. Does it need to specify a `long` or a
`long long` to get a 64-bit value. On 16-bit systems, this option is going to be
T
toby 已提交
108 109 110
ignored.

_Example:_
111 112 113
```C
#define UNITY_LONG_WIDTH 16
```
T
toby 已提交
114

115

T
toby 已提交
116
##### `UNITY_POINTER_WIDTH`
117 118 119

Define this to be the number of bits a pointer takes up on your system. The
default, if not autodetected, is 32-bits. If you're getting ugly compiler
T
toby 已提交
120 121
warnings about casting from pointers, this is the one to look at.

122
_Hint:_ In order to support exotic processors (for example TI C55x with a pointer
123 124
width of 23-bit), choose the next power of two (in this case 32-bit).

125
_Supported values:_ 16, 32 and 64
126

T
toby 已提交
127
_Example:_
128
```C
129 130 131 132
// Choose on of these #defines to set your pointer width (if not autodetected)
//#define UNITY_POINTER_WIDTH 16
//#define UNITY_POINTER_WIDTH 32
#define UNITY_POINTER_WIDTH 64 // Set UNITY_POINTER_WIDTH to 64-bit
133
```
T
toby 已提交
134

135

M
Mark VanderVoord 已提交
136
##### `UNITY_SUPPORT_64`
137 138 139 140 141

Unity will automatically include 64-bit support if it auto-detects it, or if
your `int`, `long`, or pointer widths are greater than 32-bits. Define this to
enable 64-bit support if none of the other options already did it for you. There
can be a significant size and speed impact to enabling 64-bit support on small
T
toby 已提交
142 143 144
targets, so don't define it if you don't need it.

_Example:_
145 146 147
```C
#define UNITY_SUPPORT_64
```
T
toby 已提交
148

149 150 151 152 153 154 155 156

### Floating Point Types

In the embedded world, it's not uncommon for targets to have no support for
floating point operations at all or to have support that is limited to only
single precision. We are able to guess integer sizes on the fly because integers
are always available in at least one size. Floating point, on the other hand, is
sometimes not available at all. Trying to include `float.h` on these platforms
T
toby 已提交
157 158
would result in an error. This leaves manual configuration as the only option.

159

T
toby 已提交
160
##### `UNITY_INCLUDE_FLOAT`
161

T
toby 已提交
162
##### `UNITY_EXCLUDE_FLOAT`
163

T
toby 已提交
164
##### `UNITY_INCLUDE_DOUBLE`
165

T
toby 已提交
166
##### `UNITY_EXCLUDE_DOUBLE`
167 168 169 170 171

By default, Unity guesses that you will want single precision floating point
support, but not double precision. It's easy to change either of these using the
include and exclude options here. You may include neither, either, or both, as
suits your needs. For features that are enabled, the following floating point
T
toby 已提交
172 173 174
options also become available.

_Example:_
175 176 177 178 179
```C
//what manner of strange processor is this?
#define UNITY_EXCLUDE_FLOAT
#define UNITY_INCLUDE_DOUBLE
```
T
toby 已提交
180

181

M
Mark VanderVoord 已提交
182
##### `UNITY_EXCLUDE_FLOAT_PRINT`
183 184

Unity aims for as small of a footprint as possible and avoids most standard
M
Mark VanderVoord 已提交
185
library calls (some embedded platforms don’t have a standard library!). Because
186
of this, its routines for printing integer values are minimalist and hand-coded.
M
Mark VanderVoord 已提交
187 188 189 190 191 192
Therefore, the display of floating point values during a failure are optional.
By default, Unity will print the actual results of floating point assertion
failure (e.g. ”Expected 4.56 Was 4.68”). To not include this extra support, you
can use this define to instead respond to a failed assertion with a message like
”Values Not Within Delta”. If you would like verbose failure messages for floating
point assertions, use these options to give more explicit failure messages.
T
toby 已提交
193 194

_Example:_
195 196 197
```C
#define UNITY_EXCLUDE_FLOAT_PRINT
```
T
toby 已提交
198

199

T
toby 已提交
200
##### `UNITY_FLOAT_TYPE`
201 202 203

If enabled, Unity assumes you want your `FLOAT` asserts to compare standard C
floats. If your compiler supports a specialty floating point type, you can
T
toby 已提交
204 205 206
always override this behavior by using this definition.

_Example:_
207 208 209
```C
#define UNITY_FLOAT_TYPE float16_t
```
T
toby 已提交
210

211

T
toby 已提交
212
##### `UNITY_DOUBLE_TYPE`
213 214 215 216 217

If enabled, Unity assumes you want your `DOUBLE` asserts to compare standard C
doubles. If you would like to change this, you can specify something else by
using this option. For example, defining `UNITY_DOUBLE_TYPE` to `long double`
could enable gargantuan floating point types on your 64-bit processor instead of
T
toby 已提交
218 219 220
the standard `double`.

_Example:_
221 222 223
```C
#define UNITY_DOUBLE_TYPE long double
```
T
toby 已提交
224

225

T
toby 已提交
226
##### `UNITY_FLOAT_PRECISION`
227

T
toby 已提交
228
##### `UNITY_DOUBLE_PRECISION`
229 230 231 232 233 234 235 236 237 238

If you look up `UNITY_ASSERT_EQUAL_FLOAT` and `UNITY_ASSERT_EQUAL_DOUBLE` as
documented in the big daddy Unity Assertion Guide, you will learn that they are
not really asserting that two values are equal but rather that two values are
"close enough" to equal. "Close enough" is controlled by these precision
configuration options. If you are working with 32-bit floats and/or 64-bit
doubles (the normal on most processors), you should have no need to change these
options. They are both set to give you approximately 1 significant bit in either
direction. The float precision is 0.00001 while the double is 10-12.
For further details on how this works, see the appendix of the Unity Assertion
T
toby 已提交
239 240 241
Guide.

_Example:_
242 243 244 245
```C
#define UNITY_FLOAT_PRECISION 0.001f
```

T
toby 已提交
246

247 248 249 250 251 252 253 254 255 256
### Miscellaneous

##### `UNITY_EXCLUDE_STDDEF_H`

Unity uses the `NULL` macro, which defines the value of a null pointer constant,
defined in `stddef.h` by default. If you want to provide
your own macro for this, you should exclude the `stddef.h` header file by adding this
define to your configuration.

_Example:_
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
```C
#define UNITY_EXCLUDE_STDDEF_H
```


#### `UNITY_INCLUDE_PRINT_FORMATTED`

Unity provides a simple (and very basic) printf-like string output implementation,
which is able to print a string modified by the following format string modifiers:

- __%d__ - signed value (decimal)
- __%i__ - same as __%i__
- __%u__ - unsigned value (decimal)
- __%f__ - float/Double (if float support is activated)
- __%g__ - same as __%f__
- __%b__ - binary prefixed with "0b"
- __%x__ - hexadecimal (upper case) prefixed with "0x"
- __%X__ - same as __%x__
- __%p__ - pointer (same as __%x__ or __%X__)
- __%c__ - a single character
- __%s__ - a string (e.g. "string")
- __%%__ - The "%" symbol (escaped)

_Example:_
```C
#define UNITY_INCLUDE_PRINT_FORMATTED

int a = 0xfab1;
UnityPrintFormatted("Decimal   %d\n", -7);
UnityPrintFormatted("Unsigned  %u\n", 987);
UnityPrintFormatted("Float     %f\n", 3.1415926535897932384);
UnityPrintFormatted("Binary    %b\n", 0xA);
UnityPrintFormatted("Hex       %X\n", 0xFAB);
UnityPrintFormatted("Pointer   %p\n", &a);
UnityPrintFormatted("Character %c\n", 'F');
UnityPrintFormatted("String    %s\n", "My string");
UnityPrintFormatted("Percent   %%\n");
UnityPrintFormatted("Color Red \033[41mFAIL\033[00m\n");
UnityPrintFormatted("\n");
UnityPrintFormatted("Multiple (%d) (%i) (%u) (%x)\n", -100, 0, 200, 0x12345);
```
298

299

T
toby 已提交
300
### Toolset Customization
301 302 303 304 305

In addition to the options listed above, there are a number of other options
which will come in handy to customize Unity's behavior for your specific
toolchain. It is possible that you may not need to touch any of these... but
certain platforms, particularly those running in simulators, may need to jump
D
Deryew 已提交
306
through extra hoops to run properly. These macros will help in those
T
toby 已提交
307 308
situations.

309

T
toby 已提交
310
##### `UNITY_OUTPUT_CHAR(a)`
311

T
toby 已提交
312
##### `UNITY_OUTPUT_FLUSH()`
313

T
toby 已提交
314
##### `UNITY_OUTPUT_START()`
315

T
toby 已提交
316
##### `UNITY_OUTPUT_COMPLETE()`
317 318 319 320 321 322 323 324 325

By default, Unity prints its results to `stdout` as it runs. This works
perfectly fine in most situations where you are using a native compiler for
testing. It works on some simulators as well so long as they have `stdout`
routed back to the command line. There are times, however, where the simulator
will lack support for dumping results or you will want to route results
elsewhere for other reasons. In these cases, you should define the
`UNITY_OUTPUT_CHAR` macro. This macro accepts a single character at a time (as
an `int`, since this is the parameter type of the standard C `putchar` function
T
toby 已提交
326 327 328
most commonly used). You may replace this with whatever function call you like.

_Example:_
329 330
Say you are forced to run your test suite on an embedded processor with no
`stdout` option. You decide to route your test result output to a custom serial
T
toby 已提交
331
`RS232_putc()` function you wrote like thus:
332 333 334 335 336 337 338 339
```C
#include "RS232_header.h"
...
#define UNITY_OUTPUT_CHAR(a)    RS232_putc(a)
#define UNITY_OUTPUT_START()    RS232_config(115200,1,8,0)
#define UNITY_OUTPUT_FLUSH()    RS232_flush()
#define UNITY_OUTPUT_COMPLETE() RS232_close()
```
T
toby 已提交
340 341

_Note:_
342
`UNITY_OUTPUT_FLUSH()` can be set to the standard out flush function simply by
343
specifying `UNITY_USE_FLUSH_STDOUT`. No other defines are required.
T
toby 已提交
344

345

346 347 348 349 350 351 352 353 354 355 356 357
##### `UNITY_OUTPUT_FOR_ECLIPSE`

##### `UNITY_OUTPUT_FOR_IAR_WORKBENCH`

##### `UNITY_OUTPUT_FOR_QT_CREATOR`

When managing your own builds, it is often handy to have messages output in a format which is
recognized by your IDE. These are some standard formats which can be supported. If you're using 
Ceedling to manage your builds, it is better to stick with the standard format (leaving these
all undefined) and allow Ceedling to use its own decorators.


T
toby 已提交
358
##### `UNITY_PTR_ATTRIBUTE`
359 360 361

Some compilers require a custom attribute to be assigned to pointers, like
`near` or `far`. In these cases, you can give Unity a safe default for these by
T
toby 已提交
362 363 364
defining this option with the attribute you would like.

_Example:_
365 366 367 368
```C
#define UNITY_PTR_ATTRIBUTE __attribute__((far))
#define UNITY_PTR_ATTRIBUTE near
```
369

M
Mark VanderVoord 已提交
370 371 372 373 374 375 376
##### `UNITY_PRINT_EOL`

By default, Unity outputs \n at the end of each line of output. This is easy
to parse by the scripts, by Ceedling, etc, but it might not be ideal for YOUR
system. Feel free to override this and to make it whatever you wish.

_Example:_
377 378 379
```C
#define UNITY_PRINT_EOL { UNITY_OUTPUT_CHAR('\r'); UNITY_OUTPUT_CHAR('\n') }
```
M
Mark VanderVoord 已提交
380 381 382 383 384 385 386 387 388 389 390


##### `UNITY_EXCLUDE_DETAILS`

This is an option for if you absolutely must squeeze every byte of memory out of
your system. Unity stores a set of internal scratchpads which are used to pass
extra detail information around. It's used by systems like CMock in order to
report which function or argument flagged an error. If you're not using CMock and
you're not using these details for other things, then you can exclude them.

_Example:_
391 392 393
```C
#define UNITY_EXCLUDE_DETAILS
```
M
Mark VanderVoord 已提交
394 395 396 397 398 399 400 401 402 403 404 405


##### `UNITY_EXCLUDE_SETJMP`

If your embedded system doesn't support the standard library setjmp, you can
exclude Unity's reliance on this by using this define. This dropped dependence
comes at a price, though. You will be unable to use custom helper functions for
your tests, and you will be unable to use tools like CMock. Very likely, if your
compiler doesn't support setjmp, you wouldn't have had the memory space for those
things anyway, though... so this option exists for those situations.

_Example:_
406 407 408
```C
#define UNITY_EXCLUDE_SETJMP
```
M
Mark VanderVoord 已提交
409

410 411 412
##### `UNITY_OUTPUT_COLOR`

If you want to add color using ANSI escape codes you can use this define.
413

414
_Example:_
415 416 417
```C
#define UNITY_OUTPUT_COLOR
```
M
Mark VanderVoord 已提交
418

419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
##### `UNITY_SHORTHAND_AS_INT`
##### `UNITY_SHORTHAND_AS_MEM`
##### `UNITY_SHORTHAND_AS_RAW`
##### `UNITY_SHORTHAND_AS_NONE`

These options  give you control of the `TEST_ASSERT_EQUAL` and the
`TEST_ASSERT_NOT_EQUAL` shorthand assertions. Historically, Unity treated the
former as an alias for an integer comparison. It treated the latter as a direct
comparison using `!=`. This assymetry was confusing, but there was much
disagreement as to how best to treat this pair of assertions. These four options
will allow you to specify how Unity will treat these assertions.

  - AS INT - the values will be cast to integers and directly compared. Arguments
             that don't cast easily to integers will cause compiler errors.
  - AS MEM - the address of both values will be taken and the entire object's
             memory footprint will be compared byte by byte. Directly placing
             constant numbers like `456` as expected values will cause errors.
  - AS_RAW - Unity assumes that you can compare the two values using `==` and `!=`
             and will do so. No details are given about mismatches, because it
             doesn't really know what type it's dealing with.
  - AS_NONE - Unity will disallow the use of these shorthand macros altogether,
             insisting that developers choose a more descriptive option.
M
Mark VanderVoord 已提交
441

442 443
#### `UNITY_SUPPORT_VARIADIC_MACROS`

444
This will force Unity to support variadic macros when using its own built-in 
445 446 447 448 449 450
RUN_TEST macro. This will rarely be necessary. Most often, Unity will automatically
detect if the compiler supports variadic macros by checking to see if it's C99+
compatible. In the event that the compiler supports variadic macros, but is primarily
C89 (ANSI), defining this option will allow you to use them. This option is also not 
necessary when using Ceedling or the test runner generator script. 

T
toby 已提交
451
## Getting Into The Guts
452 453 454 455 456 457 458 459 460

There will be cases where the options above aren't quite going to get everything
perfect. They are likely sufficient for any situation where you are compiling
and executing your tests with a native toolchain (e.g. clang on Mac). These
options may even get you through the majority of cases encountered in working
with a target simulator run from your local command line. But especially if you
must run your test suite on your target hardware, your Unity configuration will
require special help. This special help will usually reside in one of two
places: the `main()` function or the `RUN_TEST` macro. Let's look at how these
T
toby 已提交
461 462
work.

463

T
toby 已提交
464
##### `main()`
465 466 467 468 469 470

Each test module is compiled and run on its own, separate from the other test
files in your project. Each test file, therefore, has a `main` function. This
`main` function will need to contain whatever code is necessary to initialize
your system to a workable state. This is particularly true for situations where
you must set up a memory map or initialize a communication channel for the
T
toby 已提交
471 472 473 474
output of your test results.

A simple main function looks something like this:

475 476 477 478 479 480 481 482 483
```C
int main(void) {
    UNITY_BEGIN();
    RUN_TEST(test_TheFirst);
    RUN_TEST(test_TheSecond);
    RUN_TEST(test_TheThird);
    return UNITY_END();
}
```
T
toby 已提交
484

485 486 487 488
You can see that our main function doesn't bother taking any arguments. For our
most barebones case, we'll never have arguments because we just run all the
tests each time. Instead, we start by calling `UNITY_BEGIN`. We run each test
(in whatever order we wish). Finally, we call `UNITY_END`, returning its return
T
toby 已提交
489 490
value (which is the total number of failures).

491 492 493
It should be easy to see that you can add code before any test cases are run or
after all the test cases have completed. This allows you to do any needed
system-wide setup or teardown that might be required for your special
T
toby 已提交
494 495
circumstances.

496

T
toby 已提交
497
##### `RUN_TEST`
498 499 500 501 502 503

The `RUN_TEST` macro is called with each test case function. Its job is to
perform whatever setup and teardown is necessary for executing a single test
case function. This includes catching failures, calling the test module's
`setUp()` and `tearDown()` functions, and calling `UnityConcludeTest()`. If
using CMock or test coverage, there will be additional stubs in use here. A
T
toby 已提交
504 505
simple minimalist RUN_TEST macro looks something like this:

506 507 508 509 510 511 512 513 514 515 516
```C
#define RUN_TEST(testfunc) \
    UNITY_NEW_TEST(#testfunc) \
    if (TEST_PROTECT()) { \
        setUp(); \
        testfunc(); \
    } \
    if (TEST_PROTECT() && (!TEST_IS_IGNORED)) \
        tearDown(); \
    UnityConcludeTest();
```
T
toby 已提交
517

518 519 520 521 522 523
So that's quite a macro, huh? It gives you a glimpse of what kind of stuff Unity
has to deal with for every single test case. For each test case, we declare that
it is a new test. Then we run `setUp` and our test function. These are run
within a `TEST_PROTECT` block, the function of which is to handle failures that
occur during the test. Then, assuming our test is still running and hasn't been
ignored, we run `tearDown`. No matter what, our last step is to conclude this
T
toby 已提交
524 525
test before moving on to the next.

526 527 528 529 530
Let's say you need to add a call to `fsync` to force all of your output data to
flush to a file after each test. You could easily insert this after your
`UnityConcludeTest` call. Maybe you want to write an xml tag before and after
each result set. Again, you could do this by adding lines to this macro. Updates
to this macro are for the occasions when you need an action before or after
T
toby 已提交
531 532
every single test case throughout your entire suite of tests.

533

T
toby 已提交
534
## Happy Porting
535 536 537

The defines and macros in this guide should help you port Unity to just about
any C target we can imagine. If you run into a snag or two, don't be afraid of
M
Mark VanderVoord 已提交
538 539 540 541
asking for help on the forums. We love a good challenge!


*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)*