-- Leo's gemini proxy

-- Connecting to ainent.xyz:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini; charset=utf-8; lang=en

Unit Testing & TDD, A Love/Hate Relationship


For most of my latest developments on smolver, my Gemini server, I have been practicing Test Driven Development (TDD), with which I have a love/hate relationship. In a previous post about a month back I mentioned this and wanted to expand on it.


smolver Devlog

Mention from previous post: Project Scopes


What Is It?


I won't go into too much detail here because this is not intended to be a tutorial on the practice, but rather my thoughts on it. In a nutshell, it can be summarized in a simple phrase: 'red, green, refactor'.


Write your test code, with data setup and assertions, before the code that you intend to test even exists. This will cause a compiler error, the first 'red'. Then you write just enough code to fix the compiler error, then stop. This means your assertions should fail, the second 'red'.


Next you write the bare minimum code to make your assertions pass. If you are TDD'ing a math library and your first test asserts that 2 and 2 can be added successfully, you would not write the code to do the math -- just return a hardcoded 4. The test passes, hence 'green'.


Rinse, repeat until all of your unit tests pass. Eventually your test assertions will force refactoring(s) to make your algorithm match the expectations in the assertions, confidently simplifying if not outright rewriting along the way - 'refactor'. In the math example, the hardcoded return value would be replaced with the actual math.


Another rule of thumb I like to keep in mind is that the system under test should not have any logic changes whatsoever unless and until you write a failing test to prove the existence of a problem or unhandled scenario.


Pros


Minimizes production code to only what is indisputably proven necessary

Increased confidence

Near-instant test results when run, paying time dividends when refactoring or implementing new requirement(s)

Easily catch regressions

Automation

Quantifiable progress metrics

Satisfaction


Cons


Tedious

Repetitive

Time consuming

Mind numbingly boring at times

Test code size: in my experience, lines of test code number roughly 4-7x that of the production code under test


To quote the previous post linked above:


>Ironically, unit tests are expanding the amount of work, but that is just the nature of unit testing and test-driven development (TDD). Ultimately, though, that is a good thing because it'll prevent regressions when refactoring... not to mention the nightmare that manually testing all the client certificate and CGI scenarios would be. That said, I do have a bit of a love/hate relationship with unit tests. The reasons for that could be in their own separate post, though.


Love/Hate


The pros outweigh the cons in many cases (it is a judgment call based on complexity of requirements, available time, deadlines, etc.), the 'love' angle.


The time commitment and tedium, however, are discouraging. I do overthink everything for sure, which adds time, but as a developer it is my responsibility to always be asking myself:


What could go wrong?

Are there incorrect assumptions baked into the code?

What might a malicious actor attempt in the event of an attack?

What might an incompetent user try in everyday usage?

What is the absolute worst that could happen?

How likely is that worst case scenario?

How hard is it to actually perform in practice?

How hard is it to detect and mitigate?

Is it feasible to encode this into unit test code?


These complications comprise the 'hate' angle.


Conclusion


All that said, I have no intention of stopping TDD when and where it makes sense.


What are your thoughts on TDD?

-- Response ended

-- Page fetched on Tue May 21 18:48:11 2024