TDD, why use it?

Test Driven Development (TDD) is a concept that can be difficult to grasp for new developers, as it is easy to fall into the idea of why would you spend time writing code to only test your actual code. However, not only TDD is a common requirement in many job posts, it is actually a common engineering methodology that big companies like Facebook are know to be using. This leads to the conclusion that there must be good reasons for companies, especially of that size, to use this approach.
Three of the most notable advantages of TDD include:
1- Lower debugging time.
2- Creation of a low level documentation for other developers.
3- Overall increased control throughout the codebase.
— Lower debugging time? How?
This is how a regular error without TDD would look like. (not actual code).
undefined method whatever for nil:NilClass
filename.rb:line_32At this point, the normal debugging progression would be to go to line 32 of the filename.rb.
31 ...
32 @post.author.whatever
33 ...next step would be to go to where this @post.author is defined.
def create
@post = Post.new
@post.title = params[:title]
@post.author = Author.find(params[:author_id])
@post.save
endThe possibilities are painfully too many at this point — What is params[:author_id]? How is the form sendingparams[:author_id]? Even worst, are Authors being saved properly? Ugh!
With a TDD approach, however, you would have caught the mistake at a much lower level of abstraction:
error: expected "Author.last.name == 'carlos'" to eq true, got falseEffectively removing a significant amount of layers as this error would take you straight to the Author model/controller/form, saving time as you would get a lot closer to the ‘bug’.
class Author
# only william shakespeare is allowed to be an author
validates :name, inclusion: { in: ["william shakespeare"] }
end— Creation of a low-level documentation for other developers to follow?
Again, when done correctly TDD would leave you with a file containing valuable information about your code as each testing unit contains a description of what a feature does, and how it does it.
This could become a useful tool for recently hired developers to get accustomed to the codebase.
— Overall increased control throughout the codebase?
When fixing a bug without TDD you are under the constant fear that you could have broken something else while working on the codebase.
With TDD you have the freedom of playing around as you have specs testing for possible ‘side effects’, effectively giving you that peace of mind after implementing or debugging a feature.
— disadvantages of TDD
1- Time consuming at first: You have to spend time writing tests before writing your actual code. Meaning that it takes longer for TDD developers to see results.
2- (not so true) Requires a skilled developer: TDD is about being able to anticipate possible ways of implementing a functionality even before starting to write the code for it. e.g. “I’m going to need a form, this form will have these inputs, should be sending a patch to x path”. This skill can become stronger with experience.
— conclusion
TDD has the potential of being a determining factor in the success of an application. It can become crucial when problems arise or when implementing a new feature. It saves significant amount of time when debugging by giving you a more specific and useful error message. It provides you with a thorough low-level documentation that can be useful when bringing new developers into your codebase. And lastly, it provides developer with a safety net that will ensure the codebase stays manageable and optimizable without the fear of breaking something else.
These advantages sound more relevant as an application grows larger, however, it can be argued that small applications would see no significant benefit from TDD, as a decently skilled developer should be able to interpret general error messages accurately enough to be able to fix the issue in a small size application. This leads to the conclusion that TDD is mostly application-size dependent, however, is a technique that should be learned if advancing your software development career is your goal.
