How about, they were both utterly terrible?
Like, what does it matter?
British Empire were shits, enslaved people, stole relics/art/wealth, murdered people, tortured people, probably experimented on people.
Nazis were shits, enslaved people, stole relics/art/wealth, murdered people, tortured people, experimented on people.
The Nazi’s atrocities are certainly better documented.
Both because they are more recent in history, and because they were the losers. The winner’s atrocities were less likely to be documented throughout history.
Tests.
Target the “business logic”.
You can structure your code to facilitate unit or integration testing.
Setup tests for the key functionality. Whenever a bug gets reported, create a test or test case to address that bug, fix the bug, and ensure the test now passes.
Have a staging environment, so the site can be interacted with and tested without touching anything in production.
You can push to this often, and request some help with QA to ensure nothing is broken.
Have a testing environment. Again, a complete duplication of the infrastructure.
Set up end-to-end tests. These automate interactions with the entire application.
Have tests that run against key features. “Setup appropriate state, load form page, fill in form, click button, check that database entries are correct”… “setup appropriate state, check that submission summary shows correct data”.
These are quite handy, but a lot slower and fragile than unit and integration tests.
There are automated testing platforms that can capture a “good” state of a website, then use image matching to ensure further runs visually match what it should look like.
These are normally expensive and finiky.
Hopefully you will get to a stage with your testing that your unit and integration tests catch 90% of your potential bugs, and e2e tests will ensure the core functionality is working correctly.
Then, as you do a bunch of work, you can run your tests, see they all pass, and be confident.
Finally, I will say that tooling like frameworks and typescript can catch a lot of these errors quite quickly.
However, these won’t catch logic bugs - which is what tests are for.