Mr Vladimir Khorikov started as an adviser on general programming topics, including Domain-Driven Design, functional programming, enterprise software development patterns and best practices. Over the years, he authored several popular Pluralsight courses and a lot of articles.
Lately, he shifted focus to unit testing with a central message of teaching software developers how to make unit testing painless. Also, he wrote a book on this topic and currently working on an in-depth course about Test-Driven Development.
In this post, we share a very short interview with Mr Vladimir Khorikov where he gently shares his thoughts about the current state of unit testing.
We want to express our gratitude to Mr Vladimir Khorikov for kindly taking the time to answer our questions.
Question #1 – We’ve talked about the importance of automated testing in the software industry for a long time. However, it is still not common to see technical authorities discussing the economic implications of this practice, as you do when you say that “The goal [of testing] is to enable sustainable growth of the software project.” What led you to this insight?
V.K. – Mostly, it’s the disappointment in the message that is sent by most books and online resources about unit testing. Most of them approach the topic from the perspective of “Let me show you how to write your first test”, which is fine in and of itself but doesn’t give the full picture. The “why” behind unit testing is as important as the “how” — the former drives the latter. Without a proper understanding of why you need unit tests, it’s impossible to know why some unit testing practice is important.
Also, few books or online resources focus on the hidden costs of unit testing. There are two major components of such costs: maintainability (more or less understood by the software industry at this point) and resistance to refactoring (almost no one ever talks about it). I like to think of these costs as an unseen part of unit testing. The seen part is how good your tests are at protecting you against regressions (bugs). The unseen — how much that protection costs you. In the book, I make an explicit focus on both the seen and unseen parts.
Question #2 – What is the biggest impediment, in your opinion, for well-intentioned and experienced developers to be able to produce good tests?
V.K. – The biggest one is not taking into account the costs of unit testing, particularly, the resistance to refactoring component. Because of that, people tend to produce a lot of low-quality tests. Instead of helping the project to grow, such tests drag it down. The reason is that they require you a lot of time to maintain and update after refactoring. The 2nd order effect is your distrust in tests, which leads to fewer refactorings and, ultimately, code deterioration.
Question #3 – There is some consensus that code coverage is not a good quality metric for testing. So, why it is still so used and mentioned?
V.K. – Partly because there are no other metrics that you could check automatically, and partly — because it’s still better than nothing. Code coverage is not entirely bad, it’s just only good in one direction — it’s a good negative indicator but a bad positive one. It can show you that your unit tests aren’t good enough (when you have particularly low coverage of core areas in your project, say, less than 50%), but a high coverage number isn’t a guarantee of good test quality.
Question #4 – Are there any metrics, provided by static analysis tools, that you consider relevant during the tests development process?
V.K. – Unfortunately, code coverage metrics are the only metrics you can gather with tools. The assessment of the test quality is a manual process.
Question #5 – Practices like “Behavioral Code Analysis” argue that codes with the most commits and authors are those where technical debts have the greatest impact. What are the impacts of this idea for classifying tests as good or bad?
V.K. – The same analysis can be applied to determine which areas of your code should be unit tested first and where you should put the most of your focus when reviewing test quality. In most line-of-business applications, it’s the domain model (aka the business logic). Focusing on the code quality of your domain model (and proper unit testing of it) usually provides the best return on your effort.
Question #6 – Do you plan to write more books on software testing? What can we expect?
V.K. – Writing a book is a huge undertaking (I’ve spent a year writing this one), so I don’t plan on writing another book anytime soon. Maybe at some point in the future, though.
Question #7 – Besides your book, what additional resources do you recommend for those who want to learn how to write better code?
There are three areas of software development that have a big overlap: unit testing, domain-driven design (DDD), and functional programming. For example, in unit testing, it’s important to follow the Humble Object pattern and separate the domain model from out-of-process dependencies (such as the database). This is what functional programming advocates too, and even imposes as a restriction in some languages, such as Haskell. DDD provides tools to build a proper domain model.
I recommend the DDD book by Eric Evans as a go-to book about Domain-Driven Design. As for functional programming, I very much like the writing style of Scott Wlaschin, his articles at https://fsharpforfunandprofit.com/ helped me understand functional programming. He also has a very good book called Domain Modeling Made Functional (https://fsharpforfunandprofit.com/books/)