📜 ⬆️ ⬇️

TDD is still compared to TLD - expert opinions



Specialists from several European universities - David Fucci, Giuseppe Scaniello, Simone Romane, Martin Sheppaird, Boise Sigveni, Fernando Uyaguari, Burak Turan, Natalia Juristo and Mark Oiivo - conducted a regular study on software testing effectiveness. They reviewed Test Driven Development (TDD) and Test Last Development (TLD) methodologies.


')
The researchers compared them for two indicators - the total speed of product development and the quality of the source code. The first methodology (Testing Development - TDD) again failed to meet the hopes that had been placed: the previously popular post-development testing scheme (TLD) proved to be no less effective. So for the above indicators, they did not find significant differences.

In that case, what explains the outbreak of interest in TDD when it first appeared? This methodology originated in the 2000s, so now the element of novelty can be safely discounted. Nevertheless, it remains a subject of controversy to this day.

The author of TDD Kent Beck identifies five main steps when using the methodology in practice:

• Write a new test case;
• Ensure that the launch of a new test will lead to a failure;
• Write a new one or modify the code so that the test is successful;
• Restart all other tests and confirm their successful completion;
• Make code refactoring, eliminating redundancy.

TDD and TLD have their advantages and disadvantages . Moreover, the advantage of one methodology is often a disadvantage for another.

• Test development speed

In the case of TDD, engineers have to spend 16% more time than with a TLD. This is due to the additional cost for switching developers between writing tests and basic code.

• Threshold of entry

TDD has a higher entry threshold, since it is not only a testing methodology, it is a different approach to software development. Therefore, the developer needs time to understand it and start using it in practice.

• Performance and maintenance

Thanks to TDD, software maintenance costs are reduced. Usually when using this methodology, the number of test cases is about 50% more than in the case of TLDs. This gives greater coverage and implies increased product reliability. Therefore, it is easier to accompany such software. Due to a well-designed architecture, the performance of a system developed using TDD is usually higher.

• Code size

The use of TLD can significantly reduce the amount of code compared to TDD. In addition, TLD code often has a simpler structure.

• Alteration

With TDD, developers can usually be sure that the changes will not cause unwanted effects. All necessary tests are run after each change. Thanks to development through testing, debugging of the software as a whole becomes more transparent and conscious.

In any case, each project is individual, but the general laws exist - just as there are various trade-offs.

Compromises


Ivan Khvatov:
Both are extremes. It all depends on the situation. In general, tests are a very sick and holivar topic. The question is not yet closed about which tests to write at all or not: units, functional, or integration (or all).
Let us give an example of a possible dialogue between the manager and the architect.
A: - Do we want 100% coverage?
M: - Yes, of course.
A: - Great, only this will delay the development by half and complicate the test code maintenance by an order of magnitude.
It is widely believed that the design of average quality will provide coverage for key pieces of code by 80-85%, and every subsequent 5% will take more and more resources (labor and time).

Moreover, TDD author Kent Beck once expressed the idea that unnecessary tests can be deleted. He calls such tests delta coverage, an additional coverage provided by a specific test suite. If this additional coverage is 0, then the test can be safely removed.

Kent Beck is a software developer, creator of software development methodologies such as Extreme Programming (XP) and Testing Development (TDD). Beck was one of 17 professionals who signed the Agile Manifesto in 2001.

The extra tests lead to additional maintenance costs. That is why the tests obtained in the early stages are usually too naive and can be deleted. This is especially true of the TDD methodology.

Martin Fowler led two simple rules of thumb that define the lower and upper limits of coverage: if you are not sure about your changes, and many of them lead to failures, but do not break tests, then there are too few tests. If too many tests break down with every change, then there may be too many tests.

Martin Fowler is the author of several books and articles on software architecture, object-oriented analysis and development, the UML language, refactoring, extreme programming, subject-oriented programming languages.

When should TDD be used?




The graph shows the speed of development of two projects. Blue sacrificed design and tests. Their goal is to realize the maximum amount of functionality as soon as possible. Reds, on the contrary, pay great attention to the design of the system and its testing.

Obviously, the blue ones leave a lot of “technical debts” in the code, which doom themselves to difficulties when expanding the system in the future and problems with its support.

But how does the red manage to keep the system flexible and move at a steady speed? One of the reasons is the use of TDD, writes Alexander Bindju, an expert on Agile and Lean.

He cites a number of advantages of TDD in the red project:

1. The simplest is that in such a project there are more tests compared to the usual approach. On the one hand, the number of tests per se does not guarantee a higher project quality and no errors. On the other hand, it all depends on how well you can write these tests. Many good tests will save you a lot of time.

2. The code becomes better. This is due to the fact that unit testing implies weak coherence of various modules of the system, otherwise it will be very difficult to write these unit tests. Therefore it is necessary to apply, for example, the principles of designing SOLID classes:
The Single Responsibility Principle
The Open Closed Principle
The Liskov Substitution Principle
The Interface Segregation Principle
The principle of inversion of dependence (The Dependency Inversion Principle)
Ultimately, this will give the entire system greater mobility and flexibility.

3. We can rebuild our project as much as necessary, adapt it to new requirements and not be afraid that after the next refactoring we will lose some already working functionality. Why can we afford it? Because after refactoring, we will run all the tests, and they will show us (with a green bar) that all business functions still work.

Therefore, according to Byndju, TDD forces us to write better code that is more convenient to test. And this means that we leave less technical debt in the code.
When does TDD start to overtake? Then, when the blue and red lines intersect. At this time, a team of blue with might and main begins to pay for debts. Hence the conclusion about the limits of applicability of TDD:
You can write code without TDD, if you are sure that it will not come to the dotted line. For example, you write a small project to automate the internal work, or create a business card site.
It should be understood that TDD is not a guarantee of the quality of your code, but with it it is easier to keep the system in tune, he concludes.

Not one "but"


David Hansson warns that enthusiasm for testing and trying to test everything in complete isolation (when we test only the current class, without its dependencies or auxiliary low-level classes) leads to a jumble of unnecessary layers of abstraction and over-sophisticated design.

David Heinemeyer Hansson is a Danish programmer, author of the Ruby on Rails web framework, Instiki wiki founder and race car driver, winner of LMGTE Am class (2014) and LMP2 silver medalist, world championship in endurance racing, 24 hours of Le Mans 2014 years in class LMGTE Am.

However, Martin Fowler has an important reservation to this effect:
When the system begins to grow, the problem is not in the number of levels of abstraction, but in the number of isolation levels. That is, the very fact that class A calls a class B method, which refers to class C, does not represent a problem until an isolation level appears in the form of an interface between each of these classes.
On the other hand, some Habra users are looking at this topic.

Feedback from user Volch :
It should be understood that the use of such methodologies as TDD implies that developers, not testers, write autotests. These are programming and coding methodologies, and not the development of a finished product, which involves a lot of people from PM and technical writers to admins and technical support. Developers often refer to the introduction of TDD-like as putting the testers duties on them.
Feedback from user Tagakov :
TDD is really not what testers should do. Their task is to write functional tests and, if they have enough qualifications, integration. TDD is not TDD, but developers from time immemorial have been testing, running their code and testing how it works, unit testing is more a formalization of this process.
Feedback from user Kunis :
If the test is written before and provided to the programmer as source data, it becomes a “technical requirement” (requirement). Of course, the one who writes the test must write and program all the required mocks in advance. Haha, I would not want to be the programmer whose responsibility it is to program tests for others.

Well, can a programmer himself write tests to his code in advance? In my experience, no and no. Programmers (and I and the vast majority with whom I discussed it) just think in the opposite direction. Yes, at first people tried to honestly follow the methodology. But after some time, they started to write the code first and then add tests to it. And after some time, the tests lost their versatility and meticulousness. And then “shtob was” was written at all, since they ask.

Does it even need it?

TDD Adaptation


One of the apologists for the development through testing, Alexander Lyulin, also expressed his opinion:
I do not use TDD in its classic sense. In general, it is unlikely that someone from professionals considers encyclopedic articles as a guide to action. We “suffered” our approach as part of a successful project, so we have real experience, not “stupid use of other people's ideas.”

Rather, we use synthesis from TDD and our own ideas about how to develop software. Even if these “external ideas” come from very smart people, they should be critically interpreted and adapted to the real company, the existing team and the strategy of development and quality assurance.

Oleg Balbekov, CEO of Vexor:
In our opinion, it is rather difficult to strictly separate these approaches and not at all necessary. It so happened that in our team we usually combine the use of both approaches in one project, and even sometimes when developing one block of code.

Well, for example, when we write part of a project to work with services through an API, we write first the tests and only then the code (TDD). However, after the implementation, it often happens that the tests written in advance are not enough and you have to add them, achieving 100% coverage (TLD).

Sometimes, even on very simple controllers (a normal resource with basic CRUD), first simple tests are written, and then a code (TDD). This gives us confidence that nothing is forgotten in the original implementation. In the future, with the development of the project, in most cases, the tests are written after writing the code (TLD).

Often there are tasks to implement the algorithm for known input / output data, here too the TDD approach is mainly used. If there are ready input and output data, then it is very easy to write a simple test using them, and only then implement this algorithm, being sure of the result.

Most often, the TLD approach is applied during refactoring. First, we test the existing implementation with tests and then rewrite it.

If we talk about the ratio of the use of TDD and TLD in projects, the TLD usually benefits. Developers who simply write tests are always more than those who are able to "think tests" and write tests in advance.

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


All Articles