2 ms·
I've been in software development for over twenty years. I have similar feelings about maximalism in a lot of areas. Many organizations producing software tod
by agentultra 4y ago
I've been in software development for over twenty years.
I have similar feelings about maximalism in a lot of areas.
Many organizations producing software today don't share many values with me as an engineer. Startups aren't going to value correctness, reliability, and performance nearly as much as an established hardware company. A startup is stumbling around trying to find a niche in a market to exploit. They will value time to market above most anything else: quick, fast solutions with minimal effort. Almost all code written in this context is going to be sloppy balls of mud. The goal of the organization is to cash out as fast as possible; the code only has to be sufficient to find product-market fit and everyone riding the coat-tails of this effort will tolerate a huge number of software errors, performance issues, etc.
In my experience practicing TDD in the context of a startup is a coping mechanism to keep the ball of mud going long enough that we don't drown in errors and defects. It's the least amount of effort to maintain machine-checked specifications that our software does what we think it does. It's not great. In other contexts it's not even sufficient. But it's often the only form of verification you can get away with.
Often startups will combine testing strategies and that's usually, "good enough." This tends to result in the testing pyramid some might be familiar with: many unit tests at the bottom, a good amount of integration tests in the middle, and some end-to-end tests and acceptance tests at the top.
However the problem with TDD is that I often find it insufficient. As the article alludes to there are plenty of cases where property based testing has stronger guarantees towards correctness and can prevent a great deal more errors by stating properties about our software that must be true in order for our system to be correct: queued items must always be ordered appropriately, state must be fully re-entrant, algorithms must be lock-free: these things are extremely hard to prove with examples: you need property tests at a minimum.
The difficulty with this is that the skills used to think about correctness, reliability, and performance require a certain level of mathematical sophistication that is not introduced into most commercial/industrial programming pedagogy. Teaching programmers how to think about what it would mean to specify that a program is correct is a broad and deep topic that isn't very popular. Most people are satisfied with "works for me."
In the end I tend to agree that it takes a portfolio of techniques and the wisdom to see the context you're working in to choose the appropriate techniques that are sufficient for your goals. If you're working at a startup where the consequences are pretty low it's unlikely you're going to be using proof repair techniques. However if you're working at a security company and are providing a verified computing base: this will be your bread-and-butter. Unit tests alone would be insufficient.