3 ms·
Let me have my take on TDD. (I work with legacy corporate systems mostly so that's how I am biased) TLDR: it never had a chance of working The basic problem o
by lmilcin 6y ago
Let me have my take on TDD. (I work with legacy corporate systems mostly so that's how I am biased)
TLDR: it never had a chance of working
The basic problem of TDD is that it has a huge cost to it and therefore you have to do it right to not only get any benefits but to just get even.
In a perfect TDD utopia, all developers would start with a set of clear, complete requirements and then implemented each requirements with a clean and concise test and then ensured their code passes the test. Then later, with not much additional effort, these tests would be used to verify that whatever shenanigans you are doing to your project still cause functionality X to do Y when Z happens.
Unfortunately, this fails to capture whole diversity of the development reality.
- It is rare you get clear and concise requirements. Most corporate code is just something that a developer decided should happen in a situation, not a result of meticulous discussion and planning. As such, preserving these requirements in stone has much less value than one might think because now instead of preserving objective truths about how the application should work you are spending time to preserve what an intern Joe decided this should be doing with probably little regard for entire system.
- There isn't a way to tell your tests are complete and good quality. Whereas an application must implement functionality and must be doing (something) right because otherwise your users would notice missing or faulty functionality (users are ultimate verification of your app), tests can be as incomplete as you want and as pointless as you like and will still "pass". Thus, completeness and quality of tests is completely on a whim of developer. Guess what, if they can't get the app right will they be able to at least get tests right? And if they can get the app right the lack of tests is the least of their problems. By having feedback on how teh application functions from their users the developers are "forced" to deliver something at some level of quality. By having no feedback on tests quality developers are not forced to deliver anything (other than to satisfy tests) and if they are not forced to do something no user or manager will ever look at they are most likely do only what is absolutely necessary (to pass automated gates).
- Most developers want to be done with a task and there is this bunch of stuff they have to do that is just annoying because it has no immediate bearing on how the application functions. That bunch consists of refactoring, documentation, code reviews and guess what, tests. Do you know why documentation is typically poor if at all? Do you know why code reviews mostly focus on little stuff and rarely attack big problems? Because overwhelming majority of developers don't put their heart into stuff that does not bring them closer to achieving the goal (except reading HN, taht is, and other forms of procrastination).
- Management. While they will usually "require" tests, I have never in my life seen that a development was extended to get more time to "get tests right". Usually tests is something you have to do as quickly as possible to meet the requirements rather than something that is seen as core to the project functioning.
- Developers. Most developers are already overwhelmed with stuff they need to learn to be able to functioning in increasingly complex technological jungle. Microservices? Devops? Full stack? Given choice to spend time learning skill of doing tests right and learning above not many developers will choose tests. Making quality tests is a skill that like any other skill require you to apply yourself.
- Refactoring functionality in a legacy system (which is theoretically exactly the reason you might want tests) requires that you know exactly what you are doing. This means understanding what changes are "safe". When I refactor a piece of code I try to form a hypothesis that the change is not going to break functionality and then prove it by following code leads (how the function is used, etc.) until I am satisfied. Doing hundreds or thousands of refactorings one by one requires from me that I am 100% certain I know I am not breaking anything. If I were to use tests to help me do refactorings I would also have to have close to 100% trust in that these are correct. Unfortunately, there are no tests to test that tests are correct or complete. Therefore, I cannot use tests to replace my process of following code leads and this makes tests useless for my needs.
- wenc 6y agoThis. It's not that tests have no benefit -- they do, especially for complex refactoring (though even for that, as you say, tests are rarely exhaustive enough to engender full trust). But outside of the narrow confines of production programming, it's rare that the requirements can be specified completely up-front. In the initial stages of development, coding is very much a discovery process. Code is often evolved rapidly and drastically, such that any test written is a throwaway. And some of these tests/mocks aren't easy to generate. In data intensive applications, it's especially a chore to have to generate new mock database objects each time the code changes, and with completely different data characteristics to boot (in order to test different facts of the code). The psychological tedium of doing this will put off most developers. The potential drag on productivity extends to more than just the time required to write test + code: the whole pace will feel sluggish and the dev is liable to feel demotivated. I see tests being more useful as a retrospective addition, once the code has stabilized and the use-patterns established.
- lmilcin 6y agoThat is good point. In my initial stages I like to explore the problem and tests just get in the way of being able to refactor everything very quickly. Maybe I want to put some dirty implementation first and then once I think I understand the problem better quickly fix it? Maybe I want to start refactoring it without knowing where it exactly will lead me? The problem is tests do not help with these initial stages, they only help if you know exactly what you are doing. And once I am done with the initial stage I want to move to another problem. I don't like sticking with the same module to now do the documentation, tests, etc. Once something works and I am satisfied I move on.