11

I'm considering writing a low level driver or OS components/kernels.

The osdev.org folks seem to think that the important bits are not meaningfully testable this way, but I have read some discussions where people thought differently. I've looked around, but have failed to find any real life examples of TDD on low-level components.

Is this something people actually do, or just something that people talk about in theory because there is not a good way to do it in practice?

3
  • If just MS provided the kernel developers with appropriate "kernel mocks" (or whatever it could be), the practice in question would not that "imaginative", I think.
    – mlvljr
    Nov 10, 2010 at 15:37
  • Hi @Bill - I've rephrased your question a bit and have voted to reopen it. If I've changed it too much from your original intent, please feel free to edit further or revert the question :)
    – Rachel
    Jan 3, 2013 at 17:28
  • Says the same thing from my point of view - no Worries
    – Bill
    Jan 3, 2013 at 20:21

3 Answers 3

3

If you're interacting with or controlling hardware, then it's difficult to test without it. You can try emulating the hardware, but that's often more difficult than writing the driver in the first place, so you wind up not knowing whether the bug's in your driver or your emulator.

9
  • 1
    And why not test the emulator then? ;)
    – mlvljr
    Nov 10, 2010 at 17:22
  • @mlvljr: because emulators aren't the real thing. there is no substitute for real hardware. Nov 10, 2010 at 17:25
  • @mlvljr You'd also need to test the emulator against real hardware, using test suites created to test the original tests for... wait, where am I again? Nov 10, 2010 at 17:34
  • So, vmware and alikes cannot be tested then?
    – mlvljr
    Nov 10, 2010 at 17:44
  • 1
    @mlvljr: It's a valid point, but I think it falls outside the realm of "TDD". Not many developers have access to a scriptable, instrumented system-level emulator. I felt lucky to have a four-channel scope!
    – TMN
    Nov 10, 2010 at 18:54
3

I personally tend to believe one can get many of the benefits of TDD (without actually adhering to TDD), by:

  • Writing both the caller and the callee code at around the same time (definitely not more than 24 hours apart).
    • And use that to influence the design of the interface (objects, method calls and parameters).
  • For a component requiring a complicated algorithm/code, strongly consider implementing in a simpler but correct algorithm first, even if it is less efficient (or stupid, or only works in a narrower situation).
    • A very simple testing method would be running both algorithms and comparing their results.
  • Once a bug was discovered (by any means) in one part of the code, that part of code deserves to be tested much more aggressively. This means doing more sophisticated tests than TDD would call for. (based on the reasoning that bugs occur in clusters)

TDD seems to require you to have a pretty clear understand of what function you plan to implement, or what requirements you plan to satisfy by implementing the code. In some situations, there is simply too little understanding of the problem. This would have called for a Spike solution. Within the scope of this Spike solution, TDD can be applied because the problem has been narrowed down to a managable level. Once a few Spikes have been finished, each covering some aspects of the original problem, one can start working on the full solution, and applying TDD at that point might be feasible because of the improved understanding.

Edited:

After reading the page more carefully,

While it should be possible to test most kernel functions in a "testbed" test driver, the really "juicy" stuff like interrupt handling, process dispatching or memory management are probably not unit-testable. --- from http://wiki.osdev.org/Unit_Testing

They are clearly saying that most parts are testable, and that some parts require a different kind of testing: Stress Testing.

2
  • it is also implying that the important parts are the parts that require different testing imho.
    – Bill
    Nov 15, 2010 at 15:50
  • what an awesome answer! in some many levels cheers! Jul 25, 2014 at 13:11
1

I don't. In my Master's embedded code I just write the code and spend my time reasoning about what it does (and doesn't). I'm not sure it could be done in my case anyway, I'm getting disturbingly close to the physical limit of memory without injecting testing code.

I think that for systems that are large enough (ie have MB of memory, not KB), it can be done for some components if you have enough time and effort. Testing pin-reading code by mocking the pins up is...er...not very meaningful. If you've separated your logic out enough, you can test the logic elsewhere.

FWIW, I don't buy TDD in the general case - it works fine for system stacks that are large enough with enough resources with enough deterministic behavior, outside of that it doesn't seem reasonable practice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.