Unit testing for C++ code - Tools and methodology [closed]
Asked Answered
C

22

139

I'm working on a large c++ system that is has been in development for a few years now. As part of an effort to improve the quality of the existing code we engaged on a large long-term refactoring project.

Do you know a good tool that can help me write unit tests in C++? Maybe something similar to Junit or Nunit?

Can anyone give some good advice on the methodology of writing unit tests for modules that were written without unit testing in mind?

Calida answered 18/9, 2008 at 10:8 Comment(1)
Check out this question: #3650Regelation
H
85

Applying unit tests to legacy code was the very reason Working Effectively with Legacy Code was written. Michael Feathers is the author - as mentioned in other answers, he was involved in the creation of both CppUnit and CppUnitLite.

alt text

Heimer answered 18/9, 2008 at 10:47 Comment(5)
I think CPPUnit could make it simpler to write tests. We use CPPUnit, but I am not satisfied. I need to update two files for each test, and in my opinion, a test should be as simple to write as: 'TEST("testname") {ASSERT(1==1);}' The book on the other hand is a must for everyone, not only those who work with legacy code, but also for those who create it ;)Kaspar
I read the book. Very good readCalida
Since when is c++ legacy?!Nomology
IT's not that C++ is legacy - if I recall correctly, that book defines a legacy project as one for which there are none, or very few unit tests. Such projects do tend to be /hard/ to write unit tests in, because test driven development has never influenced the code base such that it is trivial to write them.Privateer
@Nils: As one of the Amazon reviewers of the book mentions, "legacy code is code without unit tests," which is exactly what this question is about.Laval
B
40

Google recently released their own library for unit testing C++ apps, called Google Test.

Project on Google Code

Boggle answered 18/9, 2008 at 10:20 Comment(4)
is it possible to use this with VC++Judgment
Seems pretty ok, especially the way they have to add description to each assertion. On the down side, I personally prefer having a Unit Test class instead of macros that really don't look like classes.Biggers
another nice point is the mocking possibilities: code.google.com/p/googlemockSelima
I find this MUCH nicer than CPPUNIT which requires tons of macros and magic files to make tests workDeadline
C
30

Check out an excellent comparison between several available suites. The author of that article later developed UnitTest++.

What I particularly like about it (apart from the fact that it handles exceptions etc. well) is that there is a very limited amount of 'administration' around the test cases and test fixtures definition.

Cayla answered 27/9, 2008 at 9:23 Comment(2)
Isnt' that our fundamental fallacy? He's got good insight into available projects - but instead of improving them, he starts his own.Cygnus
@Cygnus : yes; but then UnitTest++ is so small and lightweight that it has value in being a separate project - it's very easy to get up and running.Jared
A
24

Boost has a Testing library which contains support for unit testing. It might be worth checking out.

Arnett answered 18/9, 2008 at 10:25 Comment(3)
I can recommend this excellent toolkit.Ashleighashlen
Yes, boost is the way to go. No overhead, just test and go! I was actually working on my own framework in despair when boost came to my rescue. Thank you boost (for everything!)Kaspar
You may check out an article I wrote introduction Boost Unit Testing beroux.com/english/articles/boost_unit_testingBiggers
S
22

Noel Llopis of Games From Within is the author of Exploring the C++ Unit Testing Framework Jungle, a comprehensive (but now dated) evaluation of the various C++ Unit Testing frameworks, as well as a book on game programming.

He used CppUnitLite for quite a while, fixing various things, but eventually joined forces with another unit test library author, and produced UnitTest++. We use UnitTest++ here, and I like it a lot, so far. It has (to me) the exact right balance of power with a small footprint.

I've used homegrown solutions, CxxTest (which requires Perl), and boost::test. When I implemented unit testing here at my current job it pretty much came down to UnitTest++ vs boost::test.

I really like most boost libraries I have used, but IMHO, boost::test is a little too heavy-handed. I especially did not like that it requires you (AFAIK) to implement the main program of the test harness using a boost::test macro. I know that it is not "pure" TDD, but sometimes we need a way to run tests from withing a GUI application, for example when a special test flag is passed in on the command line, and boost::test cannot support this type of scenario.

UnitTest++ was the simplest test framework to set up and use that I have encountered in my (limited) experience.

Swordbill answered 18/9, 2008 at 13:35 Comment(0)
Y
17

I'm using the excellent Boost.Test library in conjunction with a much less known but oh-so-awesome Turtle library : a mock object library based on boost.

As a code example speaks better than words, imagine you would like to test a calculator object which works on a view interface (that is Turtle's introductory example) :

// declares a 'mock_view' class implementing 'view'
MOCK_BASE_CLASS( mock_view, view )
{
    // implements the 'display' method from 'view' (taking 1 argument)
    MOCK_METHOD( display, 1 )                   
};

BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
    mock_view v;
    calculator c( v );

    // expects the 'display' method to be called once with a parameter value equal to 0
    MOCK_EXPECT( v, display ).once().with( 0 ); 

    c.add( 0, 0 );
}

See how easy and verbose it is do declare expectation on the mock object ? Obviously, test is failed if expectations are not met.

Yuri answered 18/11, 2010 at 7:37 Comment(0)
M
14

I've just pushed my own framework, CATCH, out there. It's still under development but I believe it already surpasses most other frameworks. Different people have different criteria but I've tried to cover most ground without too many trade-offs. Take a look at my linked blog entry for a taster. My top five features are:

  • Header only
  • Auto registration of function and method based tests
  • Decomposes standard C++ expressions into LHS and RHS (so you don't need a whole family of assert macros).
  • Support for nested sections within a function based fixture
  • Name tests using natural language - function/ method names are generated

It also has Objective-C bindings.

Mame answered 28/12, 2010 at 3:11 Comment(1)
doctest is my reimplementation of Catch with a huge focus on compilation speed - checkout the FAQ to see how they are differentArmenta
V
9

CxxTest is a light, easy to use and cross platform JUnit/CppUnit/xUnit-like framework for C++.

Viole answered 18/9, 2008 at 10:24 Comment(0)
S
7

CppUnit is the way. See link below:

http://cppunit.sourceforge.net/cppunit-wiki

http://en.wikipedia.org/wiki/CppUnit

Soave answered 18/9, 2008 at 10:10 Comment(0)
D
7

UnitTest++, small & simple.

Dna answered 18/9, 2008 at 10:20 Comment(0)
H
6

I am currently looking for a unit test and mock framework that can be used at our company for a long lived code-base. As you know the list of unit testing frameworks for c++ is long so I applied some filters to reduce it to a hand-full that can be looked in more closely. The first filter criterion was that it must be for free. The second criterion was project activity. I also looked for mocking frameworks because you need one if you want to write unit-tests.

I came up with the following list (approximately) sorted by activity, highest activity at the top:

  • GoogleTest / GoogleMock: Many contributers and used by Google itself. This will probably be here for some time and receive updates. For my private code-base I will switch to this combination in hopes to jump on the fastest train.

  • BoostTest + Turtle: Not updated that often, but the testing framework is a part of boost so it should be maintained. Turtle on the other hand is maintained by mainly one guy, but it has resent activity so it is not dead. I made almost all my testing experience with this combination because we already used the boost library at my previous job and I currently use it for my private code.

  • CppUTest: Provides testing and mocking. This project has been active from 2008 to 2015 and has quite a lot recent activity. This find was a little suprise because a lot of projects with significantly less activity come up more often when searching on the web (like CppUnit which had its last update in 2013). I have not looked deeper into this so I can't say anything about the details. Edit (16.12.2015): I recently tried this out and found this framework to be a little clumsy and "C-stylish", especially when using the mock classes. Also it seemed to have a smaller variety of assertions then other frameworks. I think its main strength is that it can be used with pure C projects.

  • QTest: The test library that ships with the Qt framework. Maintanance should be guaranteed for some time, but I use it rather as a supporting library, because the test-registration is IMO more clumsy then in other frameworks. As far as I understand it, it forces you to have one test-exe per test-fixture. But the test helper functions can be of good use when testing Qt-Gui code. It has no mocks.

  • Catch: It has recent activity but is mainly developed by one guy. The nice thing about this framework is the alternative fixture approach that lets you write reusable fixture code in the test itself. It also lets you set test names as strings which is nice when you tend to write whole sentences as test names. I whish this style would be ripped of and put into googleTest ;-)

Mock Frameworks

The number of mock frameworks is much smaller then the number of test frameworks but here are the ones that I found to have recent activity.

  • Hippomock: Active from 2008 unitl now but only with low intensity.

  • FakeIt: Active from 2013 unitl now but more or less developed by one guy.

Conclusion

If your code-base is in for the long run, choose between between BoostTest + Turtle and GoogleTest + GoogleMock. I think those two will have long term maintenance. If you only have a short lived code-base you could try out Catch which has a nice syntax. Then you would need to additionally choose a mocking framework. If you work with Visual Studio you can download test-runner adaptors for BoostTest and GoogleTest, that will allow you to run the tests with the test runner GUI that is integrated into VS.

Heaps answered 25/11, 2015 at 20:9 Comment(0)
P
3

See also the answers to the closely related question "choosing a c++ unit testing tool/framework", here

Photophobia answered 22/9, 2008 at 7:51 Comment(0)
A
3

There also is TUT, Template-Unit-Test, a template-based framework. It's syntax is awkward (some called it template-abusing), but its main advantage is that is it all contained in a single header file.

You'll find an example of unit-test written with TUT here.

Archetype answered 13/10, 2008 at 19:34 Comment(1)
I put up a header only library providing macros wrapping TUT's ensure function and test decleration code both to simplify it and provide file and line number information in failures. Here is a link to a post with examples of the difference in output and the code as well as link to the project on github: codecrafter.wordpress.com/2012/12/19/tutadapter1Intimate
F
2

I've tried CPPunit and it's not very user friendly.

The only alternative I know is using C++.NET to wrap your C++ classes and writing unit tests with one of .NET unit testing frameworks (NUnit, MBUnit etc.)

Fyke answered 18/9, 2008 at 10:18 Comment(0)
P
2

CppUTest is an excellent, light-weight framework for C and C++ unit-testing.

Perishable answered 7/6, 2011 at 18:33 Comment(0)
T
1

Michael Feathers of ObjectMentor was instrumental in the development of both CppUnit and CppUnitLite.

He now recommends CppUnitLite

Tournament answered 18/9, 2008 at 10:13 Comment(0)
V
1

Have a look at CUnitWin32. It's written for MS Visual C. It includes an example.

Velarium answered 12/2, 2009 at 22:16 Comment(0)
R
1

Have a look at cfix (http://www.cfix-testing.org), it's specialized for Windows C/C++ development and supports both user mode and kernel mode unit testing.

Renarenado answered 23/2, 2009 at 7:17 Comment(1)
Thanks for sharing. I recently started using cfix for testing purposes. I was looking for a way to view call stack both in case of passed and failed test cases. Is there way in cfix to achieve this?Shamus
K
1

If you are on Visual Studio 2008 SP1, I would highly recommend using MSTest for writing the unit tests. I then use Google mock for writing the mocks. The integration with the IDE is ideal and allows and doesn't carry the overhead of CPPunit in terms of editing three places for the addition of one test.

Kr answered 11/5, 2009 at 19:30 Comment(0)
A
1

I think VisualAssert is doing a great job in VS integration. It lets you run and debug the tests from VS and you don't need to create an executable in order to run the tests.

Adherence answered 27/9, 2010 at 8:36 Comment(0)
A
0

Check out fructose: http://sourceforge.net/projects/fructose/

It's a very simple framework, containing only header files and thus easy portable.

Assertion answered 22/9, 2008 at 7:31 Comment(0)
W
0

I'm using MS Test with Typemock Isolator++. Give it a try!

Webfooted answered 17/3, 2016 at 10:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.