Main menu

Post navigation

About jwgrenning

Hi
I've been developing and managing software for decades now. Starting in embedded, but doing more than embedded. Many of the mainstream software development techniques have crossover value to embedded. My mission is to spread some of those techniques to the embedded community.
My company is
Wingman Software.
Please visit my site.

A recent TDD for Embedded C attendee asks me “TDD does not help reduce the time I spend in the lab during system integration testing”

(This is asked in the context of embedded development. But the answer is half applicable to any development where there is integration.)

TDD should definitely help reduce the time you spend in integration. How does it do that? It helps you eliminate the non-integration problems before you get to the integration lab. An honest appraisal of what you do in integration may reveal that during integration you are finding problems you could have discovered before integration. It would help reduced integration time if you find fewer problems during integration. Don’t you think?

This cause/effect diagram helps to visualize the relationship of TDD to time spend in integration.

Another attendee of my training tells me “The quality of my application is exceptional, adding TDD is an overhead that brings no added value.”

You statement makes me ask a few questions. How did you get the exceptional quality? Is your application finished? Will it be changed? How do you plan on maintaining exceptional quality?Continue reading →

One of the attendees of my training objected to TDD stating “TDD does not resolve the real-world (temperature, pressure, timing, noisy signals, etc.) issues that my project is encountering.”

You are right! I’ll add TDD does not resolve anything. TDD is not a magic incantation that solves any problem the embedded developer may encounter. From discussions at your company, I think you realize this. But it does not change the fact that you have to spend a lot of time chasing these kinds of problems. So let’s see how TDD can support this activity.Continue reading →

I’m going to bend the example a little, and look at how to write tests that interact with an interrupt service routine and again with a semaphore. I’ll also get some help with the tedious parts of building fakes by using Mike Long’s Fake Function Framework. (BTW: I am using a beta version, that has changes the released version does not yet have.)

This figure shows the concurrent runtime relationship between the MessageProcessor and its SerialDriver.

In the last article, the OSSemPend() test-double was coded to handle a specific OSSemPend() application and test need. The semaphore was being used to signal when there is a message to process. It was the first need for a OSSemPend() test double and was quickly developed. As more RTOS dependent code is brought under test, a more general solution will be needed.

In this article, we’ll look at a test double that can be customized for each application.Continue reading →

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.

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 →

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 →

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.

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 tested automatically. 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.