Rob Myers on Using TDD with Enterprise Development
Noel Wurst: Hello, this is Noel Wurst, with Skytap, and I am interviewing Rob Myers today. Rob Myers is an Agile coach and instructor and also the founder of the Agile institute. How are you doing today Rob?
Rob Myers: Good. How are you?
Noel Wurst: Great, doing great. I interviewed Rob about a year ago, and I was excited to get to interview him again. I’m going to be talking about test-driven development today and how it relates to enterprise software development as well.
What I think is really funny is that when I look online to learn more about TDD—it is incredibly simple, or it sounds incredibly simple. You write a test that fails, you write the code that passes that test, refactor it incrementally, and then repeat. What’s funny is that you also see people talking about about why it’s so difficult. I was curious as to why is it such a simple thing to do, yet why is it so difficult to do it sometimes?
Rob Myers: Yeah. Interesting question. There is a couple of things that come to mind that are probably making it more challenging for people. One of them is that it is a discipline. It requires a lot of care and attention, so to speak. I think that what we have to see with any discipline, our human nature comes into it and we want to take the easy route, right? The only way that we can discover that TDD is the easy route is to work on it for at least a month, that’s one of the things that I think happens is that people get discouraged before their thirty days are over, before it’s become a habit before they have seen that there is some kind of long term benefit.
Now, by long-term benefit, that varies, too. I have seen situations where benefits to the organization are tremendous but they don’t occur for maybe four to six months. Then I have seen cases where developers discover that the test-driven development is very valuable to them within hours. It varies.
Noel Wurst: Wow. I guess that’s a testament to Agile’s track record as far as success goes because people do always want the easy way out yet there is really nothing all that easy about Agile.
Rob Myers: Right. I think in the long run, it’s actually easier, but what it does is it takes the stresses of the crunch that usually happened at the end of the cycle of building a software release and spreads it out over time. You are effectively working harder at the very beginning of a release than you normally would because you are waiting for other people to do other things and now you are working on everything the same way you will be at the end in a continuous fashion where we find is that when we look back, it’s actually been a much easier release.
Noel Wurst: That’s interesting.
Rob Myers: The other thing that I think is a really big challenge, is that I find that I teach a lot of test-driven development courses and people are really excited about that and at the end of their course, they’ll come up to me and say, “This is just wonderful stuff. It’s too bad we can’t use it, because we have three million lines of legacy C# code,” or something like that.
So, the legacy code problem is probably the other thing that’s impeding them. And it’s not the case like some people would like to say, that you can just do TDD on your new behaviors and leave your old behaviors alone. Software doesn’t work that way, right? It intertwines, so you have to do some sort of characterization testing on your legacy code and maintain that in a strategic way.
Noel Wurst: Speaking about intertwining, we are all big fans of continuous integration here, and I was curious as to with the kind of like that fast nature an incremental approach of TDD, is it easily I guess introduced alongside other Agile practices like continuous integration?
Rob Myers: Yeah. In fact, I would have to say that test-driven development and continuous integration go hand-in-hand to the point where if you don’t have continuous integration then you are pretty much doing test-driven development on your own.
It’s not all that strong, especially if you are working on a team, and then continuous integration without some kind of safety net or tests created by a test-driven development, or tests that run that fast, then continuous integration is really ineffective, right? What you are doing? You are just dumping stuff into repository and it compiles, great. If it doesn’t pass the tests, then it’s not good and if your tests don’t run fast, you’ll not integrate as often.
Noel Wurst: Right. You mentioned earlier, as far as some issues dealing with legacy code— How about using TDD on enterprise level projects? Is there anything overly beneficial to using TDD in that kind of development.
Rob Myers: I think so. There are a number of different things when people talk about enterprise software that come up for a test-driven development environment. One of the things I think that they are saying is “our software is very complex, our software is very large.” What test-driven development does, is it it forces you to think in small steps, but also to leave behind something that checks to make sure that investment that you’ve made in a small bit of software is still good. It’s actually easier to expand the abilities of your software using something like test-driven development than it would be otherwise. That’s one aspect.
One of the other aspects is that, again, going back to the legacy code problem, a lot of enterprise applications have a lot of legacy stuff that’s embedded in weird places like hard to test places like database-stored procedures, for example, and you end up with the whole legacy code problem that’s slowing you down.
Now, you can’t really suggest that test-driven development should be able to solve problems that it isn’t designed to solve. It’s really effective when you are building a new product, or when you are building new features. If you could start all over again, great, or if you are starting all over again or otherwise you are doing characterization testing.
Noel Wurst: Right. I know it’s good in those incremental approaches, and at the beginning, so obviously it deals a lot with unit testing. Are there some other types of testing that TDD can be used with as well?
Rob Myers: Yeah. Test-driven development comes from two of the original extreme programming practices that were called “test first” and “merciless refactoring.” And, in fact, there are people out there who will refer to test-driven development as “test first” to make sure that they are clear about when you are writing the tests.
And then what can happen fairly quickly … I can’t recall a time … maybe 1998 was the last time when I thought about or talked about extreme programming without the idea of doing acceptance testing. You can do acceptance test-driven development using a lot of the new tools as well, where you write the acceptance test, also known as story testing or sort of the BDD. The behavior-driven development number is strange and anamorphous. People argue about what it means, what’s under the umbrella, and I don’t know if we want to get into that discussion, but me, I say, “Okay I’m going to just distinguish between TDD and acceptance testing,” in that case.
Acceptance testing is one of those things, and also James Shore, author of “Art of Agile” had this comment about what he called focused integration tests which is essentially making sure that when you are actually doing integration with something like a database that you are testing in a focused way, so that you can actually use that database in the appropriate way. Doing simple crud tests and maybe testing your behaviors, and your code around how it interacts with that.
Noel Wurst: Finally, just as we are talking about test-driven development, let’s maybe talk a little bit about who is actually using it, who is actually putting it into play. I found a debate online about whether testers or developers should be the one writing the unit tests in TDD and I saw someone say that people shouldn’t forget what the D stands for, “development.” They said, “this is the developer’s job, plus it helps them focus on writing better and cleaner code.
But then on the other hand, people who are referencing the benefits of collaboration say that testers should be involved in writing those tests. I was curious whether you thought it should be one or the other, or both, and if you do think it’s the developer’s job what’s something that testers could be doing during that time that would be a good use of their time?
Rob Myers: Wow. Yeah. You are putting me on the stop here and we could probably have a whole conversation.
Noel Wurst: Yeah, about five questions inside that last one!
Rob Myers: Yeah. It’s a really good topic, too. There is really no one right answer. Should your test-driven developers be pairing on the tests, should your testers be … I would say that the unit testing is so different from the other forms of traditional testing. In fact, Ward Cunningham, at one point said, “Test-first is not a testing technique.”
What he means by that is, “testers do testing things.” I’ll talk a little bit more about that in a minute, but, developers are using test-driven development to craft their code and the testing is a very important secondary effect of that, right? When the test passes it becomes a test, and, effectively, what they are doing there is they’re really, it’s a thinking process.
They are expressing what it is that their code is supposed to do, and therefore, they are getting instant feedback about when it is working, and then they can set it aside and move on to something else. There is a whole thought process that goes into test-driven development from a developer’s standpoint.
Now, having them pair with somebody who is a tester—I can see how that’d be a very valuable at some levels to make a developer a better tester, and to make a tester see what kind of tests, and to have some confidence in the unit testing.
There is something that is very interesting that’s occurred to me over time and it occurred to me when I learned about one of the testing techniques known as “pairwise testing” that professional testers use. What it is, is that if you’ve got a complex system and you’ve got, let’s say you have two variables, and the variations for each of those variables, maybe one of them is 1 to 10 and the other one is A to Z, right?
You’ve got, I don’t know how many combinations of possible combinations you have there, but what you do with pairwise testing is there is some sort of mathematical way that you chose which of the pairs you are going to test, and, it gives you a 98% confidence level that you’ve tested all of the code paths. That’s really neat.
The problem is that, it’s speeding you up because you are not testing all the combinations. The problem is that, from a unit testing stand point, from a developer stand point, what I’d actually like them to encourage is to break the dependencies between those two independently varying variables in such a way that their unit testing the alphabet over here, and their unit testing the numbers, or whatever they are, right, and therefore they are breaking the combinations up, so there are no combinatorial explosions.
In that respect, developers are effectively testing 100% of the behaviors with quite a bit fewer tests. They are not testing at any other higher level. They are testing their code right there as close to the code as possible. In fact, the unit testers representing the other object that’s going to be delegating to that object. It’s a very different type of testing and I know I’m going on and on about …
Noel Wurst: No. I was just going to ask you, I didn’t hear what you said at the very beginning, is that something that you are seeing currently being done or something that you’ve come up with recently or thought about recently, and you’re envisioning that this could be really beneficial in the future?
Rob Myers: I think people have been doing it, when they are doing test-driven development, and they are doing it conscientiously and mindfully, I think they are going to discover … they are probably not really doing it consciously but they are probably discovering that their objects are small and concise and very cohesive about what they do. And good objects are easy to unit test, and bad objects are not. And if you just take that feedback of, “it’s hard for me to write this test, maybe something is wrong here,” what you end up with is a very nice design that’s easily testable and everything is testable.
I think it’s just more of a looking back on what we’ve been doing over whatever 15 years. I think that we’ve been doing that when we do it well, and it’s a good thing for people to think about. It’s something I teach in my courses. I talk about this very thing because it’s important for them to realize that the minute that they are testing two objects instead of one, there is a combination that could happen and it could blow up in their face. They need to make things very small.
Noel Wurst: Oh wow. That’s really fascinating.
Rob Myers: The reason why I actually had to start thinking about that was because I ran into some clients who, there is the old school of thought that developers shouldn’t test their own code. They should write the code and then a tester tests it. There is an old joke, and it’s actually, coming from a developer background, it’s sort of a self-effacing joke, but it actually has some truth to it. The joke is that if a developer was going to build a bridge and was then going to test the bridge—he would wait until a nice sunny day, drive a single car down the middle, and call it good.
Now, there is some truth to that, but what you have to recognize, is the reason why the developer doesn’t want to test the edges is that he doesn’t want it to break. He is already done building it. Right? Now, if you give a developer the opportunity to say, “what kinds of things would you like to have tested in your code?” They will come up with an immense number of things, and they’ll be very comprehensive about it. What we are doing is we are actually giving them a game that they can play with the code where they are testing it and building it all along. They are actually encouraged to come up with whatever tests they think of. That breaks the joke.
We as testers, and to get back to your question, that leaves testers with other things to do like building acceptance test-driven development, story testing sometimes and also, one of the things that I definitely don’t want to discourage, or belittle, is that testers need to have the time to do exploratory testing.
It’s so important and sometimes it gets missed when people talk about Agile testing, but it’s there in Agile testing. You need to have the time to do exploratory testing, which is manual but not scripted, right? There is a session but you are not just pointing and clicking based on a script. The computer can do that. It’s thinking.
Noel Wurst: Right. That’s really cool. I think that was a great way to wrap it up and thank you again for speaking with me today.
Rob Myers: My pleasure.
Noel Wurst: Everybody, this Noel Wurst, with Skytap, and I have been speaking with Rob Myers who is an Agile coach and trainer, and also the founder of the Agile institute. We should do one of these yearly or so, to check up on TDD and see who is using it more and more, and see if you can track any trends on whether it’s developers or testers or both.
Rob Myers: Sure. Where it’s going.
Noel Wurst: Right. Thanks so much.
Rob Myers: Take care. Bye.