This is the second part of a two-part blog that reviews a recent Google Hang-Out between Kent Beck, Martin Fowler and David Heinemeier Hansson regarding Test-Driven Development (TDD).
In my opinion, the solution that enables the IT project to deliver more, deliver cheaper and deliver quicker comes from TDD taking the next step along its evolutionary path. In this second part, I would like to discuss the Google Hang-Out and explore the areas that I feel would benefit greatly through some form of evolutionary development.
The majority of the first series concerns the act of testing. Specifically, David Heinemeier Hansson challenges Kent Beck regarding testing and asks, “What’s a useful definition of unit testing”. In his reply, Kent Beck gives some insights that, I feel, are valuable to the Tester and the related Industries that the Tester operates.
Between 06:00 and 06:15, Kent Beck recalls an old book from the days of punched cards and paper tape. He says, “Here’s how you program. You type in the output tape that you expect your program to produce for some given input tape and ‘programming’ is just … you write the program until it produces the output you expect.”
The simplicity and elegance in this statement is so easy to over-look. The insights I find include:
- The test and business specification are actually the same artefact.
- A cross-functional role is necessary: the Business Analyst role is necessary to create the business specification, as well as the Tester role is necessary to define the test case (and all the other corner cases surrounding the centre case).
- Defining the test (and therefore the specification) occurs before development takes place.
- Testing can (and does) exist before the Developer creates a running system.
- The testing process is transparent and the test-results are binary: red light, green light. Either the output matches the expectations or not: a non-negotiable definition of done.
- The Developer role strips down to the absolute bare engineering essentials. The artefact presents to the Developer containing all instances of input and output: the only task remaining is “programming until it produces the output you expect”.
The last insight is interesting. Compare with IT projects that do not engage TDD and how often does the Developer role change to assume the analyst role or the tester role? How often does the Developer make false assumptions regarding the values of input, output, and claims that their code “works” even though it is not what the business specified?
Between 06:40 and 06:50, Kent Beck picks up again on the “test first” principle saying, “Writing the test before writing the code … which makes no sense, right? The code is going to fail and you want the test to succeed so why do it?”
Again, Kent is bringing the role of the Tester right up to the front of the development cycle. Compare this to a typical IT Project plan. Whether the project methodology is Waterfall or Agile, the probability is that you will find a process dependency: first process defines the requirements, then the specification, then the build and then an iteration of highly stressed testing phases until go-live. After go-live the expectation is that things will not work properly and therefore another iteration of bug fixes and patch releases are necessary.
Whereas, if you applied the mind-set of the “paper-tape” programmers, you would have just the one stream called “test, build, repeat”. This probably sounds ridiculous to us now, but at one point in time, this was the norm. In fact, the Waterfall process of today would be non-standard at that time. Now, the exact opposite is the norm. Therefore, at some point in time, we (the creators of IT systems) changed from “test first” to “test last”. Yet, research shows that, on average, the IT project runs 45% over budget, 7% over time, while delivering 56% less value than predicted. Why do we continue with a methodology to “test last” when the results do not justify the means?
Between 07:20 and 07:40, Kent Beck gives a psychological perspective saying, “There is an aspect of my personality that makes [TDD] work really well … I have anxiety, I get over-whelmed by big problems, so for me TDD solves those problems.” I find this interesting because, for me, I see insights into the goals and motivation of a TDD proponent such as high quality build, stable systems, ability to embrace change, ability not to introduce instability and so on. For me, this aligns perfectly to the goals and motivation of a Tester. For me, the Tester is not there to cause friction within the IT project by continually identifying problems and single points of failure: the Tester fundamentally is there to ensure a high-quality deliverable, a highly stable system, a system that can embrace change and not introduce instability.
From 07:40 to 07:50, Kent Beck continues saying, “Even if I don’t know how to write a program, I can always figure out how to write the test. And if I don’t know how to write the test then I have no business writing the code.” For me, this is absolutely the golden point: if we cannot test then how can we expect the Developer to “build something”? By following TDD and adopting the “test first” principle, every feature has a test. Whereas, in the “test last” philosophy, Developers have free will to create as many features as the Business Analyst never specified, leaving the Tester to “guess” what the Developer created. Where there are gaps; there are inefficiencies and TDD solves these problems.
Flaws of TDD
Kent Beck also highlights what I see as a fundamental flaw with his implementation of TDD. As he says, “I can always figure out how to write the test and if I do not know how to write the test…” Further, Martin Fowler follows up at 09:02 (recalling a past IT project) saying, “The focus was on the testing without the testers…”
My insight (and in my opinion the fundamental reason for David Heinemeier Hansson’s pain) is that programmers must never write the test. Writing the test is responsibility of the business. Using the cross-functional role of Business Analyst and Tester, the cross-functional role can extract from the business the input and output values. Thereafter, the IT Project delivers the input and output values from the business to the Developer as a single artefact.
Going one further, the Business Analyst and Tester should never write program code (e.g. Java or a Junit implementation). Thus, in this structure we expose a problem to solve. If the business does not write a Junit test and the programmer does cannot write the input and output values to assert, how can TDD function?
The answer is TDD (in the current form) cannot function. Instead, we require a new path to the common goal: a new framework that consumes a test / specification artefact, and “executes” the artefact automatically against the programmer’s code base – generating a red light, green light result depending whether the code produces results according to expectations.
For me, the framework goes right back at the roots of TDD and, for me, solves the problems that David Heinemeier Hansson raises. At 10:20, David says, “the programmer happiness is certainly related to confidence [that your program code works without errors]… and you’re not done until you have tests; and I am completely on board with that.” He goes on to say, “Where I’m not on board is that whole feeling of ‘feeling great’ … I was not getting that from TDD.”
At 11:15, David Heinemeier Hansson clarifies, “we have different ways of looking at things … but what I was finding was that, the whole notion of writing of tests first, and seeing that fail, and doing that for every piece of code before I move forward was not only unnatural but also not a pleasant flow.”
For me, the key insight is that the pain-point arises when the programmer writes the test. However, with the framework improvement I mentioned previously, we solve this problem because the programmer does not write the test. Rather, the business (through support of the Business Analyst and Tester) writes the test content and the framework will execute the test automatically (triggered by the instance the programmer commits their code to a source-code repository). This gives freedom to the programmer and enables them to write their code according to their style – just so long as the results match the expected output.
At 12:18, David notices the different programming styles. “Kent, as you say, if you can’t write a test for it then I have no business writing the code … although I can understand how you arrive at that, it is just not at all how I work: I have a hard time writing a test for it if I don’t get to see it first.” Since the improved framework presents all tests to the programmers (as artefacts from the business) then the solution addresses the problem – a completed test enables the programmer to “see it first”.
From 17:40 onwards, the debate changes between Kent and David. The debate questions the methods to implement the test (best practices, mocking and so on). Kent’s line of reply is to challenge the programming style; David’s reply was more concerning how TDD introduces “design damage”. Since the framework improvement removes from the programmer the need to create the test implementation, (this is automatic and therefore, the framework makes decisions whether to mock, fake or instantiate “real” objects) – the framework solves the problems regarding “design damage”.
The series continues and the debate covers in six parts trade-offs in development, places TDD in the trade-offs, and gives some perspective with which you can decide for yourself how you want to program.
Does TDD Work?
In its current form, TDD works well when the problem space overlaps heavily with the programmer requirements (for example, a parse tree or a new database construct). However, with business application and a lack of specification regarding input values, the traditional TDD framework has limitations: the programmer must guess the input and output – as well as having to write the Junit test code in addition to the production code. Whereas, the modification to the TDD framework solves the problems: the IT project presents to the programmer all the input and output values and the framework itself manages the test code creation / execution – creating freedom for the programmer to program according to their style.
However, above all other benefits, the new TDD framework brings with it an essential re-definition of the Tester role – one that combines with the Business Analyst role as a cross-functional work cell and therefore an integral part of the IT project, engaging right at the front of the project process.
About the Author:
I am an experienced and innovative business analyst with a unique set of skills that allow me to dive deep into the technology, analyse the issues, communicate issues into business terminology, discuss options, advise, consult with all stakeholders in the project and support the development process to implement the goals without defects.
The methodologies I practice inclue Agile, Kanban and Waterfall. I am experienced in object-orientated analysis & design as well as relational database design & management with special focus on Oracle, ETL, data warehouse design, star schemas and reporting cube design, implementation and management.
The various tool-chain products and frameworks I have used and trained include Eclipse, Enterprise Architect, IRA, Jenkins and Confluence.
Over the past 20 years, my client list includes Julius Baer, Credit Suisse, HSBC, JP Morgan, Royal Bank of Scotland, Man Investments (now called AHL), Allianz, Deutsche and UBS. Although this has heavy focus on financial services, within the industry I have covered ground such as engineering, financial engineering and regulatory engineering.
Dave Cobbe: http://www.tek-motivation.com/dave-cobbe.html