TDD: From Katas to Production Code
Katas are a way to break down the learning and not overload developers trying to learn technical practices, such as TDD.
Join the DZone community and get the full member experience.Join For Free
TDD has been a subject of interest for practitioners at least for the last ten years or so, even before that if we take into account the eXtreme Programming practices and the agile manifesto.
Despite its claimed popularity today and its symbolism of quality the practice of writing the test before production code is still uneven. It varies based on the practitioner's context, past experiences, and the practitioner's learning path.
We could elaborate further on the uneven knowledge of TDD starting from the formal education on the subject, therefore, it might require even more discussions about its applicability. Is it possible to teach effectively TDD without professional project experience? Some might argue that it is possible, while others will say the opposite.
Despite great content published by renowned publishers such as O'Reilly, packt, # Addison-Wesley Professional Computing Series, Apress, and Manning the practice of TDD is still a challenge, even the best books, the best examples, cannot automatically translate its content to the unique problems that practitioners face on the daily basis.
Katas are a tool that might be used to fill in this gap for both: formality in learning TDD and uniqueness problems that practitioners face.
Practicing with katas is not a replacement, it can be understood as an aid instead.
The Mismatch With Real Problems
Practitioners have tried different approaches to internalize test-driven development. Despite the effort, the mismatch between training and production code exists.
The patterns found in practicing Katas are close to green field projects. In the day-to-day, it is most likely that practitioners will join a brownfield project that is not that friendly to maintain. There are books that focus only on this aspect of things, for example, Working efficiently with legacy code by Michael Feathers, Refactoring: Improving the Design of Existing Code by Martin Fowler, Refactoring to Patterns by Joshua Kerievsky, and many more.
The patterns that practitioners use for Katas but are usually a mismatch with production code that frequently appears together are:
- Approach to test from the outside - when should I switch to the unit?
- Persistent layer - I use an ORM (Object Relational Mapping) or the layers of my application are mixed together
There are different approaches that one might take to write code, what is usually shared across the source code is the technique of splitting problems and then combining all the pieces to solve the problem.
Let's dive into the chunking and what it means to use it to start tackling the transition from Katas to production code.
The process of chunking happens without one noticing it, but practitioners are experts in this technique. The chunking approach is described by Learning how to learn by Barbara Oakley and also depicted by Felienne Hermans in her book The programmer's Brain.
The process is the same as an algorithm: given a complex problem, what are the pieces that compose the problem? and what are the pieces that can be split? With each step, move forward the needle to get the problem solved.
Splitting the problem is important, as it gives room for our brain to work without overloading it, we do have limitations to working with information. Looking specifically at practitioners, this is one of the reasons that one might not have the entire system architecture in her head as described in What Makes A Great Software Engineer? by Paul Luo Li, Amy J. Ko, and Jiamin Zhu.
Taking a step back, if we are talking about Katas, they are the first step of chunking. In this stage, we are focused (but limited) on:
- Learn something new (such as the practice of writing tests first)
- Sharp a skill, given that TDD is a known subject, one might want to try different styles. Such as: with or without test doubles, a new architectural style, a new programming language, etc.
Without this first step, it might be difficult for practitioners, on the job, to learn TDD, learn baby steps, learn simple design, learn to refactor, learn architectural styles that might fit the problem at hand, learn the pragmatic approach to a problem, and so on.
There is a lot to take into account, Katas abstract that away, and focuses on a single technique that is at hand. For example, take the following list(that is not exhaustive) as the focus point:
- fizzbuzz focuses on baby steps
- mars rover focuses on the TDD flow
- smart fridge focuses on test doubles
- gilded rose focuses on legacy code
Katas are here to ease the process of learning the techniques that are used on the daily basis by practitioners. Of course, this is just the first step, the first chunk that allows practitioners to become effective in their work.
Expanding to Production Code
Moving from a Kata setting to a professional project that is in production is not as transparent as it might look.
Let's take into account brownfield projects, which are the most likely faced project by practitioners.
The first barrier that is not easily transported from Katas is that the code might be mixing too many responsibilities in a single class, or that there is too much to understand of the code, as it was a developer that left the company already written, or the dependencies of the project are too many.
Regardless of what it might be, the challenges sum up in the bill.
Referring back to chunking, the first step here is to identify a single point that can be tackled. This is an important step, as the technique is already in training.
Focusing on a single aspect at a time to improve production code plays an important role.
Let's think about the following scenario:
We have a application that was developed with a MVC (model-View-Control) framework, but the layers have been mixed, there is no clear layering going on, besides that, there are no testing in place, the application is mainly tested through a manual approach. To top that, practitioners want to apply the new techniques they've learned to make the code maintainable.
As we already discussed, the key point here is to identify the pieces of the puzzle first. Trying to tackle all the problems that were listed at once might lead to more harm than bring benefits. Let's enumerate the key chunks:
- Mixed business logic between layers
- It is difficult to read a line between the layers, often leading to a manual end-to-end test - if it were an API, it would be done through post, if it were a web application, it would be done accessing the browser and navigating as the end user would do.
- There is no automated testing in place
- Practitioners want to apply new techniques learned
- An example of an approach could be implementing a new algorithm that performs faster
- Restructure the code to fit an architectural style
If we think about them one by one, we start to see a correlation with specific Katas we might want to perform:
Mixed Business Logic Between Layers
Gilded rose is a good candidate for that, applying the technique of golden master, helps to improve the internal structure of the code.
There Is no Automated Testing in Place
Once again, Gilded rose allows the creation of new test cases that do not exists, as the previous step, used the golden master, now the code should allow practitioners to write new tests that can code specific edge cases that weren't before.
Practitioners Want to Apply New Techniques Learned
At this point in time, the two previous steps are in place already, with that, the code should be testable enough that the production code is not highly coupled with the test code - This should be a health check, before implementing the new techniques.
Can you answer the question:
If I refactor, the tests don't change and I have the confidence to release?
If the answer is yes, then applying new techniques learned should be doable.
Opinions expressed by DZone contributors are their own.