
Why you should drop everything now and start writing unit tests
With my first TDD experience, insight dawned on me. The last 2-3 years the information “TDD is good”, “You need TDD” has been attacking from all sides, which is why the brain instinctively begins to resist the implanted information. Before that, I had never practiced TDD in commercial projects, but when I started, everything fell into place. I want to show an interesting point of view in my opinion on automated tests, which I have never heard from anyone.
Over the past year, I read several good books, not even on TDD, but simply on good programming / design practices that explicitly state "if you do not practice TDD, drop it and start now." But anyway, after re-reading enough of the theory, it was not entirely clear where such perseverance and confidence of the authors came from, that it was right for everyone.
Compile? I once realized that not only. More precisely, not in order to get some kind of binaries, DLLs. As I type in the code, from time to time I look out the window with errors and correct if something appears. This wonderful opportunity is provided to me by a parser that spins in the background and checks the code for the presence of simple errors. But sometimes this is not enough. Sometimes the compiler needs to compile / compile all the project sources to find an error. This situation happens, for example, in ASP.NET, when we remove the public method from our usercontrol, but we don’t see any errors, since the compiler must rebuild this user control. In such cases, you need to completely rebuild the project, but note that we essentially do not need what we got as a result of the assembly, at this stage only information about the absence / presence of errors was important to us.
Moreover, the compiler in this situation is needed mainly to indicate our programming errors. Usually these are simple errors, but we love the compiler because it directly points to them. Remember one of the drawbacks of loosely coupled architectures? Due to the fact that late binding prevails in them and prefer composition instead of inheritance, we can no longer catch many errors while writing code.
Calling the DoHeavyBreath method of the Luke class is a logical error not visible to the compiler. This is a mistake of a higher level. But programming is yearning upward every year, becoming more abstract, so we need tools to deal with complexity. One of the necessary tools is a parser of errors of a higher level. Just as the compiler points out syntax errors to us.
The code above should be rewritten like this for greater literacy:
What changed? We all have the same logical error and the compiler still cannot detect it. But now we can use TDD to detect this error. We are creating a method for testing the main method. In the simplest way
I personally see in this approach nothing more than a tool to combat the complexity of high-level architectures. The brain has its own limit, which it can cover, and the necessary tools expand these limits. At high levels of abstraction, the compiler loses its role as a "pointer to errors", since it cannot cover the bulk of errors. TDD is able. Of course, the technique will still be developed. Ideally, the developer should know all existing bugs (including logical ones) before he compiles the project, he will be helped by existing and future tools, with which TDD is mainly associated. This development can even be noticed. Those interested can read about NCrunch for Visual Studio. I think for other IDEs such tools are also available that relate to continuous testing. In a nutshell - this tool runs unit tests all the time in the background and you immediately see the test results as you write code without recompiling. You will notice some similarities with how the compiler in the background searches for syntax errors and produces as it finds it. And now the tools have become so smart that they also show logical errors. Of course, you can express your dissatisfaction with the fact that you still have to write tests yourself and you can lose sight of some kind of logical error, but I think this is still ahead. Maybe sometime tests will themselves be generated from some formal description of business logic. In any case, it is better to rejoice at what is, than to cry for what is not. how the compiler in the background searches for syntax errors and issues as it finds it. And now the tools have become so smart that they also show logical errors. Of course, you can express your dissatisfaction with the fact that you still have to write tests yourself and you can lose sight of some kind of logical error, but I think this is still ahead. Maybe sometime tests will themselves be generated from some formal description of business logic. In any case, it is better to rejoice at what is, than to cry for what is not. how the compiler in the background searches for syntax errors and issues as it finds it. And now the tools have become so smart that they also show logical errors. Of course, you can express your dissatisfaction with the fact that you still have to write tests yourself and you can lose sight of some kind of logical error, but I think this is still ahead. Maybe sometime tests will themselves be generated from some formal description of business logic. In any case, it is better to rejoice at what is, than to cry for what is not. but I think it is still to come. Maybe sometime tests will themselves be generated from some formal description of business logic. In any case, it is better to rejoice at what is, than to cry for what is not. but I think it is still to come. Maybe sometime tests will themselves be generated from some formal description of business logic. In any case, it is better to rejoice at what is, than to cry for what is not.
Over the past year, I read several good books, not even on TDD, but simply on good programming / design practices that explicitly state "if you do not practice TDD, drop it and start now." But anyway, after re-reading enough of the theory, it was not entirely clear where such perseverance and confidence of the authors came from, that it was right for everyone.
Why do you need a compiler?
Compile? I once realized that not only. More precisely, not in order to get some kind of binaries, DLLs. As I type in the code, from time to time I look out the window with errors and correct if something appears. This wonderful opportunity is provided to me by a parser that spins in the background and checks the code for the presence of simple errors. But sometimes this is not enough. Sometimes the compiler needs to compile / compile all the project sources to find an error. This situation happens, for example, in ASP.NET, when we remove the public method from our usercontrol, but we don’t see any errors, since the compiler must rebuild this user control. In such cases, you need to completely rebuild the project, but note that we essentially do not need what we got as a result of the assembly, at this stage only information about the absence / presence of errors was important to us.
What am I getting at?
Moreover, the compiler in this situation is needed mainly to indicate our programming errors. Usually these are simple errors, but we love the compiler because it directly points to them. Remember one of the drawbacks of loosely coupled architectures? Due to the fact that late binding prevails in them and prefer composition instead of inheritance, we can no longer catch many errors while writing code.
class Darth
{
public void FeelForce()
{
...
}
public void DoHeavyBreath()
{
...
}
}
class Luke : Darth
{
public void DefeatAllEnemies()
{
...
}
}
void main()
{
Luke luke = new Luke();
luke.FeelForce();
luke.DefeatAllEnemies();
luke.DoHeavyBreath(); // нет, это не то, что может делать Люк
}
Calling the DoHeavyBreath method of the Luke class is a logical error not visible to the compiler. This is a mistake of a higher level. But programming is yearning upward every year, becoming more abstract, so we need tools to deal with complexity. One of the necessary tools is a parser of errors of a higher level. Just as the compiler points out syntax errors to us.
The code above should be rewritten like this for greater literacy:
abstract class Jedi
{
public void FeelForce()
{
...
}
public virtual void DefeatAllEnemies()
{
throw new NotImplementedException();
}
public virtual void DoHeavyBreath()
{
throw new NotImplementedException();
}
}
class Darth : Jedi
{
override void DoHeavyBreath()
{
... // do heavy breath
}
}
class Luke: Jedi
{
override void DefeatAllEnemies()
{
... // defeat all enemies
}
}
void main()
{
Luke luke = new Luke();
luke.FeelForce();
luke.DefeatAllEnemies();
luke.DoHeavyBreath();
}
What changed? We all have the same logical error and the compiler still cannot detect it. But now we can use TDD to detect this error. We are creating a method for testing the main method. In the simplest way
void test_that_luke_cannot_do_heavy_breath()
{
try
{
main();
}
catch(NotImplementedException ex)
{
Assert.Fail("Unimplemented method was called!");
}
}
I personally see in this approach nothing more than a tool to combat the complexity of high-level architectures. The brain has its own limit, which it can cover, and the necessary tools expand these limits. At high levels of abstraction, the compiler loses its role as a "pointer to errors", since it cannot cover the bulk of errors. TDD is able. Of course, the technique will still be developed. Ideally, the developer should know all existing bugs (including logical ones) before he compiles the project, he will be helped by existing and future tools, with which TDD is mainly associated. This development can even be noticed. Those interested can read about NCrunch for Visual Studio. I think for other IDEs such tools are also available that relate to continuous testing. In a nutshell - this tool runs unit tests all the time in the background and you immediately see the test results as you write code without recompiling. You will notice some similarities with how the compiler in the background searches for syntax errors and produces as it finds it. And now the tools have become so smart that they also show logical errors. Of course, you can express your dissatisfaction with the fact that you still have to write tests yourself and you can lose sight of some kind of logical error, but I think this is still ahead. Maybe sometime tests will themselves be generated from some formal description of business logic. In any case, it is better to rejoice at what is, than to cry for what is not. how the compiler in the background searches for syntax errors and issues as it finds it. And now the tools have become so smart that they also show logical errors. Of course, you can express your dissatisfaction with the fact that you still have to write tests yourself and you can lose sight of some kind of logical error, but I think this is still ahead. Maybe sometime tests will themselves be generated from some formal description of business logic. In any case, it is better to rejoice at what is, than to cry for what is not. how the compiler in the background searches for syntax errors and issues as it finds it. And now the tools have become so smart that they also show logical errors. Of course, you can express your dissatisfaction with the fact that you still have to write tests yourself and you can lose sight of some kind of logical error, but I think this is still ahead. Maybe sometime tests will themselves be generated from some formal description of business logic. In any case, it is better to rejoice at what is, than to cry for what is not. but I think it is still to come. Maybe sometime tests will themselves be generated from some formal description of business logic. In any case, it is better to rejoice at what is, than to cry for what is not. but I think it is still to come. Maybe sometime tests will themselves be generated from some formal description of business logic. In any case, it is better to rejoice at what is, than to cry for what is not.