I am aware that there are many advantages of test driven software development. However, I'm wondering if there are situations in which test driven development is not appropriate or just downright not feasible.
I thought TDD would be impractical / not feasible for me in general because I am working with a 16bit uC. There is no open source test harness that directly compiles in my build environment and the proprietary solutions are pricey. The rest of my answer will be W.R.T. TDD in embedded C.
I am working through James Grenning's book and he uses cpputest and cunit for his examples. The trouble with either of these is that I would need to maintain two separate build environments - GCC+Cygwin, and then my normal build environment. My other option would be substantial reworking on a C++ test harness to make it compile in my build environment which only supports a limited subset of C++. That isn't something that would scale up very well for my team of developers.
But then I discovered how downright easy it is to just make my own lightweight unit test harness and embed it in in my projects, and away we go! I was able to make my own test harness in a couple of days that supports testing assertions by redefining the assert macro, allows me to test functions declared static, and even allows for dynamic function stubbing. My IDE can give me an idea of what my code coverage is when I run the code in a simulator so I can gauge in the simulator whether or not my bases are covered and then rerun the same tests again on the target later.
So for my application, TDD IS feasible for most of the application. However, I don't think it makes a lot sense for an INIT function where the flow of the code is completely linear, e.g. just writing constants to registers to setup your cpu clocks, uart baud rates, etc. Instrumenting a test to see if the value was written to the correct location is fruitless labor. That functionality is much easier checked on the target during integration testing. You'll know pretty quickly that your baud rate register isn't setup correctly when all of the data you're getting is garbage.
But this touches on some other techniques such as design by contract. You can put in asserts to assert that the UART buffer will never overflow or there is never a framing error. That will tell you quickly if there is a configuration problem or not when you are testing your code on the target, and it is of more valuable then knowing "I wrote this number to a spot and read back what I expected from some other spot". You'll actually be verifying your configuration's correctness, rather than whether or not you were able to write something to a memory address.