One thing which I tried doing differently this time with one of my side projects is to do TDD from the start. Someone may ask why? It's just a side project no? (1/n)
One reason is that, for some of my past side projects, when someone creates an issue/submits a PR. I wouldn't necessarily remember everything which I did/why I did x instead of y, when I would have authored it (more on how this can be improved later) (2/n)
Coming back to say reviewing a bugfix/feature PR. Having no coverage for those specific routines which were modified, would mean I either would have to rely on my gut feeling, or I would have to test it by pulling the changes. (3/n)
This in turn would do two things, for one, it would create a form of resistance, as to even review the PR, it would mean me having to also manually test out things and see if changes are not having any regression/the feature works as expected (4/n)
The 2nd thing which would be a by-product of this, is that for these changes, I am doing the testing manually, which would mean I would have spent say x amount of time doing it which could have been used for something else. (5/n)
This x amount of time, would vary wildly, depending on many factors. Some can be, how good are the docs, which would allow 1 to replicate the setup quickly? Familiarity with the codebase so as to remember all the cases, corner cases included, so that you don't miss them. (6/n)
It's natural for someone to not remember minute details of the codebase, when they are looking at it again after weeks/months/years. Naturally, they will need some time to again get acclimatized to the codebase which they had interacted/authored. (7/n)
This is where tests for the routines bring in value. It's your 1st level of safety net which you have spread out to weed out changes which would break your expected flow/behaviour. (8/n)
Again, 100% code coverage doesn't mean that your software is bug free/free of issues. The only real test is when your software is getting used by someone. This is where it should behave/perform as it is expected out of it. (9/n)
But having a high coverage would also mean, that you can refactor without fear, and have a faster feedback cycle than before, i.e testing for changes manually. (10/n)
The 2nd level of safety net can be end-to-end integration tests for your codebase, which would run with each commit, the same way your unit tests would run with each commit. (11/n)
The value here out of these 2 safety nets, is that you will be able to ship with more confidence, compared to not having these 2 safety nets at all. (12/n)
Now as to why I prefer TDD? There's a lot of literature around this, but for me personally I feel it allows me to think in terms of contract and how a routine should behave. As the behaviour is what we would really like to test for routine rather than the exact mechanics (13/n)
To add to it, the tests would act as documentation when I would go through them, telling me how a particular routine behaves under different scenarios. It also encourages baby steps and a faster feedback loop for something functional as fast as possible. (14/n)
For reference, a few years ago, I wrote this thing called plino (spam filtering as an API) back in college days. I wasn't aware of the testing literature back then (still learning), but what I ended up writing was an integration test for the api https://github.com/tasdikrahman/plino/blob/master/tests/test_plino_app_api_response.py (15/n)
It has absolutely no coverage for other routines which are present. It's just by luck, that the codebase is small and someone will be able to quickly grok it and understand what is happening, but the overload of the same happening in larger codebase does affect maintenance(16/n)
If I have to compare it with bhola, I ended up having coverage for even a small routine which just does a POST to an external API https://github.com/tasdikrahman/bhola/blob/master/spec/services/slack_notifier_spec.rb. Someone might think it's an overkill, why do we need all this if barely anyone is using this? (17/n)
Another question which comes is, at the end it would be the functioning lines of code which your consumer of the software would be interacting with, not the tests. So why write tests? But would skipping these mean, taking a hit on maintainability, I feel the answer is yes.(18/n)
As for bhola https://github.com/tasdikrahman/bhola/, I feel I would definitely have more confidence and faster feedback cycle when adding changes to it in future. (19/19)