Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design for testability in C++

I want to understand the best way to design testable applications in C++, perhaps in comparison to C# (because its my background and great for testing)

I'm used to coding to interfaces, dependency injection, inversion of control frameworks, and mock objects. Since C# has a lot of different language features I'm not sure how much of the patterns should still apply. I also imagine C++'s unique features / limitations might lend to different testing strategies.

I've looked at unit testing frameworks, and I like Google Test, but it's also important to write my fresh code to be testable as possible.

  • Are there any opensource projects which could be recommended as C++ testing done right?
  • Any books or articles that go into this topic in greater detail?
  • Recommendations for additional frameworks / libraries

Thanks

like image 748
Ryu Avatar asked Mar 13 '12 03:03

Ryu


2 Answers

I'm in the exact same situation myself, right now. Coming from a C# background, now I'm writing new (and expanding legacy) C++ applications.

I guess the shared background leaves us with common questions going forward. I was surprised how tightly coupled dependencies were to our classes in the legacy applications.

The concern, as you seem to have highlighted, is that maybe best practice in C# is not the best way in C++. After much research, some Stack Overflow questions of my own, and some prototyping, I've ended up with a C++ architecture that in many ways mirrors what I felt worked best in C#.

Here are the main principals I'm using:

  • Dependency injection

    Constructors for our classes take interfaces for dependencies that we might want to mock as parameters. In some cases, this meant writing wrappers for dependencies, like boost::filesystem, for example, which is mostly implemented in templated headers. Worth the small effort, in my opinion, as is more loosely couples us from libraries that may change or be swapped by us, and it allows us to unit test with mock implementations.

  • Test as you go!

    This should go without saying, but writing tests as you write the class allows you to sanity check your design in regards to testability. I don't care you test first, do TDD, or whatever you call it, my philosophy is just write your tests before you start consuming the class in your code base.

  • Google Test as our unit test framework

    So far, I've used Cxxtest (legacy apps) and Google Test. Google Test provides a lot of flexible options at execution time to determine what set of tests you run. We split our class naming convention out to UnitTest_xxxx and IntegrationTest_xxxx. Then at the command line, I can tell gtest to only run tests with one name, the other, or both. Then my build server can execute the long running tests over the whole test suite at night, but the unit tests at every check in. Cxxtest could do the same thing, but with more work, and is generally clunky for many reasons.

  • Google Mock for mock objects at test time

    The obvious benefit of dependency injection is using mocked objects during testing. One could simply write fake implementations of every interface, but Google Mock allows quick spin up of fake objects and provides the typical checks you would expect from a good .NET mocking framework like Moq or RhinoMock.

like image 170
Evan Avatar answered Sep 20 '22 16:09

Evan


I've used CPP Unit which is a port of JUnit. It's very easy to use and provides output in XML format which is great. As far as how to use it, you can check out the cookbook here.

like image 25
bsimic Avatar answered Sep 22 '22 16:09

bsimic