I don’t write unit tests (that’d be almost as pointlessly redundant as type annotation) but I generate them automatically and they’re great. They let me refactor wildly and they help prevent old working code from breaking.
I like high-level tests, too. When I was first writing 7off (a markdown->gemini converter), I created a sample source file, and a hand-made target file that looked the way I wanted, and then as I was hacking, I kept looking at the diff between the program’s generated target with my handmade version. That’s actually still the only test in 7off’s test directory, which makes sense since it’s a single-procedure API.
For the other libraries I make, though, it’s pretty good to make sure they’re working. Their API is the finished thing, in some sense, and testing them is as high-level as you can get. Unit becomes the highest level.
It’s a quirk of Chicken’s module system that you can only test exported procedures.
Having unit tests is great. No more constantly neurotically checking in the REPL. Just relax and refactor away.