relevance of using preprocessor directives for testing unit - c++

I'm using Boost unit tests BOOST_AUTO_TEST_CASE
It requires to remove main() function to execute the test cases.
The question is
What directives should be used for switching between Normal/UnitTest modes? I have cross-platform application for Windows and Unix.
I have only one suggestion: use something like #ifndef TESTING in main.cpp and use manual change #define TESTING line ?
Is there any better solution?
Thanks

Unit tests should go into a separate translation unit. If you have foo.hpp and foo.cpp for your library, you have something like foo_test.cpp for the unit tests. Your build environment would then be made aware of a new "test" target which builds and runs those tests.

Related

What structure should I have for mocking an embedded systems class for desktop testing?

I am building an embedded application in C++, but I want to test it through conventional continuous integration techniques. I am working on a library that depends on functions of the hardware such as printing, outputting to a pin, reading in analog data, etc.. Lets call the library lib and the hardware functions core(hardware.h). I have a mock class that covers all of these functions(hardware.h). The issue is that when I compile the code for the embedded application I need to include a header file for the hardware definitions, but I want to swap this out for the mock header when I want to do testing. Is there a way to get Cmake to do this? Should I be doing this a different way? Any suggestions would be appreciated.
I have made this work in IDE and such, but never with cmake and continuous integration.
-Lib
--src
---button.h
---button.cpp
--test
---testButton.cpp
-core
---hardware.h
-Mock
---hardware.h
//button.h
#include hardware.h
setPinMode(Input);
Is there a way to have cmake link the correct hardware.h up to the mock during debugging and the core during release?
We deal with this normally in the following way:
--lib
---hardware_interface.h
---etc
--MCU_TYPE
---main.cpp
---hardware_mcu_type.h
---hardware_mcu_type.cpp
--test
---main.cpp
---hardware_mock.h
As you can see we have a generic folder with common code. All code in the library uses the interface class from hardware_interface.h (we often have multiple interfaces for I2C, SPI, UART etc. all defined in separate files). All classes making use a specific interface have a function to set a pointer or reference to the interface. This is done in the main.cpp files.
Now these interfaces are pure virtual. When building an application it is thus required to fill these in. This is where either hardware_mcu_type.h or hardware_mock.h come in. In the main for the actual mcu the actual hardware implementations are used. When testing on a pc the mock objects are used.
You do need at least a switch in the CMakeLists.txt file building the different files for different builds.
Side note: please not that memory access and allocation is difficult to test on a different platform as this may vary. The unit tests are best focused on testing logic.
Declare a macro "MOCK_TEST", which when defined causes your mock code to get compiled, and when its not defined causes your embedded Hardware Abstraction Layer to be compiled. This way you can selectively compile mock/HAL.
//------ hardware.cpp ------
#ifdef MOCK_TEST
<Mock code>
#elif
<HAL code>
#endif
Pass this macro using the compiler option -D (in gcc) while compiling the mock.
$CC -c -DMOCK_TEST hardware.cpp (for compiling mock)
Integrate these changes for the two targets you are defining in CMake.

Can I link multiple BOOST unit tests into a single test binary?

I've recently started trying to put a venerable and large (>1 million lines) program under test. There are currently no unit tests. Also, the program is linked as each individual file being linked together - there are no component libraries. Furthermore, the objects are highly interdependent, and it is difficult (impossible?) to link to any object files without linking to at least half of them.
Yes, I know, my life sucks.
I'd like to do some refactoring (obviously), but I'd like to have some tests in place before I start moving things around. My current idea is to compile a single "test program" which runs all of the tests I create. This would drastically simplify the linking issues that I have and let me focus on the real problems. So I have two questions:
Is it possible to link multiple BOOST unit test files into one test executable?
Is there a better solution?
I guess, this is precisely how to use boost test.
I would keep one short main.cpp file consisting of literally 2 lines:
#define BOOST_TEST_MODULE "C++ Unit Tests for MyTangledLibrary"
#include <boost/test/included/unit_test.hpp>
And then I would keep adding test module *.cpp files compiled together into one executable
#include <boost/test/unit_test.hpp>
<< your include files >>
BOOST_AUTO_TEST_SUITE(FancyShmancyLogic)
BOOST_AUTO_TEST_CASE(TestingIf2x3equals6)
{
...
}
BOOST_AUTO_TEST_CASE(TestingIf2x2equals4)
{
...
}
BOOST_AUTO_TEST_SUITE_END()
Yes, you will be able to compile that main.cpp and all of your modules into one large executable.

Eclipse CDT: how to test functions?

How can I test the functions I write before using them in my main C++ application?
Say I have a main.cpp that uses function foo() declared in mylib.h and defined in mylib.cpp.
I would like to test foo() extensively on "toy" situations, to check that it behaves as expected.
How can I do this in Eclipse? For my need it would be enough to have a test.cpp so that I can test single functions at the occurrence. I just would do this adding a "test" option to my makefile that compiles "test.cpp" rather than "main.cpp" but I don't know how to do this in Eclipse.
Any other less naive advice is appreciated as well.
You should have two projects :
project with your main, that uses the library
project where you implement your library, with the unit test main. This main needs to initialize the unit test framework, and execute tests
So, if you haven't, pick an unit testing framework, and add tests.

"Comment" out Macro Function Definition

I am trying to use GTest to test my code but one of the things that bothers me is that it always gets compiled in. This slows down my release builds. A GTest test looks like this
TEST(CaseName, TestName)
{
ASSERT_EQ(3, 3);
}
I want to be able to comment out all of my test by a simple define. I can wrap every test in #ifdef's but that is really ugly. I would like to not include the GTest headers and instead define TEST myself in a way to get rid of the test.
What I Have So far.
I have a macro that defines it as a static function so that it should get optimized out but the assert's inside the test still get compiled (and are undefined). This means that I would also have to define every ASSERT and EXPECT which is tedious to say the least.
#define TEST(tcase, test) static void uselessFunction##tcase##_##test(void)
I could stick with this but I would much prefer something nicer. Hopefully there are some macro-magicians out there to help.
Rather than using macros like this, it might be better to put all your tests into files which are compiled into a test executable, and put all your production files into a library which is linked by the test exe.
In this way, you can have gtest run against both Debug and Release builds, but only compile the test code when you build the test executable.

Compiling Boost.Test tests faster

I am using xcode (gcc) to compile my boost test suite and it takes too long.
The tests are minimal dummy tests, yet it takes several seconds (about 20) to compile them:
#include "boost/test/included/unit_test.hpp"
BOOST_AUTO_TEST_CASE(dummy)
{
BOOST_CHECK_EQUAL(2+2, 4);
}
BOOST_AUTO_TEST_CASE(dummyFail)
{
BOOST_CHECK_EQUAL(2+3, 4);
}
The manual suggests using the library version to speed up compilation. However, I am concerned this might not work - xcode already rebuilds my tests only. The whole framework isn't compiled again since the object files exist.
I guess it's the amount of header files and templates in Boost.Test that are responsible for most of the compilation time.
Do you have an idea of how to compile significantly faster? Would using it as library work? Would including only parts of boost.test work?
Any help is greatly appreciated!
The reason it's slow to compile is because boost/test/included/unit_test.hpp is huge. Using a library makes it faster because the huge header is compiled when the library is built and not thereafter. Your tests then include a smaller set of headers, leading to shorter build times.
Because I'm too lazy to build the library, an alternative I've used is to have one source file (which never changes, and so is rarely rebuilt) include the full boost test, and then have all the real test sources include just boost/test/unit_test.hpp. That gives most of the benefits of using the library.
Try using precompiled headers, this should reduce compilation time. Details can be found here:
http://www.boost.org/boost-build2/doc/html/bbv2/reference/precompiled_headers.html
I believe all the options are now described in the official documentation (see Usage variants).
The Static library usage variant is very convenient, and greatly reduces compilation times.
As described there, one can create a single source file including just two lines, compile that separately and link that in with the other tests.
A comment regarding the linked docs.
I believe that there is an error in that page, namely here:
One and only one translation unit should include following lines:
#define BOOST_TEST_MODULE test module name
#include <boost/test/unit_test.hpp>
This leads to "undefined reference" errors in the linking phase.
I believe it should be instead:
#define BOOST_TEST_MODULE test module name
#include <boost/test/included/unit_test.hpp>