To deliver good code we must understand the problem from the user’s viewpoint. We must understand at a level of detail that is very difficult (and very tedious) to document.
So we work with the Customer on a white board to ensure we have taken on board the nuances of the user task. Have we got inside the head of the user? [I recommend the use of a white board with screen capture interface.] The customer must gather up test cases.
As we write code we think of all sorts of details that are not in the specification. If we have established a good rapport with the user we understand how to handle most of these.
But some of these will require us to think: If this was not raised before can I razor this issue away?
Some will say to us: Why is it not simpler to do something else instead? We must be able to immediately check with the customer.
Finally to ensure we have understood and implemented what the customer wanted we must show the customer the results of our tests.
Firstly the unit tests and secondly the integration tests are shown to the customer who will eventually agree we have delivered a solution to this task.
Initially the customer will have difficulty in envisioning the deliverable from the discussion and therefore to see the results immediately ensures that the customer and the coders are in sync.