Bugs are common in software development [citation needed].
I decided to introduce checklists in the development process of our team. This page in our wiki explains the reason:
Checklists are an essential component of high-quality processes, e.g. in aviation, medicine or construction. But checklists can also be a major obstacle. We want to build high quality software without losing a fast and flexible process. How does that work? We use checklists in a targeted manner and consider when and how checklists make sense.
A very good explanation of what is important can be found here (refers to the very readable Checklist Manifesto).
Step 1: Identify “Stupid Mistakes” That Cause Failure → see Known Traps and Post Mortems.
Step 2: Seek Additional Input From Others → for example in retro’s
Step 3: Create Simple “Do” oder “Test” Steps → in a checklist, which should become part of the process
Step 4: Create Simple “Talk” Steps → which can take place after the Daily Standup or as part of the Code Review
Step 5: Test The Checklist
Step 6: Refine the Checklist → nothing is perfect; review the success in a retrospective or when things are not going well
Important: The checklist must only contain the most important sources of error. Completeness is not the goal, but to ward off the greatest risks without slowing down the process.
We use checklists at three different points of the development process:
A Ready Checklist is used to ensure key business and architecture aspects are considered, and the ticket can be picked up by a developer without (much) further back and forth.
A Code Review Checklist covers business-critical classes of error and things hard to fix later (e.g. database changes). It leaves general adherence to engineering standards to the reviewer’s discretion (we use MoSCoW there).
The Approval Checklist is used by testers and subject matter experts to ensure the feature is fit for use (e.g. works on mobile).
I can confirm that people sometimes roll their eyes, but consistently using the checklists leads to much better quality.
One difference between hospitals and programming is that code is entirely digital, so a lot of check lists can be replaced with automated tests. For example:
Instead of “did you run the code to make sure it works?”, have test cases. This is traditional test cases. (Fully end-to-end testing is very hard though, to the point that it can be more feasible to do some QA testing instead of trying to automate all testing.)
Instead of “did you click the links you added in the documentation to make sure they work?”, have a test that errors on broken links. Bonus is that if the docs link to an external page, and that link breaks a month later, you’ll find out.
Instead of “did you try running the sample code in the library documentation?”, have a test that runs all code blocks in docs. (Rust does this by default.)
Instead of “did you do any of these known dangerous things in the code?”, have a “linting” step that looks for the dangerous patterns and warns you off of them (with a way to disable in cases where it’s needed).
Of course not everything can be automated (most of Gunnar’s list sounds like it can’t). But when it can be, it’s nice to not even have to use a checklist.
Bugs are common in software development [citation needed].
I decided to introduce checklists in the development process of our team. This page in our wiki explains the reason:
We use checklists at three different points of the development process:
A Ready Checklist is used to ensure key business and architecture aspects are considered, and the ticket can be picked up by a developer without (much) further back and forth.
A Code Review Checklist covers business-critical classes of error and things hard to fix later (e.g. database changes). It leaves general adherence to engineering standards to the reviewer’s discretion (we use MoSCoW there).
The Approval Checklist is used by testers and subject matter experts to ensure the feature is fit for use (e.g. works on mobile).
I can confirm that people sometimes roll their eyes, but consistently using the checklists leads to much better quality.
One difference between hospitals and programming is that code is entirely digital, so a lot of check lists can be replaced with automated tests. For example:
Instead of “did you run the code to make sure it works?”, have test cases. This is traditional test cases. (Fully end-to-end testing is very hard though, to the point that it can be more feasible to do some QA testing instead of trying to automate all testing.)
Instead of “did you click the links you added in the documentation to make sure they work?”, have a test that errors on broken links. Bonus is that if the docs link to an external page, and that link breaks a month later, you’ll find out.
Instead of “did you try running the sample code in the library documentation?”, have a test that runs all code blocks in docs. (Rust does this by default.)
Instead of “did you do any of these known dangerous things in the code?”, have a “linting” step that looks for the dangerous patterns and warns you off of them (with a way to disable in cases where it’s needed).
Of course not everything can be automated (most of Gunnar’s list sounds like it can’t). But when it can be, it’s nice to not even have to use a checklist.
Our code review checklist looks like this:
Have GDPR annotations been added for all fields? (all fields that are stored persistently count)
Do interactions with the user happen that should be recorded as events?
Is data collected for later use (logging doesn’t count, anything in a database does)? Are there reports or some other way to find this data?
Are there no unencrypted credentials in any files?
Are there notable changes that should be recorded in an ADR?
(I replaced the links with public alternatives)