I myself was skeptical of the "unit testing". And I am still somewhat skeptical about the common/usual practices around the unit testing.
The first time I got the value of unit testing was, when I saw a bug report was converted to a test. The bug resolves when the test passes, easy and simple! Then I knew, all the tests there, are some kinds of checks against bugs, reported or foreseenanticipated. And as all those tests has to be passed before the software is shipped, those bugs are not coming back again. So, these tests are defining and guarding the expected behavior/outcome of the software.
Now if we go back to the first principle, what is testing"testing"? Not unit testingthe "unit testing", just testing"testing"? Is it checking if a software is doing what it was expectedsupposed to do. If it is an application, QA people do itthe check. But that is a time-consuming, error-prone, manual job. Wouldn't it be nice if we can automate it and then run the automated tests every time a task is done, or any code is updated?
But everything cannot be automated. The software is likely dependent on database or some kind of external services. Also, the user is going to use different kind of inputs etc. So, now we can either mock the external affairs, or instrumentalize them. The mocked first type of tests with mocking are now called unit tests, the second type is integration test.
And both of these tests are treating the software as a black box, implementation is hidden. So, these tests would not change with implementations or refactoring. But developers may want to test parts of their own implementations, which hidden from the external tests, for their own peace of mind. Then there can be many small tests alongside the implementation. But this kind of tests will likely change with implementation. I love Rust for making this type of test so easy. In any file, we can make a test block/module, which have access to the functionalities in the file and can test them. No need to change access modifiers just for testing. After using Rust's testing style, testing in other languages/frameworks feels quite artificial to me.
At the end, I am still skeptical about the current testing practices in the development world. The Java-like strict OOP, layered architecture, onion architecture, artificial interface-per-class makes the unit tests just some obligations to fulfil, without adding much real value. That is my current opinion. Thanks for asking the question!