The Psychology of Code Testability
Table of Contents
The Psychology of Testing
Testing FundamentalsThe three things you need to know about testing. 1: Read the code, 2: Mind your dependencies, 3: Sharpen your environmental Ax. It’s easier to do it properly than do it wrongly. It’s quicker and easier to write test code than not. While the test code is almost as long as the working code, it’s much simpler and quicker to write. Testing needs to be built in from the ground up. When the application is complete, you can’t go back and retro-fit the testing. People don’t write testing because they don’t know how... but this is a secret. Don’t be afraid.
Write Tests FirstIf you want to test your software, test it at the point of writing. Once it is written, it’s too late. How would you make code that is deliberately hard to test? The difficulty is structural. The more layered the dependency, the harder it is to test. With more control over variables, testing is straight forward.
Testing Large and Small ProjectsBigger projects are no harder than small projects - there is just more work. Find the stuff you actually need and then work with them. The more nested the dependencies, the harder things will become for you. The magic is in writing testable code, rather than writing code tests. It’s not about writing code that pretends to be a user. If you can replace all the other components with dummies, eventually you can break the code down into its simplest parts. Unit tests are easier than end-to-end testing. Only once the components are working properly, can you begin to look at end-to-end testing.
Testing Classes and Business LogicHow do you test a class? You test it by replacing the class’s sub-dependencies with ‘friendly’ dummy modules. Then everything that goes wrong is in the class under test. The real sub-dependencies can be plugged back in later. Keep business-logic separate from object graph construction and lookup. Mixing these two types of coding makes testing hard. It’s easier to replace real modules with friendly modules.
Testing ExamplesTesting after the fact means you assume the code works, then try it out. The problem is largely insoluble. Can you write the test before the code? If you write the test first, it will probably be able to survive changes to the code. If you know what the tests are actually trying to achieve - the stories of the tests - you’ll be able to write code that can be tested by it.
Testing code vs. Production codeWhile simple objects can be trusted to be benign, more involved objects need careful handling. The ‘new’ operator is best avoided. The graph shows the lines of production code vs the lines of test code. Ideally these should be developed evenly and at the same time.