Aphorisms on software development - part I
(published: 2023-11-04)
A forever incomplete list of mental beacons for use in the darker corners of the trade. First up: on quality and testing.
Over the years I have gathered a collection of thought razors which have assisted me in various situations, from better framing the problem landscape ahead, to quickly dismissing "alternative facts" spouted by unfortunate future targets of the Peter principle.
Some of these are tame and almost common sense, others are controversial. Some might even be considered offensive. But I have found each and every single one of them to hold true in the overwhelming majority of situations.
There are quite a few of them, so this post is the first in a series, with said heuristics grouped by subject, but otherwise in no particular order.
Enjoy responsibly.
Aphorisms regarding software quality:
-
The upper bound for the quality of any codebase is primarily determined by the personal coding standards of the "dirtiest" senior developer on the team, and is mostly independent from other factors such as architecture, code style, tooling or methodologies.
-
Removing the "dirtiest" senior developer from a team immediately increases the upper bound of code quality, but that by itself does not guarantee that the code quality will increase.
-
The lower bound for the quality of any codebase is initially determined by the personal coding standards of the most pedantic developer on the team.
-
The lower bound for the quality of any codebase asymptotically approaches zero over long enough periods of time.
-
All code eventually looks bad to someone at some point. Sometimes this says nothing about the code, but quite a bit about the developer.
-
Knowing the difference between "I don't understand this code" and "this code is hard to understand" is a crucial, yet sometimes absent, skill for experienced developers.
-
The only intuitive, and useful, measure of code quality is still, undisputedly, WTFs/min.
-
Above 25k SLOC or 25 REST endpoints, your so called "modern microservice" is guaranteed to just be a plain, normal, boring, possibly crusty webservice.
-
To the uneducated eye, sophistication is indistinguishable from bloat. Here is an extreme case.
-
To a developer, service quality is irrelevant and code quality is paramount. To an end user, it's the other way around.
-
Service quality and code quality are orthogonal. When faced with the situation where you're frequently asked to sacrifice one for the other, you're either dealing with someone who is careless about the business, or you're dealing with someone who is careless about you.
-
The old saying "if you can't spot the fish, you're the fish" from the game of poker applies equally to software development by replacing "fish" with "pig".
-
All of the above notwithstanding, a truly temporary, well contained and surgically applied hack is worth more than one hundred man-hours of discussions on software architecture.
Aphorisms pertaining to software testing:
-
All software is rigorously tested. If not by developers and QA, by end users and foreign hackers.
-
Software is occasionally tested in development and continuously tested in production. This is independent of testing discipline.
-
Do not help anti-testing zealots win arguments by writing slow, flaky, brittle or bureaucratic tests.
-
It's fine if you don't want to write tests for your code, so as long as you promise to test everything again manually whenever anyone changes it.
-
Unit tests far away from their units will rot.
-
Tests aimed at concrete are essential. Tests aimed at porcelain are not just useless, they're harmful.
-
In any project, the physical meaning of test coverage is, roughly speaking, the probability of not needing a debugger for that project.
-
A project with integration tests outside of the main repository has no integration tests.
-
Integration tests that can only run in a specific environment that is hard to reproduce will rot.
-
Integration tests that do not run as part of a CI pipeline don't run at all.
-
Code that's hard to test is a quality issue. Not being able to make it easy to test is an education or skills issue. Not wanting to make it easy to test is an attitude issue.
-
If there's no production code to add or change, then there are no tests to add or change.
-
A well written test with wide coverage is much more valuable than its equivalent verbosity in wiki pages.
-
The specification changes, the test changes, the production code changes. In this order.
-
Incomplete specifications lead to incomplete tests, which in turn allow buggy code to land in the hands of users.
I may have missed a few, but any razors that were missed will at some point land on one of these pages. More aphorisms and other subjects to come in the future. However, for now, that's all I got.
Keep your ears up for future posts.