Unit testing RTOS dependent code – RTOS Test-Double

When you’ve got legacy code that depends on the Real-time Operating System, you have a challenge to get your code off the target for unit testing. If you want to test with the concurrency provided by the RTOS, these are not really unit tests, and you won’t be able to write thorough tests, and you need unit tests to be through.

You’re going to need to make a test-double so you can get your code off the RTOS and into your development system for unit testing. In this article we’ll go through the steps to get started.

Continue reading

Code Coverage’s Mixed Message

I’m in agreement with Robert Glass when he says “100% test coverage is insufficient. 35% of the faults are missing logic paths.” It’s not controversial, but I’d like to give my perspective on it.

If you have an automated unit test suite, low code coverage is an indication that you need more tests. Unfortunately, high code coverage does not tell you if you have enough tests or the right tests. Adding to Robert Glass’ observation, executed code is not necessarily tested code. Imagine a test case that runs through many lines of code, but never checks that they are doing the right thing. At best this is the “I don’t have any bad pointers” test.
Continue reading

Hiding Non-standard C Keywords for Off-Target Testing

Some silicon vendors extend the C language so the programmers can easily interact with the silicon. Using these extensions tie production code to the silicon vendors compiler and consequently the code can only run on the target system. This is not a problem during production, but is a problem for off-target unit testing.

The good news is that we may be able to get around this problem without having to change production code, one of our goals when adding tests to legacy code.
Continue reading

#include Test Double

It’s day one of adding tests to your legacy C code. You get stopped dead when the compiler announces that the code you are coaxing into the test harness can’t be compiled on this machine. You are stuck on the Make it compile step of Crash to Pass.

Moving your embedded legacy C code (embedded C code without tests) into a test harness can be a challenge. The legacy C code is likely to be tightly bound to the target processor. This might not be a problem for production, but for off-target unit testing, it is a big problem.

For C we have a limited mechanisms for breaking dependencies. In my book, I describe at length link-time and function pointer substitutions, but only touch on preprocessor stubbing.

In this article we’ll look at #include Test-Double as a way to break dependencies on a problem #include file.

Continue reading

Manual Test is Unsustainable

Creating automated tests can be very difficult, especially when the code has gotten long in the tooth and was not created with automated tests to begin with. Many product development teams don’t invest in automated tests. They think they cannot afford them. They think their product is different and can’t be manually tested. This thinking is flawed.

Back in the products younger days, manual test was not too time consuming. But slowly that changed. The system grows, the manual test effort grows. Eventually, it seems that no amount of manual test effort finds all the problems.

In this article I show a simple model that illustrates why manual test is unsustainable and that a sustainable software product development effort must include considerable test automation.

Continue reading

The Careful way is the Fast Way

After the Agile2011 conference, my wife and I took some great hikes in the mountains of Utah. We were careful as we navigated the slot canyons, rushing streams, and falling water. We were careful, we did not want a mistake to cause an injury; but we have no fear of height and love adventure. After a few days of hiking, our skill grew and we worked the terrain more quickly and safely.

I’ve described TDD using the analogy of stepping stones to cross a river for years. Here’s a Utah stream coming from a slot canyon.

You can see there are a few ways across. It’s not a straight path, but with a few careful steps you get to the other side, keeping your shoes dry.

Over several days of hiking, I discovered another metaphor for TDD, often thought of as a very careful way to program. The careful way is the fast way.

Continue reading

Spying on Embedded ‘asm’ directives

Sometimes embedded developers have to use inline assembler instructions to get better control of the processor, or to improve performance. How should we deal with those when we’re doing TDD and testing off the target?

What’s the problem? The embedded asm statements cause compilation errors if the assembler instructions are not part of the off-target test platform instruction set. Also some of the instructions might not be legal in the test environment. This article shows how to insert a test double for the asm directives with gcc and CppUTest.

Continue reading

Test Before or Test After, that is the Question

In Jeff Langr’s blog, Jeff responded to an assertion (from someone Jeff calls Schmoo) that writing tests after developing a unit of production code takes less time than using TDD to create production code and its tests. For starters, I am happy the discussion is about when to write the unit tests and not if.

I think a model would help us talk about this issue. It would be great to have some real numbers in the model; that will be hard. But for starters let’s look at a model. Maybe then someone can figure out how to put some numbers to the model.
Continue reading

Legacy Code Change – a Boy Scout Adds Tests

Here is a legacy code change policy for a team adopting TDD that has a legacy code base:

  • Test-drive new code
  • Add tests to legacy code before modification
  • Test-drive changes to legacy code

Refactoring without tests is dangerous; with all the details we must keep straight, a mistake is easy to make. How many code reviews have you been in where the recommended design changes are not made because “we already tested it”? You avoid the change because it’s dangerous to change code without tests. So, the Boy Scout adds tests too. For more on Boy Scouts, see previous post.

Continue reading