2
votes

Any good software architects would be agree that when someone builds a new project from scratch, he mustn't carry about boundaries at the beginning (database, GUI, external services etc...) Indeed, he should construct heart of his software independently of any backend and think about them as just kind of "plugins" to the application.

TDD and acceptance testing promote that for each new feature:

  1. Write a failing acceptance test (end-to-end) for the feature
  2. Drive and complete your code design thanks to some unit tests
  3. Finished as soon as acceptance test passes.

However, a lot of articles explain that an acceptance test is a really really end-to-end test involving thus GUI (browser (using Selenium for instance) or some other interface).

Shouldn't Acceptance testing be based on the application's HEART and independent of any boundaries? It would force me to think about GUI for instance... :s

What is a good practice? Write two kind of Acceptance tests for each feature?: one for business logic and one ensuring that the GUI well works?

1

1 Answers

4
votes

First let me suggest reading Growing Object-Oriented Software, Guided by Tests by Steve Freeman and Nat Pryce. It's by far the best software testing book I read so far. What's great about it is that the authors don't focus on dummy use cases like Calculator class and using TDD to test add(int, int) method. This is silly. Instead they build fully-functioning application with Swing interface, network connectivity via XMPP and quite a lot of business logic. Which brings us back to your question.

Authors of the book above use various techniques and tools but they keep TDD practices all the time. For unit tests they go for but for acceptance and integration tests they actually automate starting an application (GUI) and XMPP test server.

They managed to test-drive GUI tests by employing high separation between the test and GUI. You should hide your user interface (web, desktop, SOAP web service, etc.) behind an abstraction called driver. Your test interacts only with the driver using high level methods like placeOrder("Foo"). Each driver (BrowserDriver, SwingDriver) understand what that means and either browses your web page or clicks buttons on fat GUI.

If you can change your GUI without changing test but only by changing underlying driver - you got it right.

See also