Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question
    
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 '10 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 '13 at 17:28
    
Says the same thing from my point of view - no Worries –  Bill Jan 3 '13 at 20:21
add comment

3 Answers

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.

share|improve this answer
    
And why not test the emulator then? ;) –  mlvljr Nov 10 '10 at 17:22
    
@mlvljr: because emulators aren't the real thing. there is no substitute for real hardware. –  Paul Nathan Nov 10 '10 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? –  Note to self - think of a name Nov 10 '10 at 17:34
    
So, vmware and alikes cannot be tested then? –  mlvljr Nov 10 '10 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 '10 at 18:54
show 4 more comments

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.

share|improve this answer
add comment

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.

share|improve this answer
    
it is also implying that the important parts are the parts that require different testing imho. –  Bill Nov 15 '10 at 15:50
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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