UTF"> ]>
Boost Test Library: The Unit Test Framework The Unit Test Framework
Introduction XP maxim The acceptance test makes the customer satisfied that the software provides the business value that makes them willing to pay for it. The unit test makes the programmer satisfied that the software does what the programmer thinks it does What is the first thing you need to do when you start working on new library/class/program? That's right - you need to start with the unit test module (I hope you all gave this answer!). Occasional, simple test may be implemented using asserts. But any professional developer soon finds this approach lacking. It becomes clear that it's too time-consuming and tedious for simple, but repetitive unit testing tasks and it's too inflexible for most nontrivial ones. The Boost Test Library Unit Test Framework (further in the documentation referred by the acronym UTF) provides both an easy to use and flexible solution to this problem domain: C++ unit test implementation and organization. Unit testing tasks arise during many different stages of software development: from initial project implementation to its maintenance and later revisions. These tasks differ in their complexity and purpose and accordingly are approached differently by different developers. The wide spectrum of tasks in a problem domain cause many requirements (sometimes conflicting) to be placed on a unit testing framework. These include: Writing a unit test module should be simple and obvious for new users. The framework should allow advanced users to perform nontrivial tests. Test module should be able to have many small test cases and developer should be able to group them into test suites. At the beginning of the development users want to see verbose and descriptive error message, whereas during the regression testing they just want to know if any tests failed. For a small test modules run time should prevail over compilation time: user don't want to wait a minute to compile a test that takes a second to run. For long and complex tests users want to be able to see the test progress. Simplest tests shouldn't require an external library. For long term usage users of a unit test framework should be able to build it as a standalone library. The &utf; design is based on above rationale and provides versatile facilities to: Simplify writing test cases by using various testing tools. Organize test cases into a test tree. Relieve you from messy error detection, reporting duties and framework runtime parameters processing. The &utf; keeps track of all passed/failed testing tools assertions, provides an ability to check the test progress and generates a result report in several different formats. The &utf; supplies command line test runners that initialize the framework and run the requested tests. Depending on the selected compilation flags the function main() default implementation, that invoke the supplied test runner, can be generated automatically as well. The &utf; is intended to be used both for a simple and non trivial testing. It is not intended to be used with production code. In this case the Program Execution Monitor is more suitable. Given the largely differing requirements of new and advanced users, it is clear that the &utf; must provide both simple, easy-to-use interfaces with limited customization options and advanced interfaces, which allow unit testing to be fully customized. Accordingly the material provided in this documentation is split into two sections: The User's Guide: covers all functionality that doesn't require knowledge of the &utf; internals The Advanced User's Guide: covers all implementation details required for a user to understand the advanced customization options available in the &utf;, and for a user interested in extending the testing framework. For those interested in getting started quickly please visit collection of examples presented in this documentation.
The &utf; compilation variants and procedures Compilation
<para role="first-line-indented"> The &utf; is comparatively complicated component and is implemented in close to hundred header and source files, so for long term usage the preferable solution is to build the &utf; as a reusable standalone library. Depending on your platform this may save you a significant time during test module compilation and doesn't really require that much effort <footnote><simpara>If you are using Visual studio compilers do not forget to set a subsystem to console when you build test modules. You can do it either in project properties or by setting command line /SUBSYTEM:CONSOLE. Number of people reported link error caused specifically by this omission</simpara></footnote>. <ulink url="http://boost.org/more/getting_started/index.html">Boost Getting started</ulink> tells you how to get pre-built libraries for some platforms. If available, this is the easiest option and you can ignore standalone library compilation instructions below. </para> <para role="first-line-indented"> Following files constitute the &utf; implementation: <!--TO FIX: explain cpp/ipp --> </para> <itemizedlist html-class="files-list"> <listitem> <simpara><ulink url="../../../../boost/test/impl/debug.ipp"><filename>debug.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/compiler_log_formatter.ipp"><filename>compiler_log_formatter.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/exception_safety.ipp"><filename>exception_safety.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/execution_monitor.ipp"><filename>execution_monitor.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/framework.ipp"><filename>framework.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/interaction_based.ipp"><filename>interaction_based.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/logged_expectations.ipp"><filename>logged_expectations.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/plain_report_formatter.ipp"><filename>plain_report_formatter.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/progress_monitor.ipp"><filename>progress_monitor.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/results_collector.ipp"><filename>results_collector.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/results_reporter.ipp"><filename>results_reporter.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/unit_test_log.ipp"><filename>unit_test_log.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/unit_test_main.ipp"><filename>unit_test_main.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/unit_test_monitor.ipp"><filename>unit_test_monitor.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/unit_test_parameters.ipp"><filename>unit_test_parameters.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/unit_test_suite.ipp"><filename>unit_test_suite.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/xml_log_formatter.ipp"><filename>xml_log_formatter.cpp</filename></ulink></simpara> </listitem> <listitem> <simpara><ulink url="../../../../boost/test/impl/xml_report_formatter.ipp"><filename>xml_report_formatter.cpp</filename></ulink></simpara> </listitem> </itemizedlist> </section> <section id="utf.compilation.procedure"> <title>Compilation procedures In comparison with many other boost libraries, which are completely implemented in header files, compilation and linking with the &utf; may require additional steps. The &utf; presents you with options to either built and link with a standalone library or include the implementation directly into a test module. If you opt to use the library the &utf; headers implement the auto-linking support. The compilation of the &utf; library and a test module can be configured using the following compilation flags. The &utf; compilation flags Flag Usage BOOST_TEST_DYN_LINK Define this flag to build/use dynamic library. BOOST_TEST_NO_LIB Define this flag to prevent auto-linking. BOOST_TEST_NO_MAIN Define this flag to prevent function main() implementation generation. BOOST_TEST_MAIN Define this flag to generate an empty test module initialization function and in case of dynamic library variant default function main() implementation as well. BOOST_TEST_MODULE Define this flag to generate the test module initialization function, which uses the defined value to name the master test suite. In case of dynamic library variant default function main() implementation is generated as well BOOST_TEST_ALTERNATIVE_INIT_API Define this flag to generate the switch to the alternative test module initialization API.
Further in documentation you are going to see in details when and how these flags should be used.
Standalone library compilation If you opted to link your program with the standalone library, you need to build it first. To build a standalone library the all C++ files (.cpp), that constitute &utf; implementation need to be listed as source files in your makefileThere are varieties of make systems that can be used. To name a few: GNU make (and other make clones) and build systems integrated into IDEs (for example Microsoft Visual Studio). The Boost preferred solution is Boost.Build system that is based on top of bjam tool. Make systems require some kind of configuration file that lists all files that constitute the library and all build options. For example the makefile that is used by make, or the Microsoft Visual Studio project file, Jamfile is used by Boost.Build. For the sake of simplicity let's call this file the makefile.. The Jamfile for use with Boost.Build system is supplied in libs/test/build directory. The &utf; can be built as either static or dynamic library.
Static library compilation No special build options or macro definitions are required to build the static library. Using the Boost.Build system you can build the static library with the following command from libs/test/build directory: bjam -sTOOLS=<your-tool-name> -sBUILD=boost_unit_test_framework Also on Windows you can use the Microsoft Visual Studio .NET project file provided.
Dynamic library compilation To build the dynamic libraryWhat is meant by the term dynamic library is a dynamically loaded library, alternatively called a shared library. you need to add to the list of macro definitions in the makefile. Using the Boost.Build system you can build the dynamic library with the following command from libs/test/build directory: bjam -sTOOLS=<your-tool-name> -sBUILD=boost_unit_test_framework Also on Windows you can use the Microsoft Visual Studio .NET project file provided. For test module to successfully link with the dynamic library the flag needs to be defined both during dynamic library build and during test module compilation.
Support of the auto-linking feature Auto-linking support For the Microsoft family of compilers the &utf; provides an ability to automatically select proper library name and add it to the list of objects to be linked with. By default this feature is enabled. To disable it you have to define the flag . For more details on the auto-linking feature implementation and configuration you should consult the appropriate documentation.
Including the &utf; directly into your test module Direct include If you prefer to avoid the standalone library compilation you can either include all files that constitute the static library in your test module's makefile or include them as a part of a test module's source file. To facilitate the later variant the &utf; presents the single-header usage variant. In either case no special build options or macro definitions are required to be added to your compilation options list by default. But the same flags that can be used for the standalone library compilation are applicable in this case. Though, obviously, neither nor are applicable. This solution may not be the best choice in a long run, since it requires the &utf; sources recompilation for every test module you use it with and for every change of a test module you are working on. In a result your testing cycle time may increase. If it become tiresome, I recommend switching to one of the prebuilt library usage variants.