Humans are fairly simple-minded creatures. Only when you accept some of your own limitations can you start to think about your abilities in a helpful way. We all tend to like receiving rewards for even the smallest of tasks. If it wasn’t for the instant feedback of PHP, I might have never learned to program. I blame the instant feedback of PHP, HTML and CSS for inspiring the wonder and fascination which started in my pre-teens and will hopefully last well into my future.
Writing tests for software was pitched to me as a necessary evil for production-level code. It was the code that didn’t actually do anything. It was the boring stuff in the corner that seemed weird and was full of strange concepts like fixtures, mocks and the code that looked like it did nothing important. It was only until much later that I understood what tests really were: a formal way to get the same feedback I’ve gotten all my life when scripting. Consider a typical programmer workflow:
- Make a change to your source code
- Run a test script or refresh the web page
- Manually verify the output based on your expectations on the behavior and the given input.
…wait, those steps sound an awful lot like testing. That’s not a mistake. Formal tests automate what was typically a manual process for programmers. That’s satisfying and rewarding. Everyone should love tests. Tests are awesome.
At this point, I practiced writing tests. I was really bad at first. I had no idea what I needed to mock out and had no idea how to write testable code (hint: side-effects are bad). I believe a critical experience in any programmer’s development is whenever they change the implementation of a function and all the tests work without needing modifications because the tests were testing the behavior which, in this scenario, did not change.
That’s neat and all… but what happens when other people want to contribute to the project? I teach them to run and make tests! Cool!… but other people are lazy and unreliable… And even I, the self-proclaimed test master of the universe, can forget to run tests before committing code. The solution to this problem, of course, is continuous integration — specifically gating continuous integration. The premise is simple: Do not let a test-breaking change into the code base by automatically running the tests on every commit and reject the change when the tests fail.
This process can be expanded to include linting tools and testing with multiple versions of software. I only have so much patience to guide people to following language style standards like PEP-8 or one of Google’s many style guides. I want to focus on real problems not whether or not you left an extra space at the end of a line, but… I also don’t want my project to have a bunch of random spaces at the end of lines. Gross. I am unreasonably happy every time automated tooling catches a style issue like that because it means that a program just did something that I didn’t want to do. That’s why programmers even exist in the first place, right?
Test your code. You will be able to sleep better at night.