How are unit tests different from acceptance tests?

There was a question on one of the internal aliases today about the difference between unit tests and acceptance tests. I responded with my take on it. After some consideration, I decided to share this with the world as well. Of course, I have edited this a tiny bit to make sense by itself, and not in the context of a long email thread. Enjoy.

“How are unit tests different from acceptance tests?”

My unit tests each test one behavior of one class. There are lots and lots of them, grouped into fixtures by class. Acceptance tests, I prefer to have written by the customer or customer proxy, but it is often the testers who write them. My acceptance tests, when I write them (yes developers can help testers and customers by writing these too) are a lot higher level. Acceptance tests probably load up the whole application (or a big piece of it) and ensure that it works properly.

That is somewhat high level, so here are some examples:

I just finished up a project (<shameless plug>the Web Client Software Factory with a Codeplex community site </shameless plug>). This included guidance for developers on creating web applications for the enterprise, code generation, and a very simple sample web app. In the web application, there is a page that handles a customer entering an electronic funds transfer. There are unit tests for the presenter for this page, as well as the application controller that the presenter talks to. For example, a few unit tests for the presenter are

· AddIsEnabledAfterFithItemDeleted

· AddIsDisabledAfterFiveItemsAdded

· LookupAccountNameThrowsAnErrorIfAccountNumberNotFound

· GetAccountNameReturnsCorrectAccountName

Each of these test one specific behavior of the class. If one of them fails, you can figure out why pretty quickly, even if you have not seen the code before.

The whole EFT process had a number of functional tests, written with an internal web testing tool (That is as much as I can say about it, sorry). We tried to ensure that before dev work started on a feature, we had an automated acceptance test or at least the outline of the steps for the test and the expected outcome (so the dev and tester could work in parallel on the same feature). Here are a few test case names from the automated tests:

· CreateandSubmitOneTransferTest

· CreateandSubmitMultipleTransfersTest

· EmptyAccountNameTest

· EmptyAccountNumberTest

Each of these loaded a web browser, navigated to the site, logged in, hit the pages necessary for the test, filled in values, and determined success or failure. They looked at the whole system. For example, CreateandSubmitOneTransferTest would login, go to the eft page, enter an eft with valid information, submit it, and ensure that the eft went through. This was hashed out with a developer, a tester, and the customer (proxy) creating a set of steps to be done and checked on.

I hope this helps clear up the difference between acceptance tests and unit tests.