Friday, January 6, 2017

Does X Make You Successful?

I was recently asked to complete a survey about Test Driven Development. After looking through the questions, I found that I couldn't really answer them.
  1. In how many projects did you use TDD?
  2. Was TDD successful in at least 50% of the projects?
  3. Did TDD delay the release date of the projects?
  4. Describe the advantages you realized after using TDD.
  5. Describe the disadvantages you realized after using TDD.
  6. Did the software maintenance decrease after using TDD?
The questions are fair questions, and the survey was put together by an engineering student (and I love that he is reaching out to people to ask about their experiences). The problem I had in trying to answer the questions is that it's hard to take a single practice (such at TDD) in isolation and credit success/failure/maintenance costs to that one thing.

I'm not much of a TDDer myself. I'm a huge believer in unit testing, and I'm convinced that Unit Testing Makes Me Faster. But I'm more of a "test along side" developer, where I'm writing code and writing tests more-or-less together. I don't strictly follow the red-green-refactor cycle, and I don't mandate 100% code coverage in my projects.

Note: If you're curious about my unit testing talk, you can see a recording from Visual Studio Live! from last May.

You might ask why I have videos showing people how to do TDD if I don't use it widely myself. That's mostly environmental. Based on the types of applications I've been building and the environments I've been working in, TDD hasn't been a the the best fit (although I'm sure there are those who disagree with me). But I have seen TDD be an extremely useful tool in a lot of circumstances, so I want to encourage people to explore it and help them get over some of the roadblocks that might stop them.

Other Factors
The problem with trying to isolate success to any one practice (whether Agile, Scrum, TDD, CI/CD) is that there are always other factors that influence success or failure.

Specifically with regard to TDD, I've seen teams fail horribly using it. I was a bit outside of these groups, and TDD was not the cause of their issues. There were issues with the management not trusting the developers. There were issues of mandating tools and processes that the developers did not believe in. There were issues around team dynamics and trust.

So there were projects that failed while using TDD. But I would not attribute the failure to TDD.

On the other side, I have a good friend who is a huge TDD proponent. He has been very successful using it, and he helps other people understand it and be successful with it.

I also know a company with a very successful development department. They have several teams that all build code using TDD. But they also have good team dynamics, trust, and a learning mindset. They are always looking for ways to do things better, and they are not afraid to discard things that don't work in their environment.

Isolating Success
The gist of this is that it's really hard to isolate what makes us successful.

I've heard people say, "Once we went to CI/CD, we saw X improvement [in speed / cost / maintenance]." But it's really hard to credit that to Continuous Integration/Continuous Delivery only. That's because most teams are not ready to simply flip the CI/CD switch.

To get to the point where we can be successful with CI/CD, we need to have good automated testing in place, we need to have good source control, we need to have good branch/merge practices. Then we can get to automated deployments. So even if we can make our users happier once when we have CI/CD in place, our success is really attributable to the other factors as well.

Continuous Improvement
One thing that I emphasize when I'm encouraging people to include unit testing in their environment is that it takes time to learn something new. It's not something that we will be instantly productive with.

With any process, framework, library, or language, we go through 3 phases:
  1. Learning the technical bits
    This is where we get the basics about how to install tools, what commands are available, and how to get things working from a technical standpoint.
  2. Learning the best practices
    This is where we look for experience and advice from other people who have used this tool. We can see what worked for them and what didn't work. And this gives us a good place to start in our environment.
  3. Learning how things fit in our environment
    This is where we see what works in our own world. The best practices that we picked up from other developers were things that worked well in their environment, but that doesn't mean they will work for us.
Once we get through phase 3, we can be really productive with this tool. We've figured out how it can really help us, and we're comfortable using is effectively. (And we may not get to phase 3 if we find that the tool really doesn't fit in our environment.)

There is No Silver Bullet
There is so single tool or practice that will make us successful. I've seen teams using Agile fail and I've seen teams using Agile succeed (and I won't get into the "you're doing it wrong" discussion here). I've seen teams using TDD fail, and I've seen teams using TDD succeed.

My biggest frustration was watching a group that was really broken. The management didn't trust their developers and so they tried to come up with the one process that would ensure that every project would be successful. But there is no silver bullet. And every 6 months, they would give up on what they were doing and try another process to ensure success. Over the course of years, I saw each of these processes fail.

There was nothing wrong with the practice or process they chose. And the practice was not the cause of the failure. We need to look beyond any particular practice and talk about what makes up a productive team.

Asking the Right Questions
Programming practices come and go. Programming languages come and go. Programming frameworks come and go. Each of these can be useful tools in the hands of good developers. And they can also be used to create complete disasters.

We need to think about the questions that we ask about any of these tools.
What problem is this tool designed to solve?
Do I have this problem?
There was a time in my career where I did an analysis of the MVVM design pattern, and determined that it was not appropriate for our environment. Of the 3 problems it was designed to solve, we had already solved 2 of those problems another way, and we didn't have the 3rd problem. Since then, I have used MVVM quite successfully in a lot of other environments. But we do need to stop and ask those questions.

So rather than asking if a particular tool or practice makes us successful, we should be asking "What problem is this tool designed to solve?" And of course, "Do I have this problem?"

Happy Coding!

No comments:

Post a Comment