Interview: Testability in C++ with Clare Macrae

Clare Macrae

Clare is an independent consultant, helping developers work more easily with legacy C++ and Qt code. She has worked in software development for over 30 years. Until June 2019, she was a Principal Scientific Software Engineer at Cambridge Crystallographic Data Centre (CCDC), which releases data and powerful software for scientific education, research, and streamlining the design and manufacture of new medicines. Clare has recently been working with Llewellyn Falco on ApprovalTests.cpp, to radically simplify testing of legacy C++ code.






Q1. In the past, many people found that C++ was harder to test than other languages. Is that still the case?

C++ has a wide range of excellent test frameworks – and newer ones like Catch2 and doctest make it easy to write powerful, expressive tests.

I think many people unfairly judge C++ based on their experiences with code written prior to C++ 11. The language and its Standard Library have improved beyond all recognition, with major improvements in 2011, 2014 and 2017. That 3-year pattern will continue.

However, those who come to C++ from other modern languages justifiably bemoan the absence of reflection, a standard dependency management tool, and more powerful refactoring tools. They probably complain about slow build times too!

Of course, all these things are being worked on, and will improve over time.

On my personal wish-list: I would love to see a C++ equivalent of NCrunch – live, automatic running of just the relevant tests, with fast code coverage feedback - all whilst you type.

So C++ testing has got massively easier over the last 8 years or so – but that shouldn’t stop us wanting to make it easier still!

Q2. You have been contributing to the C++ version of ApprovalTests. Could you tell us a bit about the ApprovalTests library and how it helps improve testability?

Approval Tests are a quick way to add tests for complex objects in existing (often, Legacy) code. They are a form of Golden Master test. Many people create their own Golden Master implementation, and then find that Approval Tests are more convenient, powerful and maintainable.

The approach was created by Llewellyn Falco, and there are now implementations in many languages.

You supply the inputs to the code you are testing, and Approval Tests takes the output and saves it in a readable format. You add the output files to version control, and they become your specification. From then on, Approval Tests ensures that the output remains consistent, and makes it easy to view and manage differences using standard tools if the results change. 

Approval Tests mean you can move on to the next feature or next test more quickly.

I’ve heard from people who thought it would be impossibly expensive to write tests for critical legacy code. With Approval Tests, they have been able to get good test coverage in a day or two, and enabled safe refactoring.

A recent talk from Clare Macrae at London Continuous Delivery meetup group - londoncd.org.uk


Q3. What are some simple things that C++ developers can do to improve the testability of the code they write?

If you haven’t done so already, pick a test framework that auto-registers tests, and get to know it well. Two that I recommend these days are Catch2 and doctest

My advice with hard-to-test code is to “take any reasonable measures to make it easy to add tests”: writing effective tests as you go will save you time later.

This might mean using dependency injection to give tests control over behaviour. It might mean introducing a test fixture that sits between the thing you are testing and your tests, and using the test fixture to write expressive tests.

Once you start writing tests as you write code, you will find that it encourages better design, for example by dividing up code that does too much to separate the responsibilities. 

That’s all about unit tests, but I have recently discovered the Team Guide to Software Testability, and it makes a really good case for also considering testability at a much higher level, of the running system. I think some systems I worked on years ago would have been much more maintainable had I known that earlier.



Q4. You are very active in the C++ community. What are the best meetups and conferences to go to for people working with C++, Qt, and related frameworks?

It’s really hard to pick just a few C++ conferences to recommend these days. The Standard C++ Foundation maintains a world-wide list of conferences and it grows every time I look at it - from 6 listed in 2016 to 19 in 2019! Meeting C++ and code::dive are the biggest in Europe, and CppCon - in Colorado - is the biggest anywhere.

Meeting C++ maintains a list of C++ User Groups - and publishes monthly lists of upcoming meetups and user group meetings. Here in the UK, it’s also worth knowing about the ACCU Local Groups.

Qt has the mainly marketing-focussed Qt World Summits and QtDay is more developer-focussed.

One more thing: I encourage readers to look at #include <C++> - the global, inclusive, and diverse community for developers interested in C++. Our diversity scholarships send people to major conferences and include conference admission, accommodation and travel, as well as access to events like speaker dinners. Please consider applying or donating, as appropriate.




Follow Clare Macrae online: @ClareMacraeUK and claremacrae.co.uk