Should Acceptance Tests Hit the UI?
Acceptance tests are generally end-to-end tests that run on a real working environment that is similar to production. This means that in an ideal world, they would be run directly against the UI of the application.
However, most UI testing tools take a naive approach that couples them tightly to the UI, with the result that when the UI changes even slightly, the tests break. This results in many false positives—tests that break not due to any problem with the application’s behavior, but rather because some checkbox has had its name changed. Keeping the tests in sync with the application can swallow up huge amounts of time without delivering any value. A good question to ask yourself every now and again is, “How often do my acceptance tests break due to real bugs, and how often due to changes in requirements?”
There are several ways to solve this problem. One is to add an abstraction layer between your tests and your UI so as to reduce the amount of work required when the UI changes. Another is to run acceptance tests against a public API that sits just below the UI—the same API that the UI uses to actually perform actions (it should go without saying that your UI must not contain any business logic). This doesn’t obviate the need for UI tests, but it means they can be reduced to a small number of checks of the UI itself, not the business logic. The bulk of your acceptance test suite can then run directly against your business logic.