Why TDD Isn’t Working

Test driven development is a different way to think about the design, development, and maintenance of applications. It makes it easier to make larger changes to applications without worry about breaking things, makes it easier to get going and keep going while writing code, and can even decrease the rate of errors over time as an application evolves. In general, TDD will result in cleaner, less coupled code, much faster testing, and a more stable application overall. That is, if you can get past a few things that tend to trip people up.

TDD can work well for you, but it’s easy to go off the rails, especially with the kind of examples you see on the web. The basics are easy, but it can be tricky to get right. It takes a while to learn all the hard lessons of TDD, but the goal is ultimately worth it. Even worthwhile goals require that you survive until results happen.

Episode Breakdown

11:25 You aren’t giving your team time to adjust.

There is a huge change in headspace between TDD and non-TDD development styles. The difficulty is more like changing languages than changing frameworks. Not everyone learns at the same rate, which will also increase inter-team friction. Buy-in can be very difficult to attain from team members that are set in their ways.

“I figure that if the database is right, I’m pretty OK.”

In regular old development, you just start going the direction you are trying to go. In TDD, it’s more like trying to figure out what constitutes going the wrong way, and then testing for that to drive things in the right direction. As a result, you and your team will not instantly be as “productive” with TDD as you are with standard development, at least for a while.

Don’t try to do this during crunch time; it won’t help. You don’t want to damage team performance at a critical time – this will cause management to not only dislike the idea, but dislike it forever. Tests are added work and your team really needs to have their early experience with them without the imminent threat of a deadline.

20:15 You are listing “testing” as a separate task, either in your project management system or on invoices.

Testing is not a line item. Sort of like how “compiling” is not a line item. It’s critical and part of the process. This reflects that testing is optional or is an afterthought. That’s the wrong way to message testing to stakeholders.

“It’s a given fact we are going to write unit tests.”

You don’t want a debate with management/clients about whether you should do testing or not. You are a professional, making a good salary in a field that can be challenging. You don’t tell your doctor or mechanic how to do their job, because you trust them to do it. You should cultivate the same from your boss/client, for the same reason.

Making testing appear optional means that it will be understood as optional. This means that other people will decide that they don’t want to pay for testing. However, not paying for testing doesn’t mean that they want an untested product – it just means you do it for free.

24:25 You are trying to test too much of a legacy system on the first try.

If you are trying to retrofit tests onto a legacy system (while doing TDD on anything new), you’ll need to understand that it can take a while. Legacy code is nasty to test and not typically built for testability. It’s hard to convince people to test a system that they believe already works.

You may need to tease apart pieces of the legacy system in order to actually write good tests. This can be harder than it sounds, especially if you have to mock a database or other complex system. You may have to accept some compromises from “pure” TDD and unit-testing, just to get tests in place.

“You want to have as few variables that you don’t control as possible.”

This isn’t TDD, but it’s more likely to be your experience than not. Most of the time, you don’t get to do total green-field development. Tests of the legacy system will need to evolve alongside tests of new development for many reasons.

28:50 You aren’t testing enough things or are testing the wrong things.

You should probably try to test the easiest stuff first and get coverage. Your goal is to quickly get things to the point where tests provide value. Once good testing is shown to provide value, it’s easier to get away with doing more of them. You are better off testing one section of the code well than testing all of it poorly.

It’s best to test things where the code is already clean first. These tests can get you used to testing legacy code, with less risk. They can also help you sanity check adjacent modules when you expand your tests.

“Test the code you write”

Don’t test stupid things, like framework code. You shouldn’t test things like property setters when there is no logic behind them. It’s important to prioritize fixing things that you are likely to break.

31:50 You aren’t really doing TDD.

“That sounds like a ‘No True Scotsman’ argument.”

TDD means you write the tests first. Trying to write large chunks of code and then adding tests is going to get you into trouble. This is a habit I see from people who aren’t used to testing. It gets you into trouble, because you aren’t used to writing testable code.

“Hey, it worked when I tested it in production.”

You can also get into trouble by being too rigid about how you structure code. The tests will force changes in the way you code. You have to accommodate these. You have to structure code so that you are actually testing what you think you are testing.

34:50 You are testing across system boundaries when you should test contracts.

There are some things that are really hard to test. It’s difficult in code to prove that something is displayed on the screen. You CAN, however, test most of the things up to that boundary.

There are some things that are out of scope of testing because they aren’t your system. For instance, running automated tests regularly against a third party system could be expensive. In addition, they may not give you a test system. This is also a bit rough for a unit test, as someone else can break your stuff.

You want to test that you sent what expect to send in a given situation. Usually, this means mocking whatever thing is sending the payload, rather than actually sending it. This doesn’t mean you shouldn’t have a suite of sanity checks for going across the boundary.

41:05 You are trying to do it without approval.

“I know it’s best practice…”

It’s pretty hard to swap over to a TDD approach to development without management approval. You might be able to do it in small doses here and there, but doing it over an entire app is tricky without management approval. TDD is a lot of work, and schedules will slip if they were built with the expectation of not doing TDD, at least until you have sufficient experience. This can make you look slower than your coworkers.

There’s also a risk if you get caught. If you are doing what management thinks is “unnecessary” work, you can end up in trouble or even fired. It happens less now than it used to. Getting caught can also cause management to be reluctant to allow TDD later on. If you’ve advocated for automated testing (or even TDD), you know exactly the look that a manager gets who has experienced unsolicited and unauthorized TDD on their team before, usually by someone practicing resume driven development.

IoTease: Article

Automated Testing for the Internet of Things


Testing code in a production like environment has become an integral part of development. This article talks about various approaches to testing the hardware and software in IoT. First it talks about why it’s hard to test Internet of Things applications then goes into specifics of testing. The article includes information on tools such as virtual environments and emulators.

Tricks of the Trade

Personality defects aren’t “just how you are” and they aren’t excusable. The same is true for others. You are making it worse by pretending like it is.

Tagged with: , , ,