The economic aspects of microtest TDD are inextricably tied to the operational aspects of it. If we concentrate only on the artifacts involved, we will lose the picture and misunderstand the value proposition.
As a professional geek, the heart of my job is changing rigidly structured imperative text in collaboration with other humans, in order to meet a variety of locally or temporally aligned goals.

That's fancy talk for "I change code, in community, for money."
The central event is the *changing* of code. (It's remarkable to me how very little attention we pay to this in the trade. Instead, we focus almost exclusively on getting to a state -- usually imaginary -- where no changing occurs.)
So, if changing code's the thing, there are some factors, in the actual operation of changing the code, that seem to loom extra large when I talk about production or efficiency or economics.
Factor: To change code, I have to understand what it does. The relationship is direct, topping out at the Heinlein-esque "grok" level, where I can change code with great rapidity. Bottoming out at "I have no clue", where every change takes a long time and a lot of courage.
Factor: My productivity is highly dependent on sizing. Roughly put, the bigger the change, the more I have to hold in my head while I do it, and the closer I come to hitting the limit of my human mental bandwidth.
Factor: Highly structured imperative text is finicky and peculiar and inhuman, so I do better when I can frequently and easily confirm that what I said is what the text-receiver heard is what I meant. The faster I get that confirmation, inch by inch, the faster I go.
Factor: Most of the changes I make that break things are actually rather simple mistakes. Though we love rocket-science errors, they are a tiny minority of real change-breakage. Most bugs are -- a technical term here -- "dumb-assed". Off by one, inverted condition, and so on.
Factor: The next most frequent cause of my change-breaks is when I make regressions without knowing I have done so. I see a lot of "toggle-bugs", where I fix A and break B, then I fix B and break A, and so on. Knowing that my code here didn't break my code there is really useful.
Factor: I don't work solo. Other people are changing the code even as I'm changing it. If I have to worry that they suck and are breaking my work, or that I suck and am breaking their work, I go very much slower.
So with all these factors in mind, and likely some I forgot to mention, we can almost ease in to the economics of microtest TDD. Before we do, though, there is one more really important aspect of all this we need to both understand and accept: perfection is not on the table.
Perfection is not on the table: It is not possible for me to make changes to my highly structured imperative text with perfect certainty that they contain no errors. This is not an opinion, and it's not because practice is shoddy, it's a direct consequence of the halting problem.
So the question we're approaching is not now or ever the question of "how can we prove our changes work?". We can't prove that, under any circumstances. We are permanently thrown to ask a lesser question: "how can we become reasonably confident that our changes work?"
This is a really important distinction, because the number one source of misunderstandings about TDD, microtest or otherwise, is that it is a failure if it can't prove that no bugs are created by a given change.
Okay, reeling all that back in. Let's talk about how microtest TDD works economically. The short version: it's the cheapest way I know to combine the factors above (and others) to mitigate the effect of my most frequently occurring mistaken changes.
Microtests increase the speed of my understanding of both my own code and other people's. They form a kind of "grokking scaffold" around the shipping code. The tests are little usage snippets, they're answers to common questions, and they're executable documentation.
Microtests inherently *size* the changes I make. They are so small themselves, the changes they're validating must also be small. This leans in to my very real very stark very severe limits on mental bandwidth.
Microtests catch illegal highly structured imperative text by running it in a very narrow exercise case. This is particularly useful when I'm working with dynamically typed languages. They only show such errors when they *run*, and microtests run the code w/o running the app.
Microtests are *particularly* good at catching that category I called dumb-assed mistakes. It's because they're so tightly focused around my branching logic, exercising it case by case in little chunks. It's not that they make hard bugs easy, it's that they make *easy* bugs easy.
Microtests persist in the source vault, they accumulate as the codebase accumulates. This means that toggle-bugs are caught the instant they happen. Nothing stops all possible regression, but microtests catch many of them at a very small expense.
Microtests capture not only my expectations/usage of my code, but others, of theirs, and we can use them to *cross* connect, e.g. my expectation but on your code. A broken microtest is a first-rate collaboration focus, something many of us need frequently.
You can follow @GeePawHill.
Tip: mention @twtextapp on a Twitter thread with the keyword “unroll” to get a link to it.

Latest Threads Unrolled: