Writing good simple, easy-to-read test code is actually faster than write complex, hard-to-understand test code says Gerard Meszaros
Gerard Meszaros, the author of xUnit Test Patterns – Refactoring Test Code, will be speaking during the Continuous Delivery and DevOps Day at #AgileIndia2018 on Improving the Maintainability of Your Tests. He is also conducting a post-conference workshop titled Test Refactoring Workshop – Improve Your Unit & Component Tests!
Gerard is an independent software development consultant and trainer with 30+ years experience in software and over a decade of experience in agile methods. He has coached teams and taught courses as far afield as China, India, Japan and Europe. He is also the CTO and Product Owner of FeedXL.com which provides a web-based diet optimization tool for horses.
Gerard gives us a peek into his talk and workshop at #AgileIndia2018 through this interview with the AgileIndia team
What are ways in which we can evaluate the quality of our unit tests?
Unit tests should clearly describe how we expect the code under test to behave. If it is hard to understand what the code should do, the test quality is lower than we would like. Also, if it is hard or high effort to determine the various usage scenarios for the code from our unit tests, our tests aren’t clear enough or named well.
What are common test smells that you generally notice?
The most common issue is Obscure Test. This happens because most developers think about what the compiler needs to run the test rather than what the reader needs to understand the expected behavior of the code under test. This results in test code that is much too verbose, suffers from Primitive Obsession and Test Code Duplication. Ironically, learning how to write better test code also results in much better production code because many of the same issues are seen in production code.
How can we make test cases easier to understand and maintain?
The key practices that result in easy to read test code is focusing on the expected behavior of the production code. I like to use the Given-When-Then format because it encouraged thinking about the expected behavior rather than the mechanics of exercising that behavior. This is probably the biggest single change in my philosophy since I wrote the book (in which I used the Setup-Exercise-Verify terminology. Unfortunately, the other common template, Arrange-Act-Assert suffers from the same focus on mechanics rather than intent.)
Why is it important to refactor our tests?
It is important to refactor all our code because very few of us can write perfect code the first time. We learn a lot about our domain as we write the code (both production and test) and we need to incorporate that learning into the code itself by refactoring the code to match our domain more closely. This is what makes the code easy to read. And it is what makes our test code more effective at communicating *what* the production code does (as opposed to *how* it does it.)
What are some key challenges developers face when they start improving test quality? How can they overcome it?
The biggest challenge is inertia. (We’ve always written the code this way.) And time pressure. (We don’t have time to refactor our test code.) This is actually a fallacy because writing good simple, easy-to-read test code is actually faster than write complex, hard-to-understand test code. A few minutes spent refactoring the last test you wrote can make writing the next test much quicker. And if we have several more tests to write to cover all the usage scenarios, we end up *way* ahead.
What are the key takeaways from your talk and workshop for the attendees?
Improving the quality of your tests is a fun, high-value activity that will make your work more enjoyable. And it will probably improve the quality of your production code as well!