Poka-Yoke is often used in manufacturing to prevent errors. However, it's not extensively used in Software Engineering. Errors are only discovered and corrected during testing rather than prevent upfront. Perhaps one of the reasons is that errors in software are less costly compared to hardware errors.
The term originated from baka-yoke meaning idiot-proofing. It's changed to poke-yoke to be less harsh. Therefore, it's more often called mistake-proofing.
Here, it will explain briefly what is it, and how I've used it to prevent errors in code, as well as prevent other software engineers I work with to make errors. Lastly, it'll give an outline of how you can implement it in your software development process.
How it is applied
Poka-Yoke is seen everywhere in our everyday lives. They are in:
- Power plugs
- SD cards
- USB drives
- RAM slots
So how do you make sure they don't happen? You build them in a way where you can't insert them the wrong way. The USB drive contains a notch on one corner to prevent users from inserting it in the wrong orientation and causing damage. It achieves two things. It prevents you from making an error and it also provides usability on how to do it right.
Aside from that, they have error-correcting features built internally that detect and correct errors in data transfer, preventing data loss and corruption.
In short
If I had to sum it up in one line, it's this
The way to make sure something doesn't go wrong is to make sure it can't go wrong
Input validation
The most common and obvious example of its application in software engineering is user validation in an application user interface.
- Dropdowns: Prevents a user from selecting non-relevant values but also gives them hints of options.
- Textbox: Has to check for correct type, format, or range. Provides an error message to help with valid values.
I won't go too much into this since they are such clear examples that any developer should know anyway.
How I've applied it
Linting tools
Linting tools are awesome and ESLint particularly is a great one that should be in any JavaScript/Node.js developers' arsenal. They help you to catch bugs and problems early. Aside from that, they help to maintain a specific coding style in your projects that enforce good coding style practices. Hint: Use established coding style like Airbnb JavaScript Style Guide instead of trying to roll out your own.
The way to apply Poka-Yoke is to force them into your development pipeline. Add ESLint configs to all JS projects' source code. That way any developer should be able to run the linting on their local device during development. The easiest way to get it running is to install it through the VS Code plugin.
Some setups go even further (such as Vue-CLI) by preventing you from compiling and viewing your Front-End UI when there's a linting error that can be as minor as a trailing space at the end of your line of code, which I honestly love.
However, for most projects, you can't always ensure your development team installs the ESLint plugin and verifies their code. You can Poka-Yoke it even further by adding linting verification to the CI/CD pipeline. Therefore, preventing anyone from pushing code or merging Pull Request with errors or that doesn't follow the correct style.
Writing test
Adding automated tests is the best step you can take to produce and ensure reliable software. It can be used to prevent errors by ensuring tests are run consistently by yourself and others in your team. It's the best way to make sure no one makes changes that break the existing application. It's an effective way to make sure the existing software is working reliably.
You can set automated tests to run on every code change, commit, or pull request to catch errors early in the development process. However, this process can be bypassed by deleting or commenting-out the test cases. Unfortunately, the level of Baka is likely too much for baka-yoke. It's an edge case.
Assertions and errors
Write assertions (or throw errors) to assert unlikely cases in your code. Assertions imply cases that are unlikely to happen but are so catastrophic when they do that it's better for the application to just panic than fail silently.
const assert = require('assert');
...
if (projectType === 'a') {
doThis();
} else if (projectType === 'b') {
doThat();
} else if (projectType === 'e') {
doSomethingElse();
} else {
// Should not reach here
assert(
false,
'Why is our internal system sending an invalid projectType? It should not happen. Fix your code!',
)
}
The following is a way to ensure someone else working on the system doesn't make a certain mistake. It also gives information on how to do it correctly as the code itself implies what should the correct values be.
The process
Here is the process of implementing Poka-Yoke with a real-life example so you can implement it yourself for any software development scenario.
Scenario
Let's say you want to change a value in an environment variable or project configuration. As part of the twelve-factor, you store your config in the environment and you do not commit your environment file to the source code for safety and security reasons.
You would like to fix an issue with the environment variable and its value.
BACKEND_API=https://api.twm.me/development/api/v1
You have found that the value should not have a trailing /v1
as you then wouldn't be able to use a /v2
in the code. Therefore, you have made a fix to the code to use the environment value in the following format.
BACKEND_API=https://api.twm.me/development/api
However, this is going break the code for everybody in your team does not update their environment variables.
Step 1: Identify the potential mistake
Firstly, is to think of the potential error or mistake someone can make concerning what you are doing. In the above scenario, someone may not update their environment variable as you desired. Sure you may have posted an announcement in the team channel. But realistically, not everybody is going to read it or update their environment then and there.
- Potential mistake: Using an old environment variable value
- Potential error: The code stops working in development, possibly worst is it stops working in production later on if it's not caught early.
Step 2: Develop and implement the solution
Next, is to develop a solution to prevent the mistake and indicate the correct approach. The easiest thing is to add a check in the code to ensure they are not running an old config.
const endpoint = process.env.BACKEND_API;
if (endpoint.endsWith('/v1')) {
throw Error("The env config has been updated. Please use '/development/api' instead of '/development/api/v1'");
}
The above prevents the error from happening and also provides a clear solution.
Step 3: Test, monitor, and improve
Lastly, is just to test your above solution to ensure that it works. Observe your solution on preventing someone else from making the mistake and how they come to the solution.
Conclusion
Poka-Yoke helps you to create better software, but more importantly, it makes you a better collaborator. It helps improve productivity by quickly preventing errors and mistakes from happening. Failing silently and unexpectedly can cause distress in your team and product. Therefore, it's always best to take measures to prevent them from happening.