3 Stories – Test Last Development (TLD) and Test Driven Development (TDD)
December 13, 2021
Blog > Development, Quality, TDD | Valentina Cupać
Story 1: Endless Test-Last Development (TLD) – a common reality
Month 1-3: “We’re just getting started, this is just a simple CRUD application, we’ll skip automated testing because will slow us down, we need to code features as fast as possible”. Demos pass really well, clients are happy.
Month 3-6: Most of the sprint is spent during bug fixes, feature delivery has really dropped. In fact, most time goes into debugging and trying to not break the existing system. Clients aren’t so happy, they say the development team isn’t delivering enough and that the software is really buggy. “We wish we had automated tests, the manual debugging and manual testing has now become so time-consuming and every sprint demo and production release is stressful. Let’s start doing some automated tests now”.
Month 6+: Coding is done during the sprint, and then automated tests are left to be done “later, when there’s time”. But the time never comes along. Feature delivery drops further, management decides to add additional developers to the project. This causes even a further drop in delivery and even more regression bugs. “Well, looks like automated tests aren’t possible, they take too much time, this is just the way it is in IT, there’s nothing we can do about it”.
Story 2: Test Driven Development (TDD) right from the start – the dreamland
Month 1-3: “We need to build in quality right from the start”. The team analyzes user stories and writes automated tests derived from the acceptance criteria. “Done” means automated tests pass.
Month 3-6: The client has lots of ideas, changes come in. Changes are welcomed by the team – developers write automated tests for the change, then implement, check other existing tests pass. The majority of the sprint is spent doing feature development, and very few bugs. Team velocity is maintained. Sprint demos and releases are painless.
Month 6+: Management expands the team with new developers. The new developers write tests for features and changes they need to implement. They also run through the existing test suite to make sure they didn’t break any existing functionality. Team velocity stays high, and the team is able to scale.
Story 3: Transitioning legacy systems towards Test Driven Development (TDD) – the realistic journey
Month 1-3: A new project has just started, the whole team is super excited! It’s a fresh start. They’ve already seen the pains of TLD from previous projects, they theoretically know the benefits that TDD would bring. Unfortunately, using TDD in practice is not as easy as the theory. Most tutorials are at the level of calculator examples and the team is stuck on how to translate it to their actual project, and the learning takes time. On the other hand, the team is under pressure to meet hard deadlines… So the attempt to apply TDD is abandoned, and they go back to the way they did things before.
Month 3-6 and beyond: The team feels like history is repeating itself. They are back to the way they always did things.
A few years later: There comes a breaking point due to the rising number of regression bugs, due to much longer release cycles, due to inability to scale teams… And in worst cases, new feature delivery almost comes at a halt for much larger systems. Everyone is dissatisfied. There are two options – to change or not to change, that is the question. We can continue the way things were done, with no change due to inertia. Or a change catalyst – might be an internal or external person or both (who has previous experience in TDD in practice) – may initiate change within the project. In order to get the change to “stick”, it is applied incrementally, this means that when new features are requested, writing automated tests retroactively for the existing affected code, and new automated tests for the changes (i.e. applying TDD). In this way, applying TDD incrementally, helps the team continue delivery whilst avoiding untested refactoring and learning at the same time, i.e. keep up velocity and minimize risk, whilst incrementally increasing the quality of the code.