We’ve talked a lot about our love of Test-Driven Development (TDD) at Bluefruit. From improving the quality to our products to increasing the productivity of our team, we’re die hard TDD fans. However, we realise not everyone is 100% sure TDD is the right approach for their embedded software project. So we thought we’d explore some of the common challenges clients and even our embedded software colleagues raise about TDD and why we think it’s still worth giving a try.
1. Test-Driven Development doesn’t work for embedded devices.
It’s commonly known that manufacturer-provided device drivers typically do not use unit tests to ensure their own quality. However, at Bluefruit, we have created a bespoke well unit-tested embedded operating system (Satoru) to enable all aspects of the software on an embedded device to be fully testable. This gives you confidence in the accuracy, reliability, and quality of your entire system from the lowest level.
With code to run on embedded devices written in C/C++, we can integrate with test frameworks to confirm that the requirements are functional and reassure you about the quality though thorough code coverage. Integration tests ensure that the software maintains existing functionality when new features are added, which is especially important in fields where the technology and scientific knowledge is constantly evolving.
2. Test-Driven Development is disruptive and can add too much time to a sprint.
In our experience, we’ve found when executed properly TDD can actually make the development process go more smoothly. For example, by prompting the developer to analyse the requirements in depth at the start of a development cycle when writing the initial test, asking questions at that point instead of when they are in the middle of the development itself. A developer with a better understanding of what is required will implement a more concise solution, with less rework or wasted code, that is easier for others to review. For medical applications, a simpler and more concise codebase means that there are less areas which can go wrong, and this lowers the risk.
We are also able to save time because a large amount of the testing is instead automated and performed routinely during the development, giving good code coverage (reports that are required for standards documentation), identifying any new errors created earlier, and reducing the need for time-consuming rework to retrospectively add tests at the end of a project.
Whilst this process might take slightly longer upfront, once it starts running it speeds up the overall velocity of the project as you don’t have to interrupt the project between sprints to do large scale redevelopment.
3. Test-Driven Development is a nice to have not a must have and if you’re on a budget it can be cut
As developers who value quality, we want to create software which works as intended and is valuable to our clients because it is built on solid foundations—a good testbase and more concise code. This enables us to demonstrate that the work done so far is valid (functionally correct and meaningful to the user) and provides feedback on the quality of the project as well as the timely discovery and fix to any errors introduced during development.
TDD doesn’t have to increase the cost of a project and as we mentioned above, it can help decrease the testing required at the end of each sprint and project. It also builds a significant safety-net into the project as you work which means an extra level of security. We do a lot of work within the medical, automotive, and aerospace sectors where quality assurance is essential and we find that the added level of testing and the quality it builds into the code is not just valuable, it’s critical.
4. We can test at the end of the project
For a product that requires thorough testing, especially for a product that needs to conform to standards, testing during development saves time. Why? Because software bugs (errors) found late on in a project are more costly and can take longer to fix. This is because there might be subsequent design decisions that depended on a broken piece of functionality working a certain way, or for very complex functionality the developers will find it easier to fix a problem whilst the details are fresh in their memory and not several weeks later. To rewrite that code may require a redesign in other areas of the product, too, as well as any additional testing effort.
We still do robust manual testing at the end of every sprint, but the TDD framework helps to guide our actions and decreases the time manual tests take.
5. Test-Driven Development doesn’t help with adhering to medical standards
Two of the critical things you need for software to pass international medical standards is validation that the device works consistently as described and that you have taken every precaution to reduce risk. TDD helps address both of these requirements. The reports output as part of Test Driven Development can form part of the validation documents, creating evidence about the integrity of the software developed. Most standards require a strong link between requirements, code, and testing, so projects can benefit from having tests which self-document and verify the requirements.
More importantly for the consumer, aggressive testing also improves the quality of the project reducing risk. TDD when combined with behaviour driven development and manual testing provides good code coverage reducing the risk of bugs and improving the overall performance of the device.
Even as TDD devotees, we do appreciate that there are instances where TDD isn’t the right solution. If you’re doing a very quick proof of concept or R&D work and might drastically change the project, you may want to wait on doing TDD. It’s also not always the right approach for UX based work. However, we find for most embedded and IoT projects we work on, it’s a “must have”.
If you’d like to ask us more about our TDD based approach or are interested in speaking to us about working together, please get in touch. We are always happy to chat.