Unit tests are small tests, usually written by programmers (but occasionally by quality assurance staff), that test one small part of a program – for instance, a function, method or class. They usually will test not just that code does what it should but also that it doesn't do what it shouldn't. For instance, suppose you had a method that did integer division where
divide(X, Y)returns X divided by Y (X ÷ Y). Unit tests would not only check that
divide(4, 2)returns 2, but also that things like
divide('a', 2), and
divide(4,&nbs;"xyzzy")all returned appropriate error messages.
Unit tests can be written in a freestanding manner, as small programs, but there are a number of frameworks – most notably the xUnit family (jUnit, phpUnit, Ruby's Test:::Unit, etc) that make it easy to automate unit testing. Automated testing can allow you to test all your code quickly with a single command. This in turn opens up a lot of exciting possibilities. For instance, anytime you make a change to some code, you can run your tests to make sure you haven't broken anything. (If you don't have unit tests already you can write and run them before you make the change.)
Unit testing makes test driven development possible. In test driven development you write the test for a part of the finished code, run the test to fail, write the code, then (hopefully) run the test to succeed. Many programmers find that test driven development makes them significantly more efficient because they can find and fix errors quickly. If you've ever spent hours chasing down a bug then you know how much time you could potentially save by catching the error when you make it (Not that you can count on unit testing or any other testing or quality assurance method to find everything, but if you catch even half – and you'll likely catch more than that – think how much time you could save!) Extreme Programming (XP) and refactoring both rely heavily on automated unit testing. Testing can be so useful that Michael Feathers argues for the redefinition of the term legacy code - usually used to denote older, often hard to understand code in an organization – as "any code without unit tests."[Feathers]
If unit testing is so wonderful, why don't people do it? I can't talk for anyone else, but I know that the reason why I don't use it very much is that I've mostly worked in shops that didn't use unit testing, so my taking the time to learn it seems like a waste of time while we are so busy (and like so many shops, not busy never really comes.) Plus, often the frameworks we used made unit testing more difficult or slow. (One of the tenants of unit testing is you want the tests to run quickly so that you'll run them often.) Also, there havn't been good frameworks for many of the development frameworks I've worked in (although that has been changing.) I do use non-automated unit tests and often use test-driven development. One of the things I love about Ruby-on-Rails is how well integrated unit testing is (and I use unit testing heavily in RoR.)
Wikipedia keeps an exhaustive List of Unit Testing Frameworks
One of the best simple descriptions of unit testing and why it's important is Chapter 4 "Building Tests" of Refactoring: Improving the Design of Existing Code by Martin Fowler. (Buy at Amazon.com)
Michael Feathers' Working Effectively with Legacy Code uses unit testing to make changing legacy code partitionable and safe.