How not to shoot yourself in the foot

    Without the use of unit tests and TDD it’s very easy to shoot yourself in the foot. With tests and TDD it is much more difficult to do, but if you succeed, you will be left without a foot.

    Recently, a lot of articles on TDD have been published on the hub; they cause an mixed reaction among readers. There are more and more words, young developers reading these articles are wandering in the haze of definitions and terms, somewhere in the subconscious understanding that TDD is probably great.

    In this article I will try to explain what the conversation is about. What is TDD for and how to use it carefully.

    What is TDD in a nutshell? - This is a developer writing tests before implementing the functionality.
    On the advice of Roy Osherov We divide the issue of TDD applicability into two:

    • Why write tests?
    • Why write tests before implementation?


    You test anyway



    There is not a single sane developer who would not test it before delivering the program to the client. Yes, there’s a developer, in any production the product is tested at least visually. Take at least aircraft manufacturing, at least weaving bast shoes - everywhere one way or another the product is checked. This also applies to us. So since we are still testing, why not automate this process? Why, after each small change, manually check all the functionality, if you can do it with the click of a button?

    Not everyone needs it



    On our projects, developers who do not write tests, we call Chuck Norris, because they are incredibly cool and we sincerely envy them.

    Why doesn't Chuck write tests?


    His code is perfect

    There are never bugs in the Chuck Norris code. He is never wrong. If you find a bug in Chuck’s code - try talking to him about it - you will immediately realize that this is actually a necessary feature of the project.

    He does not need code documentation and communication on the project

    In fact, documentation is just one way of communicating. By documenting the code, we communicate with the team (with the present and the future) that is working on the project. Tests are the best documentation. The developers do not read paper documentation at all, and these pieces of paper and files disappear somewhere all the time. It is far from always possible to figure out the written comments on the code - what exactly did the author mean. In tests, you can immediately see how the code works, what they want to get from it.
    Chuck doesn't need all this - he works alone.

    Perfect memory

    What projects can you work on alone? Only on those where you bought a plane ticket to a warm country in which the customer will definitely not find you. On all other projects, you work at least together - you and you in the future. And you need to communicate with yourself on the subject of implementation. Chuck does well without it - he remembers everything in his projects.

    Refactoring without problems

    Chuck does not do refactoring at all, because his code is immediately perfect. So, he simply doesn’t have situations when he needs to change or optimize something and try not to break anything in the process.

    Why don't you write tests?


    I don’t understand what it is and why.

    A strange excuse, especially after you read why Chuck Norris does not write tests.

    No time

    With tests, you will save time. How much time do you spend now debugging and manually testing your applications? Yes, tests take time to write, but it pays off.

    It is impossible to test

    Almost everything can be tested, and what is not possible is not necessary. Mock frameworks help a lot with this. Unit tests need to test the logic in your project. Testing the interaction with the database, with external services, and so on - this is already a conversation about integration and functional tests.

    This is not my job.

    We have testers - let them test. The fewer bugs you leave to testers, the less you will have to work with them in the future. Work more efficiently - employers appreciate it.

    I'm fine as it is

    Congratulations, you are Chuck Norris.

    Tests save time. Tests prevent the repetition of errors. With their help, the code is documented much more efficiently and during refactoring you can feel much more comfortable.

    So why write them before implementation?




    Kent Beck's " Clean Code That Works " is all about TDD in this picture and phrase . We want our code to work, and we want it to be clean. That's all. And using the steps Red-> Green-> Refactoring, as practice shows, this is easier to achieve.
    At the Red stage, we write a test, evaluate the design of our function, and fix it right there. We make sure that the functionality is not implemented and the test fails.
    At the Green stage, we achieve the goal - “Code That Works” - our implementation begins to work.
    At the last stage of the Refactoring cycle, we realize the goal - “Clean Code” and it is still “That Works” ... and move on.

    The main idea of ​​TDD is not tests at all, it is a design issue. When you write a test, you ask yourself what you want to do and how best to implement it. You’ll test your code design right there, along the lines of Keep It Simple Stupid and You Ain't Gonna Need It .

    What gives TDD is confidence. Are you sure that the test will be written - if you write tests after functionality, then there are a thousand reasons for not doing this. You are confident in your design. You are sure that everything that you wanted is realized.

    TDD is not a silver bullet


    Unfortunately. There are no silver bullets at all, as Frederick Brooks wrote in his book . And TDD is no exception. You can still be wrong, you can be wrong in the tests. Unit tests are not limited to everything; you may need integration and other types of tests. TDD is definitely not enough to cover all your code. And most importantly - you will still need to think :) And do not relax.

    How to start using TDD?


    ... described in the TDD article - it's like snowboarding . In short - you need to be careful. You need to be aware of what you are doing and why. And the best option is to learn from someone who is already using this approach. If this is not possible - books, screencasts, articles + letters to those who write books, articles and record screencasts, if something is not clear.


    You will enjoy using TDD. It is really great to see the green stripe after the red. And it is addictive. Although you need to be careful and see the limits of applicability of this wonderful TDD thing.

    The risk of being left without a foot


    Unprepared start

    If you do not understand the essence of the matter and rush headlong into TDD, you run the risk of throwing out a ton of your time in vain. And not every leadership will tolerate this. First you need to learn how to write tests. And then move on to TDD. Seamlessly, without sudden movements. The brain itself will switch at some point.

    TDD for TDD

    TDD is cool, everyone writes about it, they talk even more, let's and we will. It’s fundamentally wrong. Very close to an unprepared start - understand how it works, then get started.

    Going beyond applicability

    Using TDD, you need to test the logic of the project. For everything else, there are other types of tests. And not every logic lends itself to such an approach - an excellent example is described in the article Why unit tests do not work in scientific applications

    Fanaticism

    We work primarily for customers. If after half an hour you have an important presentation and you urgently need to implement some new function, you will not be understood if you start writing a test and do not have time to write an implementation. You need to understand that sometimes TDD needs to be sacrificed for business purposes.

    What to read for a start


    Test Driven Development: By Example The

    first book should be the book of Kent Beck - it contains all the basics of TDD from the author of this approach. Required reading.

    The Art of Unit Testing: With Examples in .Net

    A book that will help you master the first skill - writing tests. About TDD there are just a couple of words. Examples in C #, but it doesn’t matter - it will be useful to everyone. A good review of the book can be found here .

    Refactoring: Improving the Design of Existing Code

    Martin Fowlerao's classic refactoring book that helps you keep your code clean.

    Refactoring To Patterns

    Another refactoring book. In it, Joshua Kirievsky shows the connection between refactoring and design patterns. I recommend reading right after Fowler.

    Working Effectively with Legacy Code

    A book by Michael Feathers that details how to work with legacy code correctly. It is interesting how the author defines the very concept of “inherited code” - it is code that is not covered by tests :) It will be very useful for those who work with such code.

    I hope that you will write tests and use TDD, but only where it is really necessary. Take care of your feet.

    This article is based on my recent talk at the .NET Developers Conference .

    Also popular now: