Tuesday, June 30, 2015

Book Review: The Art of Unit Testing with Examples in C#

I recently finished reading The Art of Unit Testing with Examples in C# by Roy Osherove (Amazon link). This is the 2nd edition that came out in 2013. I actually finished a couple weeks ago, but I've been taking time to digest the material. (I've mentioned it herehere, and here.)

The short version is that you should read this book if one of the following applies to you:
  • You want to get started with unit testing.
  • You want to improve your testing techniques.
  • You want tips for successfully incorporating unit testing in your work environment.
This is a short book (about 230 pages), and it is a fairly easy read.

Was It Useful to Me?
The easiest way to answer this question is to take a look at the bookmarks I put into the book while I was reading.

Interesting Topics Marked
It's pretty easy to see that I found lots of passages to be useful to me. I've been a believer in unit testing for a while now. And this helped validate some of the approaches that I've used and also see some shortcomings in some approaches that I've used. I can't say that I agree with everything Osherove says, but I agree with a high enough percentage of it that the differences are negligible.

There are quite a few things that stuck out for me. First is a clearly defined list of qualities that good unit tests have. And then it goes beyond that to describe the problems that keep us from having good unit tests (such as not having sufficient isolation) and looking at practical techniques for correcting those problems.

I also like that although he recommends TDD as a well-established way of building testable code, he does not proscribe it when first starting out. He says that it's more important that developers understand unit testing first. Having good unit tests is more important than a process. Once you understand the testing techniques, you can start to explore those other processes.

There is also quite a bit of time spent on isolation -- which is a huge issue when we're creating tests on discrete units of code. I appreciate that Osherove takes the time to go through the testing frameworks and isolation frameworks that he has found useful in his own work. (And this is one reason why I've looked into NUnit a bit further.)

When dealing with the various frameworks, I also appreciate that he tells how his tool set has changed since the publication of the first edition of the book and the reasons for that.

He also spends a bit of time talking about stubs and mocks and the differences between them. I will admit that I have not been very precise in my language when dealing with the fake objects that are in my tests. I am aware of this now and am working on being more accurate.

Osherove also provides some signs that you may have an over-complicated test or a test that tries to test more than one thing. For example, if you have control statements (switch, if, else) or loops (foreach, for, while), then you probably have logic that should not be in a test.

Along with this are a set of "smells" that you may have a problem with your tests. This includes things like constrained test order. If your tests have to be run in a particular order, then you have a dependency or shared state between tests that needs to be corrected.

I really appreciate a practical view of code coverage. Code coverage is not a silver bullet. Here's a quote:
"You could easily have close to 100% code coverage with bad tests that don’t mean anything. Low coverage is a bad sign; high coverage is a possible sign that things are better."
I have worked with teams that only cared about having 100% coverage (because this was something they could measure) without concern about the quality of the tests. In this situation, some developers will simply game the numbers so that they look like they have good results -- especially if the managers only care about the numbers. (And unfortunately, I saw that happen.)

An entire chapter is set aside for successfully bringing unit testing into your work environment. This is probably one of the most important sections. Finding the right champions, getting people of influence on your side, and setting realistic expectations are all key to a successful implementation.

My History With the First Edition
I'm a bit embarrassed to tell about my experience with the first edition of Osherove's book (back in 2009). I actually fought against unit testing in our environment back then. But (and this is a really big but), I wasn't fighting against unit testing itself, I was fighting against unit testing as the silver bullet that would fix a broken team. I used passages from the first edition to back up that viewpoint.

And I still believe that. Unit testing itself will not fix a broken environment. In this case, the team leaders were looking for a magic process that would idiot-proof development. What they really needed (at least in my opinion) was to invest in their developers. I am all about making developers better. Unfortunately, I saw them go through a new process every 6 months trying to fix things. It made me really sad to watch that.

So, I really enjoyed reading the second edition of the book because I'm now coming at it from a more productive direction. I have been extremely successful with unit testing, and I agree that it's one of the marks of a true professional -- someone who cares about the quality of the product that they deliver. (But that's another story.)

Wrap Up
So the short version is that The Art of Unit Testing is filled with great guidance and advice. As mentioned, where Osherove describes a technique that is different that what I have been doing, I explore it further.

For example, I've been swayed over to the side of not using Setup methods in test suites. Historically, I've used Setup methods, but after looking at things a bit more, I have changed my mind. I now agree with Osherove that we can enhance readability and maintainability by switching from Setup methods to factory methods that are called directly in the tests.

To make things more interesting, I had a recent conversation with Barry Stahl (my buddy that makes me think), and he described a technique that takes the concept of the factory method one step further. I'll definitely be exploring this a bit more.

Any book that encourages me to rethink the way that I've been doing things is a good book. We should be constantly re-evaluating our processes to make sure that we don't stagnate and are always headed in a productive direction.

Happy Coding!


  1. Does he give any tips for unit testing multithreaded code?

    1. Unfortunately not. Techniques vary depending on whether you're testing parallel processing or asynchronous methods. There are some good articles in MSDN Magazine about async testing from Stephen Cleary (Async Programming : Unit Testing Asynchronous Code) and Sven Grand (Async Programming : Unit Testing Asynchronous Code: Three Solutions for Better Tests).

  2. Very good article. I also read both edition and I have to say that Roy know a lot of practical things about unit testing. We also really to indicate that this is not a book only about unit testing but integration testing. I'm really picky with terms and there is a big difference in both of them and each one add values. I like to talk about Automated tests while referring to them. And I don't talk about test that use selenium or other things like which is in my view the role of the QA. I'm in a small business and I often have to do the QA role but it's totally not at the same time than when I develop the features.

    If any ways, great article and I love your last quote... Any book that encourages me to rethink the way that I've been doing things is a good book.

    If a book help me to know one new thing, this was not a lost of money and time.

  3. I like your post there is a lot of information about software testing, which i would like to learn, thank you for the great guide. Very useful post and I think it is rather easy to see from the other comments as well that this post is well written and useful. I bookmarked this blog a while ago because of the useful content and I am never being disappointed. Keep up the good work..

    QA Services

    Test automation services

    Compatibility testing services