One of the expectations of every Atom is giving a shit. Part of this is caring about meeting an appropriate level of quality, which can be tricky. Software is such an abstract thing. People know that programmers write code, but code isn’t software, it’s a recipe to recreate the idea in the programmer’s head. Software really only exists when the computer follows the recipe or the programmer thinks through the steps. Unfortunately, the problems we solve on a day to day basis are so complex, that we need to make sure our recipe isn’t written in ways that subtly deviate from the desired result. To mitigate some of the risks involved in writing custom software, we use automated tests to continually ask questions of the software we’re building to find out when the goal and the product begin to diverge. We’ve recently found these automated tests to be more useful than we originally realized and have started to put them to other uses:
- learning new things,
- teaching other people, and
- evaluating applicants.
Testing to Learn Q&A is a powerful technique. With 20 questions you can find out what pretty much anything is (if you’re good). Just as the software we write is complex, so is the software we build on. When we’re learning new things tests end up being a really useful tool for gaining insight into the the nature of the shoulders we’re standing on. When I recently started ramping up on an ASP.net application, I found that Dave had written dozens of tests just to get to know the system. Not only did this approach help him find the answers to his questions quickly (Google can suck for technical searches), the clarity and precision of his formulation of the questions allowed me to learn his insights more quickly than would have otherwise been possible. Especially since I knew the answer to every question was “yes”.
Testing to Teach Dave wrote his tests for himself, and, because he kept them, I could follow the lessons he learned. In other cases we’ve written tests to help other Atoms learn the lessons for themselves. Sometimes we get together in our spare time to learn new technologies together, such as when we got together to explore using nosql databases in rails. In this case, we created a set of unit tests each person made pass with their NoSQL database of choice. A set of failing tests and links to a library reference end up being a great way to help someone get started with a new technology. Tests provide enough structure and specificity to provide context and a goal and also provide a mechanism to know immediately if progress is actually being made toward that goal. The cadence of fail, pass, fail pass and a thoughtfully ordered set of tests can make it surprisingly easy and even more rewarding to work through something new.
Testing to Evaluate An interesting aspect of automated tests as a form of “assignment” is that they’re guiding, but open ended. To see what someone produced to make the tests pass provides insight into their maturity as a developer and the creativity of their thinking. This insight has led us to try providing a test suite as an assignment to potential hires to see if they have what we’re looking for, in that they are dedicated, motivated, and can learn quickly.
This has worked out extremely well. Due to the nature of the assignment, a passing test suite shows that the applicant can learn new technologies quickly (or are already ahead of the curve). Reading through their solution gives intimate insight into the applicant’s skills as a developer in a way that can’t be talked around or misunderstood. Further, it provides a focus of discussion. Following up on unusual design decisions or code idioms provides opportunities for someone to really impress you or expose gaps in their outlook, education, or understanding you may have otherwise missed.
Ultimately these (somewhat) unorthodox uses of automated tests hint at the real reason why we find the right approach to building software to include writing an automated test suite. Even for a customer who’s willing to accept bugs in the final product, automated tests allow us to relearn the intricacies of code we haven’t touched for months, help us bring other developers up to speed as quickly as possible, and provide a mirror with which we can critically reflect on our approach to meeting our customers needs. These aspects make automated tests a vital productivity multiplier. And, besides, when you realize a solution to a problem solves other problems you never even knew you had, you’ve found a sure sign of a good idea.