📜 ⬆️ ⬇️

TDD study through intensive practice

Note from the translator : my experience of exploring development through testing is in many ways similar to what the author describes (although it started a few years later). I started learning TDD on my own, at work, correcting bugs and creating new modules from scratch. The effect of the use of TDD made me so powerful an impression that it gave rise to a desire to share the ability to use this technique with others. I also conducted Code Retreats inside and outside my company. And I see the same problems in my trainings - it is very difficult to take and “shove” the understanding of the essence of TDD into other people's heads.

Therefore, in this article I see a fresh look at the problem, which, perhaps, will give a new impetus to the study of TDD for me and my colleagues. I think it will be useful for other interested in developing through testing. I will be glad to see your comments.

I use TDD as a tool for learning and teaching the basics of modular design, but I have to note that the effectiveness of the training is highly dependent on the discipline of the students. I want to do my job better and better, and therefore I’m constantly looking for new ways to plan critical steps in teaching TDD. I think I found a microtechnique that helps in this matter, and I want to immediately share it with you.
')

Tl; dr?


Many TDD advocates recommend an approach called “intensive practice,” but I guess that you will not have the opportunity to spend a lot of working time on the practice. I advise people to “use TDD consciously,” but I still didn’t know a good way to explain the meaning of these words reasonably well, which reduced the value of my advice. You can start using both approaches (intensive and conscious) at the same time if you start correcting bugs through tests. Even if you still do not know how to design software at the expert level, then at least you can already study as an expert. And fixing bugs through tests will give you a natural and not too risky opportunity to do this. You will have the opportunity to practice in TDD diligently and deliberately. If you have the opportunity to fix bugs at work alone, then you can use these practices without attracting too much attention, which usually occurs when talking about "intensive practice". Just tell everyone that you are fixing bugs. Everyone will like it.

You just need to start by writing a test that will fall until you fix the bug. If you need more details, read on before starting.


Details

While reading Gary Klein's Sources of Power book, which describes how people learn to make decisions, my chapter on intensive practice attracted my attention. (I will comment on a few quotes from the 104th page of this book.)
Since the key to effective decision-making is building expertise, one of the temptations will be to create a training that teaches people to think like experts.

It seems to me that many people are exposed to this temptation and build their trainings in such a way as to maximize the amount of expert-level information with which they can load the participants. I did it too, but I stopped when I visited one of them as an ordinary participant. If you open the faucet and start pouring dozens of rules and conclusions into me, I will “overflow” in just a couple of hours, and then I will stop listening.
In most cases it will be too long and expensive pleasure.

Yeah.
However, if we cannot teach people how to think as experts, we may be able to teach them how to learn as experts.

Go on ...
Having studied the literature, I have identified several ways in which experts in various fields can be trained:
  • They take part in intensive practice in such a way that every practical lesson has a purpose and evaluation criteria.
  • They accumulate a vast layer of experience.
  • They receive feedback: accurate, diagnostic, and timely.
  • They enrich their experience by conducting “debriefing” to learn from their mistakes.


Some of this sounds familiar, but something is a new opportunity to learn more from TDD practices.

Three of the four - not so bad


Earlier, I mentioned intensive practice. In “Don't Waste Your Golden Learning Opportunity!” I wrote about new practices that can be viewed as sketches. This metaphor is taken from music, where etudes are widely used to practice technology. Athletes, in turn, may think of practice as a game of training. But, since most programmers are unlikely to practice outside of their day job, it makes sense to consider such practice modes that can be used during “regular work”.

I myself studied first the “first tests” approach (test-first), and then the “test-driven development” in the heat of daily work, when time is limited, and they expect real results from me. Looking back now, I understand that I have done three of the four things that Klein lists as sources of training for experts.


But even when I was practicing intensively and diligently (and even consciously), I did not go so far as to formulate an explicit goal and evaluation criterion for my practical exercises. More precisely, sometimes I went, but more often not. As a rule, I did not set such goals explicitly, and if I did, then it happened by chance. Now it is time to remember my past experience and learn from it a new lesson.

Intensive TDD Practice


If you want to practice in TDD as a tool for the qualitative design of software systems, try to do this at work.

Grasp fix some bug. Most likely, you already know how to fix bugs, using the principle of “first tests” (test-first), but just in case I will briefly describe this process:

  1. Write an integration test that falls due to this bug. The test does not have to pass to the end, but you can continue it as far as you need. The main thing that he fell because of the existing bug.
  2. Start writing less and less (more focused) tests that bring you closer to the location of the bug. You can use for this technique " Saff Squeeze " (or any similar). You can even use the debugger if you want.
  3. Stop when you have a minimal test (or several tests if the bug has several reasons), which describes the essence of the error causing this bug.
  4. Correct the error, make sure all tests pass, and then record all your changes.
  5. Pour yourself a cup of coffee.

And now let's go back to the four points of Klein and see how this method will help you learn how to design software at the expert level.

Does this sound like an intense practice? Yes. When I sit down to fix the bug with this method, I treat it as an opportunity to practice writing tests, an opportunity to learn to rely less on the debugger and tracking code in my head, an opportunity to learn to better express and document (through tests) my knowledge of the code I am debugging .

Do I have a clear goal and evaluation criteria? I see a clear goal: fix a bug, learn how to write tests, learn how to write more focused tests, and also document the knowledge gained about the code so that this knowledge does not evaporate by the time I send my changes to the general repository. And as evaluation criteria, I can choose one of the following:


I don’t know if you would call these criteria clear enough, but at least you can start from them. Perhaps together we can work out more successful evaluation criteria.

Will it help me to gain a vast layer of experience? It will help if I fix 50 bugs this way in the next few months. At a minimum, if I decide to fix all the bugs in this way, I will consistently accumulate a significant amount of experience. Especially if I fix bugs in all parts of the system. And even more so if in several systems.

Will I receive accurate, diagnostic, timely feedback? I think yes. Every time I write a new test, it will either pass or fall. Therefore, at least I can understand that I have begun to approach the broken part of the code. I can’t be 100% sure that I’ve found the piece of code that causes the crash until my tests are small enough to prove it in one way or another, and I am gradually moving in that direction.

Will this help me review my old experience to get new insights? Yes and no. No, because (as I hope) I don’t have to fix the same bug twice; but yes, because I work this way with every new bug, so I will have to face the same parts of the system many times. The more bugs I fix in any part of the system, the more opportunity I will have to go back to my past tests and compare my new experience with the old one. If I spend a little time comparing what I do differently compared to previous times, this will give me the opportunity to get new insights.

So, it seems to me that this method of correcting bugs will help the practitioner to study as an expert (at least in this interpretation of both the method and the model of training experts described by Klein). Just try it yourself and appreciate this approach.

Outside of working with bugs


How can TDD be used to learn modular design principles at the expert level? I must mention one common negligence along the way. It is not that serious negligence, but rather the result of good intentions and at the same time misunderstanding. I have always considered using the “informed approach” as particularly important. Therefore, when someone starts to declare that the development through tests “does not work” or “causes suffering” or “hurts”, I join the discussion and repeat the same idea over and over again:
The rules do nothing themselves; people do everything. TDD, like any other practice, requires the practitioner to include brains. He must exercise consciously.

It was true, but rather useless ... until today. I am sure that Klein revealed to me a more accurate and applicable way to explain what “conscious practice” is. I am going to use it in my trainings starting today. It seems that I used it implicitly in the study of TDD (and modular design), but so far I have not had an easy-to-remember way to formulate it. Thank you, Gary Klein.

How to practice TDD "consciously"


Take a pause of a few seconds and think about when and how you are going to learn TDD. What code? What time? In what conditions? It is not necessary to limit ourselves strictly to these rules, but they will help streamline the process. It is very important to determine for yourself when you are ready to use TDD, and in which not. Determine it, for now, just for yourself. You can negotiate with colleagues later. 2 .

Once you have defined the framework in which you will practice TDD, you can ask yourself the goals and evaluation criteria for these workouts. I'll throw some ideas.

TDD Training Goals


Evaluation criteria for TDD training.


If we sit together for at least ten minutes, then we’ll probably come up with a dozen more of these useful criteria. Select a few and keep them in mind during the next programming session, during which you will work out TDD.

And let me turn to the issue of obtaining new insights from the old experience , because I often come across this, teaching others and practicing with them. To recycle your experience, it is not necessary to conduct any classes yourself. You can, for example, just answer other people's questions. For example, I repeatedly answer the same questions that come from different people. (Usually, I can not stand to repeat myself, but now I realized that these repetitions are in fact much more valuable.) The more I answer these questions, the more I reflect on my understanding. Over time, my ideas are faced with a variety of new challenges and either strengthened or give life to new, more successful ones. I also participate in Code Retreats specifically to work on the same small tasks over and over with new people. Every year I experience new insights while working on the “life” game.

And now I would like to go to one important point in Gary Klein’s model, the point that led me to write this article today.

Extensive layer of experience


For years, I have described TDD as a “technique for teaching design,” in which we can use a mechanism similar to the mechanism for developing language skills. How did you learn to speak your native language? Most likely, it looked something like this:

And this process went on without stopping. The language you speak has become a tool for continuous communication with other people, including experiments, evaluation, mutual influence, attempts at correction, the extraction of new rules and principles ... - and so on until death.

In my opinion, TDD allows you to study code design in a similar way. It allows you to go beyond conventional programming, giving the programmer the ability to evaluate code in high-level criteria, a la "I can easily test this," or "I can separate this code from its context to run in an isolated environment" or "I can add a new behavior by adding code, not by changing an existing one. ” You may argue that such assessments can be obtained even simply by reading and discussing the code, but it is TDD that motivates the programmer to engage in dialogue with the code, think about “how should this piece behave?” Or “how should I design this part?” From different sides . I think that such an interactive style of creating code allows you to accumulate experience much more efficiently and faster than the traditional “write a lot, read rarely” approach. At a minimum, TDD motivates the programmer to see the code from different points of view.

The main role in this approach is played by refactoring. During refactoring, it is required to evaluate the existing code, understand and identify its problems, suggest a way to improve it, and then modify it in accordance with this method. (I don’t want to conduct a major refactoring without tests, and if I didn’t write tests in the first place, I’d hardly have enough of them to make me feel confident enough when refactoring.) The refactoring process allows the programmer to see different design options for one the same code, each of which may either have certain problems or not; This allows you to compare different design options and choose the most worthy of them. The programmer has the opportunity to compare the “before” and “after” states of refactoring and evaluate what effect his improvements in the code give.

You can compare the “before refactoring” design with incorrect or correct-but-poorly formulated language expressions. And various micro-refactoring techniques (for example, “replacing inheritance with delegation” or “introducing a variable”) - with the rules and principles by which these expressions can be corrected and improved. In this case, the refactoring itself will be similar to the act of applying these rules and principles for correcting expressions (code). And you can evaluate your changes through the presentation of how the programmer will perceive them, who needs to read and understand what you have done. If you cannot evaluate your work yourself or feel insecure, try to offer your options to others, ask for their evaluation. They can correct you or at least indicate a bad style. Just like you used this method to learn your native language, use it to learn the language of modular code design.


one . Read Chapter 3 of the Switch book to learn more about helping people change their behavior.
2 . I teach teams how to apply new practices through safe experiments, which helps them improve their work. I have not written about this in detail yet, but I promise to do it. If you can’t wait for a new article and want to know about it as soon as possible, contact me and we will work this way together.

Source: https://habr.com/ru/post/225929/


All Articles