The fundamental principle of Software Engineering is to always focus on Fast Feedback. Everything else decomposes from this
This principle enables us to check that we are going in the right direction, and change course with minimal rework
Important factors to achieve Fast Feedback are to work in small batches, and with a test first approach
-
Fast Flow - When a change is made to a working system and something breaks, the most likely location of the issue is in what just changed. If that change is kept small, then it is far easier to find and also reason about how to fix the issue.
-
Independent Deployment by Vertical Slicing - the only way to know if a change is correct, is for it to be deployed all the way into the production environment. So if it depends on other updates to be part of a complete working system, then it will get blocked until they are also ready, slowing down the deployment and increasing the batch size. Each change should be selected as an end-to-end independently deployable update.
-
Technical Debt - prioritise tech debt which will slow you down from releasing. If some code is a little messy somewhere that doesn't need to be touched for a long time, it's not as important as part which you know will change soon. There will always be more ways to improve the code, but we are not here to write perfect code. It needs to be good enough to solve the problem, and not slow down delivery. Keep things simple by waiting for real pain signals before making improvements
- Fast Runtime
- When the whole test suite is run together it should be fast
- For example: A few slow high-value tests are acceptable if the overall suite stays fast
- Predictive Of Correctness
- The full suite should provide evidence that the code will work in production
- Each type of test may have different trade offs of how realistic they are vs how fast they are to run
- There maybe a combination of end to end, integration and unit tests, but they should provide an overlapping coverage of everything important to know that the code is safe to release
- Low Cost of Ownership
- Tests which are hard to understand have a high cost - use either Behaviour Driven Development, or Arrange Act Assert to organise the tests
- Tests which are coupled to the implementation are hard to change - only interact with the System Under Test through its public interface, and prefer Outside-In testing to provide the largest possible opportunity for refactoring without needing to change the tests
- Tests which are Flakey undermine confidence and are not Predictive - invest extra time in figuring out these issues. If the system is flakey in the test environment, it's likely it's flakey in production as well
- Test Driven Design
- Writing the tests first helps to get the intent clear, which acts as documentation of what the code should do
- Writing the tests first enables you to clearly write the minimum code to complete the required functionality
- Ensuring the test fails before the implementation is complete, ensures that your tests are not giving you false positives