• Articles
  • Ceedling Book
  • Eclipse Toolkit
  • About
Menu

ElectronVector - Test-First Embedded Software

Better embedded software
  • Articles
  • Ceedling Book
  • Eclipse Toolkit
  • About

Get your free guide: How to use Ceedling for embedded test-driven development

Why I Like to Write the Tests First

August 5, 2015

A Case for Test-Driven Development

If you're on board with unit testing, but not quite sure about test-driven development, I want to share my experience for why I think writing the tests first is the way to go.

You can't write "un-testable" code

It is certainly possible to write code that is difficult or impossible to test. This is especially a problem if you're not thinking about how you're going to test your code as you're writing it.

There are design strategies that you can use to avoid creating un-testable code, but these take experience to know when to apply them correctly.

Writing the tests first forces me to think about how to test my code as I'm writing it. The strategies for making the code testable emerge naturally each time I decide how to write the next test.

It simplifies implementation

Sometimes when I'm faced with implementing a new software module, it can be a bit overwhelming to figure out where to start.

A traditional approach would be to create some sort of design plan upfront and then implement it. However, maintaining the mental model in this approach produces a high cognitive load. It can be hard to keep track of everything in my head.

And... what if something changes as I go along? Maybe I realize that it really shouldn't or can't work that way for some reason? It's more painful to change course.

When I'm test-driving, I let go of that mental model and ask what is the very first, simple thing I need this module to do? It could be as simple as testing some initial value, but it's important and it's a good way to start. Then I write a test that describes the behavior and I implement it.

I just repeat this process over and over, each time asking myself what is the next thing this module needs to do? And, each time I add functionality with a new test I know if I everything I've already done is working because of all of the tests I've created along the way.

I've just taking a large problem and broken it down into a series of simpler, actionable tasks. This is a lot easier for my brain to handle.

You only implement as much as you need

It's easy to want to go off and crank out a lot of code all at once (without tests). But if you do that it might not be clear if all of that functionality is actually needed.

Test-driving forces me to be clear about every piece of functionality that is being implemented.

Each time I write a test I try to only write enough code to pass that test. When I do this, I know that I'm doing exactly the right amount of work to get my software to behave how I need it to.

This gives me confidence that I'm not adding any unnecessary functionality. There's a lot less risk that I'll go and do a whole bunch of extra work. And I'd prefer not doing extra work.

So, I suggest that you try writing the tests first. That is, of course, unless you like writing un-testable code, making things more complicated or doing more work than you have to.

Okay... it's actually a little more work to make the switch to writing the tests first. Once you get the hang of it, though, it'll save you time and effort in the long run.

← Slicing Embedded Software for Continuous DeliveryA Test-Driven Development Environment for the Tiva C Series Launchpad →
Matt Chernoksy

Matt Chernosky


book-3d.png

Need more help with Ceedling?

A Field Manual for Ceedling is filled with examples for how to write tests (and create mocks) for your embedded software.

Get the Book

Add unit tests to your current project with Ceedling

Try embedded TDD right now with Ceedling

Mocking embedded hardware interfaces with Ceedling and CMock

CMock vs FFF -- A comparison of mocking frameworks


Don't miss a post!

Sign up here and I'll keep you in the loop.

ElectronVector