Best way of including Unit Tests in a C++ open source project? - c++

I'm planning to release a C++ project I've been working on as my first open source project. I use GTest as my unit test framework, and I don't know what's the common procedure to include this dependency in a public project.
Right now I have GTest as a submodule of my main project, but looking at other projects they don't usually have any submodule dependency, and it seems wrong to me to make people clone GTest as well as part of my project, as if they're already using it for their own unit tests they'll end up having duplicated code etc.
What's the common procedure for cases like this?
Thank you very much!

Usually we put test under compilation flags (or cmake variable, or autotools configuration flag, or...) and disable compilation of test when the framework is not detected or not asked to be used by the person that compiles.
That way, the dependency is not required but the user has the ability to add it if he wishes to use the unit tests.

Related

Boost Unit testing- where to locate makefiles

I would like to use Boost for unit testing. Writing the unit tests is not a problem. However, I am a little unsure how to structure the makefiles relating to each unit test. I am not an expert on makefiles so I would like to explain how my code base is, what I would like to do and then ask for the best solution.
I have a code base which is a mixture of Python, C++ utility functions in headers and one C++ application/library, but it uses the classes/functions located in other folders (which are not sub folders). So unsurprisingly I only have one makefile for my application.
I would like to add unit tests in each of the various folders my application uses.
I would also like to be able to run all the unit tests (across the multiple folders) by running one executable.
Do I write a boost unit test source file in each folder and add a corresponding makefile, one per each folder I wish to unit test? How do I structure this so that I can run all the unit tests from one executable?
Also, do I need to link my unit test makefiles to my application object file, or just gcc -I flag the headers it requires?
(I am using regular GNU Make)

How to setup seperate Boost Test project in Visual Studio 2010

I want to use Boost Test to unit test my code in Visual Studio 2010. I've downloaded and built the latest version of the library.
I've read a lot on the subject here and elsewhere on the internet and people seem to suggest having a second project within your solution exlusively for your tests.
Fine, sounds good. I'm having trouble actually setting this up however. I've yet to find a clear explanation of the best way to set this up.
Do I need to use a Project Reference to make my unit test project reference my main project?
If so, do I still need to add the Include & Source directories of my main project in the properties of my unit test project? If so, what's the advantage of using the Project Reference in the first place?
Do I have to have my main project output a library for my unit test project to link in? Again, I thought that Project References would make this unnecessary but it seems I don't really understand the Project References.
If at all possible could I get a very idiot proof, step by step procedure for setting up a Boost Test unit test project alongside a main project in VS2010?
Would I be better off going with the method laid out here (one project, different configurations to build tests or actual project exe):
http://blog.yastrebkov.com/2010/07/boost-test-setup-and-usage.html
Many thanks,
There is no magic behind setting up a Boost.Test project. Maybe because it's a regular C++ (executable) project in no way different from a "normal" application. This is what I do:
Create a new C++ project. I always choose Win32 Executable with precompiled headers. I have a naming convention, that all test projects using Boost.Test start with "tests.boost.testee_name..."
In "stdafx.h", add the include for <boost/unit_test.hpp> and define the BOOST_TEST_MODULE (I always choose the project name). Also, add all other includes for external components this project requires, e.g. other boost libraries, stl headers etc. This results in considerably faster compilation times.
The testee must be a library (dynamic or static). So "add reference" to all required dependencies. You can of course test header-only libraries, in that case do not add references.
Add source files to your test project, according to Boost.Test manual. The convention I enforce is one BOOST_FIXTURE_TEST_SUITE per file.
For convenience, I have a custom property sheet tailored for boost unit test, which I add to each boost test project. Among others it contains a post-build event, which runs the tests.
I have to add that, lately, I switched to MSTest with Visual Studio 2012 which allows a more comfortable way to manage the tests and test results. Nevertheless, for the most important parts of the software, I am still writing boost tests in order to ensure correctness with older toolsets and potentially other platforms.
Cheers,
Paul

Beginning Code::blocks and UnitTest++

I'm about to start a C++ project but I'm stuck at the basics.
I want to use the (linux) Code::Blocks IDE, and it's easy to create a normal project. However I want to do TDD using the UnitTest++ framework, and I don't know how to set everything up cleanly.
I've already asked a question about where to put the UnitTest::RunAllTests() command, and they told me the best place is the main() of a separate program.
How do I go about doing this in Code::Blocks? I think I need to create 2 projects:
The "real" project with its own main();
The unit testing project containing the tests and the main() with UnitTest::RunAllTests() inside.
Then somehow have the first project build and run the second during its build process. I don't know how to do that yet but I can find out on my own.
My questions are:
this is the right method?
do I have to create also a project for the UnitTest++ framework, in order to let other people build it on other platforms? Or is dropping the complied library in the project's path enough?
how can I organize the directories of these projects together? It'd be nice to put the tests related to each package in the same directory as that package, but is it ok to have multiple projects in the same directory tree?
I'll partly answer my own questions, as I've managed to get everything working.
Following the instructions on the official documentation page, I've put the UnitTest++ folder with the compiled library and all the source files in my project's path.
Then I created a test project for all the unit testing, with a main function containing the famous UnitTest::RunAllTests(). I put $exe_output as a post-build process here, in order to have the tests executed automatically every time I build this project.
I created the "real" project where my code to be tested will go. In the build settings I specified the test project as a dependency of the real project, so that every time I build the real one, it also builds the test project first.
With these settings I can work on my tests and on the real code, and I only have to build the real one to have the updated tests executed. Any failing test will also make the build fail.
Now two questions remain: "is this the best approach?" and "right now each project lives in a different directory. Is it wiser to leave it this way or should I put each test in the same folder as the real code to be tested?"

Unit testing non-exported classes in a DLL

We develop a C++ application using Visual Studio 2008 and unit test using Boost.Test. At the moment, we have a separate solution which contains our unit tests.
Many of our projects in the core solution produce DLL's. We're limited in test coverage because we cannot test non-exported classes.
I have two ideas on how these could be tested:
Export everything
Put the tests inside the DLL (same project and solution) and use Boost.Test's external runner
I'm not entirely sure what the drawbacks would be. Number 1 above breaks module level encapsulation, and number 2 could result in a much larger DLL, unless it's possible to only include the test code in certain configurations.
So, are there any severe drawbacks to the above methods, or can you think of other solutions?
Expanding on Tom Quarendon's answer to this question, I have used a slight variant of Simon Steele's response:
Create a test project (using whatever test framework you like, I use CppUnit).
In your test_case.cpp, #include <header/in/source/project.h>.
In the test project properties:
In Linker->General, add the source project's $(IntDir) to the Additional Library Directories.
In Linker->Input, add the .obj files to the Additional Dependencies.
Add the dependency from the test project to the source project in Project->Project Dependencies.
Again, the only maintenance overhead is the standard one for unit tests - to create the dependency on the unit(s) you want to test.
The solution I use for this is to build the same non-exported code into my tests DLL as well. This does increase build time and means adding everything to both projects, but saves exporting everything or putting the tests in the main product code.
Another posibility would be to compile the non-exported code into a lib which is used by both the DLL with exports, and the unit test project.
Was searching a solution as well, maybe the following will be easier to maintain.
Add a new build configuration e.g. "Unit testing Debug" to the DLL project and change the Configuration Type to be "Static Library .lib" ("General"->"Configuration Type").
Then just add a dependency of your unit tests on this project, now everything should link together when you use new build configuration "Unit testing Debug".
If you are using release builds for unit tests then you need to add another configuration with release optimizations.
So the benefits of this solution are:
low maintanability cost
single DLL/Static library project
don't have to manually link to .obj files
Drawbacks:
Extra configuration profile(s) will require some changes in your build environment (CI)
Greater compilation times
Update:
We actually ended up using a different approach.
We added new "Test debug"/"Test release' configurations for every existing project that we have.
For .exe/.dll projects we disable the original main.cpp from compiling and replaced it with the one that instantiates the test framework (e.g. gtest) and runs all the tests, the tests are in separate .cpp files which are also excluded from compilation in regular configurations (Release/Debug) and enabled only in Test configurations.
For .lib projects we also have new "Test debug"/"Test release" configurations and there we convert the static library to be an .exe file and provide a main.cpp which instantiates the testing framework and runs the tests and tests themselves. Test related files are excluded from compilation on Release/Debug configurations.
Try making a define such as the following somewhere all files will include:
#define EXPORTTESTING __declspec(dllexport)
And use it in place of the dllexport, like this:
class EXPORTTESTING Foo
{
...
};
Then you will be able to turn off the flag for building a release DLL, but keep it on for a unit-testable DLL.

Unit tests in a separate project

Long time viewer, first time questioner here. Using Unit Tests in a separate project, I can't figure out how to separate them at the release build?
Surely when I remove the reference to the Unit Test project, all the references to the Unit Test interfaces, won't be able to find the interfaces and will cause compiler errors?
Thanks for any help.
Edit: By separating I mean removing them on the release build.
Assuming .NET, your unit test project should have a reference to the production project - but not the other way round. Your production code shouldn't depend on your unit tests at all.
You should have built your two projects, so that the base code (That in which you are testing) has no dependencies on the unit test. It is the Unit Test that has the dependencies on your code.
From what you wrote, I gather you wrote your code in .NET? (i.e. Assemblies?). Your project dependencies should look like this.
// Business code
My_Project.dll
-> References
---> System.dll etc..
// Test code
My_Project_Test.dll
-> References
---> My_Project.dll
If you make your projects that way, than I think you won't have to do anything special in your release build configuration.