|
BDE 4.39.x Production Release
|
Provide test utilities for bsl that do not use <iostream>.
Provide test utilities for bsl that do not use <iostream>.
bsl test drivers!X!X!X!X!X!X!X!XBSLS_BSLTESTUTIL_LOOP8_ASSERT(I, J, K, L, M, N, O,V, X): print args if !X
BSLS_BSLTESTUTIL_Q(X) : quote identifier literally BSLS_BSLTESTUTIL_P(X) : print identifier and value BSLS_BSLTESTUTIL_P_(X): print identifier and value without '
' BSLS_BSLTESTUTIL_L_ : current line number BSLS_BSLTESTUTIL_T_ : print tab without '
'
BSLS_BSLTESTUTIL_FORMAT_ZU : printf format for size_t BSLS_BSLTESTUTIL_FORMAT_TD : printf format for ptrdiff_t BSLS_BSLTESTUTIL_FORMAT_I64: printf format for unsigned 64-bit integers BSLS_BSLTESTUTIL_FORMAT_U64: printf format for signed 64-bit integers BSLS_BSLTESTUTIL_FORMAT_PTR: printf format for uintptr_t
This component provides standard facilities for components in the bsl package group to produce test driver output, including the standard printing macros used in BDE-style test drivers (ASSERT, LOOP_ASSERT, ASSERTV, P, Q, L, and T), and a suite of cross-platform format strings for printing C++ or BDE-specific types with printf.
Many components in the bsl package group reside below the standard library; therefore, hierarchical design dictates that the test driver for these components shall not use iostream (which is part of the standard library), and instead they shall only rely on the printf function to print objects' values. Using printf over iostream has the following disadvantages:
printf function requires a format string to specify the way to print an object; so, unlike iostream, printing different types of objects using printf requires different syntaxes due to the need for different format strings.This component provides solutions to these issues by (1) encapsulating all the standard printing macros in a single place, (2) providing a way to extend the supplied macros to support user-defined types, and (3) providing macros that resolve the correct printf format strings for types that do not have standard, cross-platform format strings of their own.
The macros in this component use a class method template, BslTestUtil::callDebugprint, to print the value of an object of the parameterized type, along with an optional leading string and an optional trailing string, to the console. The value of the object of the parameterized type will be printed using a free function named debugprint.
The macros defined in this component natively support built-in types through the debugprint function overloads for these types defined in this component. The macros can be extended support additional user-defined types by defining function overloads for debugprint that takes a single parameter of each user-defined type, in the same namespace in which the user-defined type is defined. See the second usage example for more details.
This section illustrates intended use of this component.
First, we write a component to test, which provides a utility class:
Then, we can write a test driver for this component. We start by providing the standard BDE assert test macro:
Next, we define the standard print and LOOP_ASSERT macros, as aliases to the macros defined by this component:
Now, using the (standard) abbreviated macro names we have just defined, we write a test function for the static fortyTwo method, to be called from a test case in a test driver.
Finally, when testFortyTwo is called from a test case in verbose mode we observe the console output:
First, we define a new user-defined type, MyType:
Then, in the same namespace in which MyType is defined, we define a function debugprint that prints the value of a MyType object to the console. (In this case, we will simply print a string literal for simplicity):
Now, using the (standard) abbreviated macro names previously defined, we write a test function for the MyType constructor, to be called from a test case in a test driver.
Finally, when testMyTypeSetValue is called from a test case in verbose mode we observe the console output:
Suppose we are writing a test driver that needs to print out the contents of a complex data structure in veryVeryVerbose mode. The complex data structure contains, among other values, an array of block sizes, expressed as size_t. It would be very cumbersome, and visually confusing, to print each member of the array with either the P_ or Q_ standard output macros, so we elect to print out the array as a single string, following the pattern of [ A, B, C, D, E, ... ]. This could be easily accomplished with multiple calls to printf, except that printf has no cross-platform standard formatting string for size_t. We can use the BSLS_BSLTESTUTIL_FORMAT_ZU macro to resolve the appropriate format string for us on each platform.
First, we write a component to test, which provides an a utility that operates on a list of memory blocks. Each block is a structure containing a base address, a block size, and a pointer to the next block in the list.
Then, we write a test driver for this component.
Here, after defining the standard BDE test macros, we define a macro, ZU for the platform-specific printf format string for size_t:
Note that, we could use BSLS_BSLTESTUTIL_FORMAT_ZU as is, but it is more convenient to define ZU locally as an abbreviation.
Next, we write the test apparatus for the test driver, which includes a support function that prints the list of blocks in a BlockList in a visually succinct form:
Here, we use ZU as the format specifier for the size_t in the printf invocation. ZU is the appropriate format specifier for size_t on each supported platform.
Note that because we are looping through a number of blocks, formatting the output directly with printf produces more readable output than we would get from calling the standard output macros.
Calling printf directly will yield output similar to:
while the standard output macros would have produced:
Now, we write a test function for one of our test cases, which provides a detailed trace of BlockList contents:
Finally, when testBlockListConstruction is called from a test case in veryVeryVerbose mode, we observe console output similar to:
| #define BSLS_BSLTESTUTIL_ASSERT | ( | X | ) | do { aSsErT(!(X), #X, __LINE__); } while (false) |
| #define BSLS_BSLTESTUTIL_ASSERTV | ( | ... | ) |
| #define BSLS_BSLTESTUTIL_EXPAND | ( | X | ) | X |
| #define BSLS_BSLTESTUTIL_FORMAT_I64 "%lld" |
| #define BSLS_BSLTESTUTIL_FORMAT_PTR "%X" |
| #define BSLS_BSLTESTUTIL_FORMAT_TD "%td" |
| #define BSLS_BSLTESTUTIL_FORMAT_U64 "%llu" |
| #define BSLS_BSLTESTUTIL_FORMAT_ZU "%zu" |
| #define BSLS_BSLTESTUTIL_L_ __LINE__ |
Current line number.
| #define BSLS_BSLTESTUTIL_LOOP0_ASSERT BSLS_BSLTESTUTIL_ASSERT |
| #define BSLS_BSLTESTUTIL_LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT |
| #define BSLS_BSLTESTUTIL_LOOP2_ASSERT | ( | I, | |
| J, | |||
| X | |||
| ) |
| #define BSLS_BSLTESTUTIL_LOOP3_ASSERT | ( | I, | |
| J, | |||
| K, | |||
| X | |||
| ) |
| #define BSLS_BSLTESTUTIL_LOOP4_ASSERT | ( | I, | |
| J, | |||
| K, | |||
| L, | |||
| X | |||
| ) |
| #define BSLS_BSLTESTUTIL_LOOP5_ASSERT | ( | I, | |
| J, | |||
| K, | |||
| L, | |||
| M, | |||
| X | |||
| ) |
| #define BSLS_BSLTESTUTIL_LOOP6_ASSERT | ( | I, | |
| J, | |||
| K, | |||
| L, | |||
| M, | |||
| N, | |||
| X | |||
| ) |
| #define BSLS_BSLTESTUTIL_LOOP7_ASSERT | ( | I, | |
| J, | |||
| K, | |||
| L, | |||
| M, | |||
| N, | |||
| O, | |||
| X | |||
| ) |
| #define BSLS_BSLTESTUTIL_LOOP8_ASSERT | ( | I, | |
| J, | |||
| K, | |||
| L, | |||
| M, | |||
| N, | |||
| O, | |||
| V, | |||
| X | |||
| ) |
| #define BSLS_BSLTESTUTIL_LOOP_ASSERT | ( | I, | |
| X | |||
| ) |
| #define BSLS_BSLTESTUTIL_LOOPN_ASSERT | ( | N, | |
| ... | |||
| ) | BSLS_BSLTESTUTIL_LOOPN_ASSERT_IMPL(N, __VA_ARGS__) |
| #define BSLS_BSLTESTUTIL_LOOPN_ASSERT_IMPL | ( | N, | |
| ... | |||
| ) | BSLS_BSLTESTUTIL_EXPAND(BSLS_BSLTESTUTIL_LOOP ## N ## _ASSERT(__VA_ARGS__)) |
| #define BSLS_BSLTESTUTIL_NUM_ARGS | ( | ... | ) |
| #define BSLS_BSLTESTUTIL_NUM_ARGS_IMPL | ( | X8, | |
| X7, | |||
| X6, | |||
| X5, | |||
| X4, | |||
| X3, | |||
| X2, | |||
| X1, | |||
| X0, | |||
| N, | |||
| ... | |||
| ) | N |
| #define BSLS_BSLTESTUTIL_P | ( | X | ) |
Print identifier and its value.
| #define BSLS_BSLTESTUTIL_P_ | ( | X | ) |
P(X) without \n.
| #define BSLS_BSLTESTUTIL_Q | ( | X | ) |
Quote identifier literally.
| #define BSLS_BSLTESTUTIL_T_ BloombergLP::bsls::BslTestUtil::printTab(); |
Print a tab (w/o newline).