“Natural Language” Automated Acceptance Testing
I read with extreme interest James Shore's blog about FIT but was dismayed that he devalues automated acceptance testing. To claim that FIT is a "natural language" is wrong, it is a developer language and this is possibly why customers don't get involved. Concordion on the other hand is natural language and I think plays much better in this arena. In addition it is much more developer friendly.
I've written previously that for me the value of test first is the thought processes surrounding it, however, where applicable converting these into automated tests, and in particular automated acceptance tests is a huge win. I would love having a customer "own" the tests, but when this isn't possible (almost always) I will try to put my "customer" hat on and think like the customer and express what I'm about to do in their language (which will be English, not FITnese, or selenese, or rspec). If the customer is happy with my specification, I can then use this directly as my test.
So for me, the lack of customer isn't the problem, but I agree with James on one point, there is a problem...
It's the people... The majority of developers I've encountered can't think like the "Customer" and instead thrive on complexity. They can't express the problem or solution correctly and write tests that become implementation specific. This means they have written a test for a specific solution, where actually there could be a multitude of solutions, even in the same technology. When they then 'implement' this solution and the customer doesn't like it, the test can't be reused and needs to be 'reworked' (I'm avoiding refactored, since the test was actually wrong, and therefore it should be fixed, not refactored). This is the problem, the test may be rewritten many times at which point the customer will be thinking, this is now the n'th time I've asked for this exact same feature and I've seen five different versions of a test for the same thing, none of which are producing what I'm asking for. If I was that customer would I want to own these "tests" which seem to be so difficult to change and can produce such a burden to tweak the implementation.
So for me, if I don't know what I'm doing, I won't do it and will ask for help from someone who does know what they're doing. I would encourage all developers to have the courage to admit when they are out of their depth with a practise and seek advice rather than struggle on developing the wrong thing which ultimately ends up having little value.
I forever find myself coming back to the five values, and when I measure FIT against simplicity, communication and feedback it would come in at "Good, could do better"...
The Real Value of Test First is the Thought Process

TDD found the simple solution 😉
Test Driven is a loaded term and means different things to different people. I much prefer the term Test First which clearly states that the test comes before the implementation. However, for me, the value is not necessarily in creating an executable test, but in the thought processes that Test First brings out.
One of my colleagues at emergn is constantly reminding me that when presented with a solution you need to ask yourself what is the problem. This is what lead me to question TDD and it's variants. If you search the web for Test Driven Development, you'll uncover a wealth of information from many of the authors in my BlogRoll, as well as many variants on a theme. I think the wikipedia entry is a particularly good summary of Test Driven as it is currently understood by the community but for the real meat and bones you need to look at the articles from the thought leaders behind the practises.
However, when I look at this wealth of information, I'm now faced with the question... OK, these are all solutions, but what is the fundamental problem they are solving? Is it
- Code quality/design is poor
- Code is overly complex/difficult to test
- Unused functionality within the code
- Too many bugs
It is only when we understand the underlying problem fully that we can then evaluate the applicability/suitability of a particular approach. Indeed, it is this lack of a clearly defined problem which makes it impossible to determine which approach is best, since we can't define any tests up front... This is actually a little bit of a paradox, but highlights for me one of the most important points about TDD. TDD is a solution to too many problems and in certain cases is not a very good solution.
Testing should be about proving functionality, but unfortunately we too often see TDD trying to address non testing issues like design and code quality. Of course, code needs to be testable, but it is not the responsibility of the Testing to enforce this, it is the responsibility of the design, but this is (unfortunately IMHO) the missing piece in most methodologies... Indeed, the approach of writing the "Simplest Possible Thing" to pass a test is possibly my biggest bug-bear with TDD. This approach often means you can pass tests with no functionality other than hard coded return values, now that has to be the biggest process smell ever.
I'm going to stop using TDD, or Test Driven now and use instead the term I prefer which is Test First. For me, this means that before I do anything, I will determine ahead of time how I would test it. The immediate benefit (a.k.a value) I get from determining how to test something is I'm also starting to think about (dare I suggest design) things like apis/design/interaction/responsibilities. This is not the same as BDUF (big design up front), instead it is just enough thought at just the right moment to (hopefully) prevent a disaster. I can then apply some cost/benefit analysis with a pinch of risk analysis to assign a value to actually writing all the tests that TDD would have forced you to write, or just a small percentage to cover the important or more complex functionality.
Of course, in many cases I will actually create executable tests for many of those uncovered during this thought exercise, but will I go through the whole Red/Green/Refactor cycle, possibly not. For me the Red/Green/Refactor is like micro context switching. I prefer a slightly longer period of focus and therefore I may write quite a few tests at the same time before applying that context switch to go into coding mode. This of course is my personal preference and undoubtedly would be scorned upon by the dogmatic TDD zealots, but if this is what makes me more productive, and without a baseline problem statement I challenge them to prove that this is not the best way to do your testing.
Test First allows me to
- Understand the problem I'm trying to solve
- Think about how I will solve it (just enough design)
- Uncover any unknowns or risks hidden in the initial problem statement
- Produce high quality code which has just enough tests
Many of the Test Driven approaches do indeed address many of the initial problems stated earlier, but are they the only solution to these problems? Indeed, are these problems actually just symptoms of even deeper problems? If the problem is simply that your code is very tightly coupled and difficult to test then the best ROI will probably come not from TDD but from up-skilling your development team on fundamental design principles (unskilled developers was the real problem in the first place and TDD can't solve that).
Resources:
- Wikipedia entry for Test Driven Development: http://en.wikipedia.org/wiki/Test-driven_development
- Introducing BDD by Dan North: http://dannorth.net/introducing-bdd (highly recommended reading)
- C2 wiki entry for Test Driven: http://c2.com/cgi/wiki?TestDriven