Thank you for asking me this question. In general, I do not have a strong opinion on which of the approaches is better than others. The only advise I feel to give is to try to learn, practice and experiment as much as you can with all of them (better if you try to exercise on the same Code Kata, using different approaches, so that you will have more material to think about). All of them are worth learning.
The reason why I invite people to practice all of these approaches, is because all of them have PROs and CONs, and based on the context and the purpose of what you want to achieve, you can understand which approach will be the best to use. In my opinion, the context and the purpose, are the main players that dictate when an approach is better than another. There are times - for example - when you don’t need any of these (spikes, code you know will be thrown away in the next 30 minutes, trying out if the code you wrote can work, etc …).
Sometimes, when I want to learn something new about a Framework, or a Library (like ranch, or cowboy, or plug), I prefer the London School approach: It gives me an “immediate” feedback that things are working with a minimal walking skeleton (being able to spawn a server and handle requests), and the Test-Driven pace gives me the scope of the thing I want to explore and learn at that time, proceeding at small steps (e.x. how to handle a GET? How to handle a POST? How to get HEADERs? What happen if the route is not defined? What about the sessions? And so on…), and, last but not least, having a safety net (tests from the outside) that give me enough confidence when I will try my braves refactoring moves. This is just an example, the topic is so vast, that’s why there are entire books on that matter.
The more you learn, the more will be easy for you to find out your trade-offs.
From my side, I see testing as a design tool, that also act as mechanism to prove the code is working as expected.
I think that is a book worth reading.