Search code examples
tddhardware

How to do TDD with hardware


All the projects I work interface to a piece of hardware and this is often the main purpose of the software. Are there any effective ways I can apply TDD to the code that works with the hardware?

Update: Sorry for not being clearer with my question.

The hardware I use is a frame grabber that capture images from a camera. I then process these images, display them and save them to disk. I can simulate all the processing that takes place after the images are captured by using previously captured images that are stored on disk.

But it's the actual interaction with the hardware that I want to test. For instance does my software cope correctly when there isn't a camera attached, does it properly start and stop grabbing etc. But this is so tied into the hardware I don't know how to test it when the hardware isn't present or if I should even be trying to do this?

2nd Update: I'm also looking for some concrete examples of exactly how people have dealt this situation.


Solution

  • Split your test suite into two parts:

    1. The first part runs tests against the real hardware. This part is used to build the mockups. By writing automatic tests for this, you can run them again if you have any doubts whether your mockups work correctly.

    2. The second part run against the mockups. This part runs automatically.

    Part #1 gets run manually after you made sure the hardware is wired up correctly, etc. A good idea is to create a suite of tests which run against something returned by the factory and run these tests twice: Once with a factory that returns the real "driver" and once against the factory of your mock objects. This way, you can be sure that your mocks work exactly as the real thing:

    class YourTests extends TestCase {
        public IDriver getDriver() { return new MockDriver (); }
        public boolean shouldRun () { return true; }
        public void testSomeMethod() throws Exception {
            if (!shouldRun()) return; // Allows to disable all tests
            assertEquals ("1", getDriver().someMethod());
        }
    }
    

    In my code, I usually use a system property (-Dmanual=yes) to toggle the manual tests:

    class HardwareTests extends YourTests {
        public IDriver getDriver() { return new HardwareDriver (); }
        public boolean shouldRun () { return "yes".equals (System.getProperty("manual")); }
    }