Too many unit tests can slow down refactoring. But it can still be worthwhile.
Eg: I’ve done some deep algorithmic work on CRDTs lately and my code has a lot of internal parts which are all quite fiddly to implement correctly. For example, I’m using a custom btree with some unusual features as an internal data structure. Btrees are famously difficult to implement correctly, so my btree has both unit tests and fuzz tests to make sure it does what I expect. Having that test suite makes integration tests easier to triage, since I know any failures in my integration tests probably don’t come from the btree. And some btree code paths are probably rarely or never executed by my integration tests. But I still want that code to be correct. Testing it in isolation is the best way.
They’re a lot of other small pieces that I test like this - like saving & loading code, my graph traversal utility code (for comparing versions semantically) and so on. Low level unit testing can find bugs in utility modules while you write the module itself, not later (when you start using the module in some other code).
Eg: I’ve done some deep algorithmic work on CRDTs lately and my code has a lot of internal parts which are all quite fiddly to implement correctly. For example, I’m using a custom btree with some unusual features as an internal data structure. Btrees are famously difficult to implement correctly, so my btree has both unit tests and fuzz tests to make sure it does what I expect. Having that test suite makes integration tests easier to triage, since I know any failures in my integration tests probably don’t come from the btree. And some btree code paths are probably rarely or never executed by my integration tests. But I still want that code to be correct. Testing it in isolation is the best way.
They’re a lot of other small pieces that I test like this - like saving & loading code, my graph traversal utility code (for comparing versions semantically) and so on. Low level unit testing can find bugs in utility modules while you write the module itself, not later (when you start using the module in some other code).