The most popular unit testing framework for Java is JUnit. It is based on the SUnit framework for SmallTalk, and has led to other "xUnit" frameworks like NUnit for C#. There are also some very worthwhile JUnit extensions, like DbUnit for databases, and XMLUnit and SUT (Schema Unit Test) for XML. All in all, it is an extremely successful piece of software. The only problem is the name. You see, JUnit really isn't a unit testing framework at all.
JUnit is a testing framework, a really useful testing framework. So useful, in fact, that I am happy to use it (in combination with Apache Ant or Maven) for testing non-Java code, like XSLT. I highly recommend JUnit as a testing framework - but that doesn't make it a unit testing framework.
So, what is a unit test? Well, that begs the question of "what is a unit?" A unit is a small, self-contained piece of code that you can test independently. In object-oriented programming languages like Java, most people consider a class to be the right choice for a unit - it's typically something small that should make sense in its own right. JUnit is certainly a good way to write tests for testing an individual class. So why isn't it a unit test framework?
The issue is this. Suppose you are testing class A, and class A calls methods from classes B, C, and D. If you write tests for class A using JUnit, then you will also be calling code in classes B, C, and D, so you aren't just testing class A in isolation. You won't be able to get a 100% test pass rate for class A if there are bugs in the code for classes B, C, and D. When class A is a high-level class in an application, one that calls most of the other classes in the application, that means you aren't able to independently write and debug A until all of the other classes in the application are written and working, and that is the kind of dependency that unit testing, in the classical sense, is meant to avoid.
If JUnit were a unit testing framework, it would help you write unit tests specifically. It would help you avoid actually calling the code in classes B, C, and D. It doesn't do that (although you can always try other tools like MockObjects and EasyMock to help with that).
In truth, most people don't do real unit testing, because mocking out of classes (like B, C, and D) can be more expensive that just calling out to those classes. So while JUnit is widely used, it is widely used for non-unit testing. That isn't a bad thing, it simply is as it is. The only problems are:
- people using JUnit sometimes think they are doing unit testing, when they aren't;
- people sometimes don't think of JUnit as the right testing framework to use for non-unit testing, even though that is what it is mostly used for.
What's in a name, I guess. Great tool, just needs a better name. Not that I can think of one, though.
Recent Comments