In the seminal book Accelerate, Forsgren and her co-authors provide empirical evidence that Continuous Delivery has a positive impact on the performance of software development organisations. If organisations neglect some of the principles and practices of Continuous Delivery, their performance will suffer. They will reach the point where simple changes will take ages to implement. Not so with Continuous Delivery.Read More »The Key Principles of Continuous Delivery
Not right away! Trunk-Based Development requires that the software builds and passes enough tests, before we integrate our changes into the main branch (a.k.a., trunk). We have enough tests, if breaking the software is highly unlikely. By definition, legacy code has no or not enough tests. Hence, we cannot apply trunk-based development right way, but should evolve our development process towards it.Read More »Can We Use Trunk-Based Development for Legacy Software?
We start with unit tests reading a file line by line with
QFile. Unit tests accessing the file system are not considered unit tests, as they may be slow and may depend on each other in surprising ways (see A Set of Unit Testing Rules by Michael Feathers). In a first step, we encapsulate
QFile in a class
TextFile and provide a fake implementation representing the file as a list of strings kept in main memory. In a second step, we introduce an interface, from which the product and fake implementations derive. We can now apply TDD to classes accessing files.
A client recently asked me to help them get a legacy HAL driver under test. They want to use TDD to maintain and extend the driver. We ran into a couple of problems, because the tests run on a 64-bit computer, whereas the production code runs on a 32-bit microcontroller. I’ll explain the problems and how to solve them.Read More »Applying TDD to HAL Drivers with Memory-Mapped I/O
It depends! If a C++ source file includes the header inside an
extern "C" section, the header is compiled as C++. If a C source file includes the header, the header is compiled as C. Hence, the header file should be both valid C and valid C++.
Today, I looked at the data-driven unit tests I had written nearly four weeks ago. It took me a couple of minutes to understand the tests again. Understanding my own tests should have been much easier.
Data-driven unit tests in QTest have a fundamental problem. The data goes in one function, say
testWriteFrame_data, and the test case working on the data goes in another function, say
testWriteFrame. I must go back and forth to understand the test case. While going back and forth, I typically forget one piece of information. So, I must do another round trip.
So, I sat down and converted each row of the table created by
testWriteFrame_data into a test function of its own. The resulting test cases are much easier to understand. They have about the same code size as the original solution. But see for yourself.