Despite the invention of so many different types of software testing methodologies, many in the industry are still sticking to the tried-and-true method of test-driven development, or at least some form of it.
“Like any other methodology, I think there seems to be some pretty significant variations between TDD as it’s described in books and what’s actually practiced,” said Rex Black, president of RBCS, a software, hardware, and system testing consulting group.
According to Black, the textbook definition of TDD is that it is the process of writing small tests that express some sort of functionality that you expect the software to accomplish. You then run that test before writing code to confirm that it fails, then you write software to make the test pass. As soon as the test passes, you move on and repeat that step again, Black explained.
That definition is the one advocated by Kent Beck and Martin Fowler, proponents of TDD. But not everyone who says they do TDD is doing it the textbook way, Black explained.
“I see some of that with clients, but not a lot, to be honest with you,” said Black. “Some of my clients will talk about doing TDD and sometimes, some of the people, some of the developers say that they mean they are doing exactly what Beck and Fowler and some of the other advocates of TDD recognize as TDD. A lot of the time, they’re doing things a little differently.”
According to Black, another one of the variations in definition has to do with the size of the test. In Beck’s description of how TDD should work, the tests are very, very small. But often what people do is write a test for a number of different functions all at once. “I think what Beck and Fowler would say if they saw that would be ‘no, that’s not right. You should break it down into single tests or steps and write the tests and the code step-by-step,’” Black said.
Arthur Hicken, chief evangelist at Parasoft, explained that while TDD is often interpreted as code-based unit testing, it is also sometimes viewed as something akin to a service API in that you have something that does a service and you have a definition file. “Before you ever write code, you write this definition of what it’s supposed to do, and then you can use tools against that definition to instantly generate tests,” said Hicken.
Another variant that gets confused with true TDD is people who write unit tests after they write the code.
Even if people are mislabeling something as TDD when it is not, maybe that’s not such a bad thing, Black explained. “From my point of view if I see developers producing automated unit tests and achieving 100 percent state and branch coverage and including those unit tests in their automated build and deployment systems, then I’m happy,” said Black.
Hicken sees TDD as a broad spectrum. The pure side of the spectrum is where people are coming up with requirements first, coming up with a unit test, writing the code, and writing exactly the right amount of code, he explained. On the other side of the spectrum are people who write unit tests at the same time as writing the code, said Hicken.
At the pure end of the spectrum, one of the benefits TDD provides is that it prevents people from over-writing code. “When you write code you’re supposed to write exactly how much code you need to pass the test and not a single line more,” said Hicken. “And so it keeps people from polishing the code or other things like that. You write what you’re supposed to and you move on.”
According to Black, developers can go back in and polish the code after it has been written and the test has passed.
According to Hicken, another benefit of TDD is that it forces developers to think about the outcome before developing. The code ends up being more maintainable and testable because they are thinking about what is supposed to happen when writing the test. “It kind of changes the mindset of people because they have the end in mind when they’re programming,” he said.
Hicken explained that the testing methodology TDD is most often compared to is behavior-driven development. The main difference is that TDD is focused on developers, while BDD is focused on the testers and the requirements.
With TDD, the main question should be whether the code was built right, whereas with BDD the question is whether they built the right thing, Hicken explained.
Even as more companies seem to place their focus on building for their users, which aligns more closely with BDD, TDD is not going away. “I would say that almost every client I’ve encountered this year that was interested in the one, was also doing the other,” said Hickens.
Hicken explained that companies may do BDD first if they are finding that they’re not building what people want or not getting functionality fast enough, but he does not expect people to throw away one for the other.
Like any new methodology or technology being brought into an organization, it needs to have buy-in from the top in order to work, Hicken explained. It’s crucial to have management on board and to be able to train people to write good unit tests. “I’d argue that over the long haul, the cost of creating a unit test is much less than the cost of maintaining a unit test,” Hicken said.
“It’s easy to create a unit test, but to create one that really answers the question, ‘what does this code do? If the test passes, what does it mean? If it fails, what does it mean? And if it fails, what went wrong?’” Hicken said. Training developers to be able to answer these questions is key.
Arthur Hicken, chief evangelist at Parasoft, details the benefits that Parasoft brings to test-driven development
“There are couple of big areas that we help at. And at the purest unit test level, we’re looking at code unit testing. If people are doing new code, they won’t use us as much as if they’re looking at legacy code. Suddenly if I’ve got a TDD initiative, I’ve got some code that’s new and I’ve wrote the test first, I can execute those tests inside of Parasoft’s environment. But with that legacy code, we can use our unit test assistant to help create—very rapidly—unit tests that are actually good, maintainable, have a good set of stubs and mocks around them, are very easy to execute so they’re meaningful and maintainable all at the same time. Now again as I mentioned earlier, I like to think about the service API as a unit, and in that case we can take our SOAtest product and read the definition and quickly produce a sequence of tests without any effort at all really. And then the developers can just take that and start coding until the APIs work. I would argue that as an API programmer, API is probably a more meaningful unit than a random individual file is. Those are probably the biggest benefits that we have there.”