Unit Testing: It’s Like a Box Of Chocolates

Nominally, unit testing is a QA function. After all, it’s part of the process of ensuring that an application works correctly. Developers are responsible for creating the application in the first place—and surely that’s enough to keep track of.

As a result, it seemed like an obvious question to ask both developers and testing professionals how their workflow breaks down. That is, who does the unit testing? Who should? I imagined a knock-down, drag-out fight between the two communities, possibly including shouting and name-calling, tufts of hair fluttering in the breeze, and chairs thrown across the room. It would all be very entertaining.

So much for that idea.

As it turns out, developers and QA testers have achieved an almost unanimous consensus: Unit testing is the developer’s responsibility. What I found interesting, though, are the differing opinions on the reasons why.

One consultant is unrepentant in his viewpoint. Says Brian Crook, freelance writer and IT consultant in the Rocky Mountains, “Any developer who claims to be ‘above’ unit testing is not to be trusted. A developer should be able to demonstrate that his work conforms to requirements as s/he understands them. So developers are responsible for unit testing; always have been.” Nonetheless, he admits, “Conformity has been spotty sometimes.”

When he first encounters them, says Kevin P. Taylor, principal consultant for Obtiva Corp. in Naperville, Ill., most of his clients run unit tests manually by QA teams, with test plans in MS Word or Excel. “Since my company specializes in agile methodology training and mentoring,” says Taylor, “it is always a high priority for us to (1) move unit testing from the QA team to the developer team and (2) automate the unit tests.” Moving unit testing to developers, he feels, enables QA to focus on higher-level testing, such as integration testing and acceptance testing. “Their productivity goes through the roof,” he reports.

That’s not to say that everyone believes that developers should write and run their own tests. Some believe that the programmer’s peer should do the unit testing. For example, Asif Patel, a software tester at Anker Systems in the U.K., advocates a level of test independence. “Ideally, the author should have a ‘buddy’ developer who is able to test the code. There can be a degree of emotional attachment.”

Overall, however, I found more agreement on this topic than on most others I’ve encountered. (Though perhaps the question “Is chocolate a good thing?” would have received a more uniform response.)

Developers and testers have their own reasons for developing and using unit tests, and they see different benefits.

Developers view unit testing primarily as a way to improve their own efficiency. Programmer Christof Wollenhaupt claims that unit tests are a worthwhile replacement for traditionally written test programs. “Unlike these one-time test programs that help in writing the code in the first place,” he says, “unit tests are repeatable.” Unit tests have enabled him to improve his own code quality. For instance, he says, “A modification in one class caused a side effect on another class that I didn’t foresee, as well as many bugs where changing code broke existing valid scenarios.”

Efficiency and early feedback are also the major advantages for Ilja Preuss, a software developer at disy Informationssysteme GmbH in Germany. He explains, “I need to have new tests for my new code as early as possible, and I need to be able to run all the tests whenever I want.”

Gerardo Tasistro, research and development director for Asdeporte CIE in Mexico City, is more concerned about the overall development process. According to Tasistro, when code units are tested by developers, it reduces the number of problems QA has to deal with. Also, he says, doing so benefits code reusability. “This is the most important reason. You don’t want to reuse bad code.”

Allan Caplan, architect at Workbrain Inc. in Toronto, has three reasons. First, he says, unit testing is faster than integration testing. “I’ve watched as developers go through this cycle [write the fix, compile/deploy the fix, start up your app server, navigate to the page, and perform a set of actions] ad nauseum. With unit testing, you define what the correct behavior is. You can then write your code, and if you’re using an editor with JUnit integrated, you just keep clicking that Run button until [the code passes the tests]. Only then are you usually ready to deploy to the server and attempt an integration test.”

And, of course, there’s always the cynical (or is it realistic?) point of view. According to programmer Scott Selikoff, from a management perspective, unit testing can be more about PR and accountability than it is about quality, control or good coding. “I’ve seen managers talk about it as a buzzword in the same way they talk about J2EE,” Selikoff says. “Most of the time, they have no notion of what unit testing is, nor can they properly formulate the desires to the developer as far as what to test and how.”

While it’s obvious that unit testing is considered an essential part of the development process, there’s less agreement about when those tests should be written. The test-driven development (TDD) methodology suggests that the tests be written before you begin coding. Not everyone sees it the same way.

One developer who relies on TDD is Ernest Friedman-Hill, who works for Sandia National Laboratories in Livermore, Calif. His main project is a small one, with about six developers. The developers do all the unit testing, and the tests are written before the code.

Doing it first changes everything, says Friedman-Hill. “I’ve run plenty of projects in the past where developers wrote tests after the fact. These invariably were more application tests than unit tests, because if you don’t design for testability, you often end up with code that’s hard to test ‘in the small.’ You get big tests with lots of setup that don’t isolate faults and tend to give worse test coverage.” Writing tests first leads to better design, says Friedman-Hill, because it forces you to think about an interface for each class, allowing that class to stand and be tested in isolation.

Preuss finds that writing the tests helps him write well-designed code. “Writing the unit test first forces me to write testable code. And the most important property of well-testable code is that it is decoupled, so that you can test units in isolation. Writing the tests in parallel to the code also helps with getting high code coverage,” he says.

But TDD isn’t for everyone. Selikoff says that while unit testing has advantages, test-driven development is fundamentally flawed. It’s especially problematic in J2EE, he says, where service context, database dependency and transactional requirements make it unrealistic to run good unit tests. “For example, if a line of code was only supposed to be run inside a transaction, it is very difficult to successfully unit test. I think the people who thought of test-driven development were smart and had excellent intentions; I see the practical application of it being a complete mess and giving management a false sense of security, at least in the near future.”