While catching up on some podcasts, I listened to Hanselminutes #169 with Roy Osherove.  Scott and Roy discuss the art of unit testing.  I’m a fan of unit testing, but specifically in writing high quality unit tests.  A few of the points Roy made were so good, I had to jot them down.  This post is my summary of the podcast.

What is a unit?

Understanding what a unit is helps cut down meta-test time.  Define a unit that makes sense to your particular framework.  Some people say to “Test only the smallest piece of code.”  Roy was a little more specific in providing the following list of criteria for unit testable candidates:

  • Must run only in memory
  • Must run fast
  • Does not touch any external state (database, file system, etc.)
  • Is Repeatable
  • May touch multiple classes/methods

The 3 Pillars of Unit Testing

Roy describes the 3 pillars of unit testing with the following questions:

Trustworthiness.  Are you able to run your test and trust the results?  Do you watch your test pass, and then debug it anyway?  If you don’t trust the test, it’s not saving you time.  Mixing integration tests with unit tests reduce trust.

Maintainability.  Maintenance is abandoned because maintaining costs are too high.  Tests that are not run or maintained are no longer useful, which leads to decreased trustworthiness over time.

Readability.  Do the unit tests conform to naming conventions?  Are they organized logically?  Readability is a factor that can deter maintenance and trustworthiness.  If the person working with the test cannot read it easily, they might not understand what the test is for or what the results are meant to signify.

“Remove one of these pillars, and the rest will fail.”

The Blurry Line:  Unit Testing Versus Integration Testing

In lieu of the integration test versus unit test dilemma, I defer to this StackOverflow question.  It really depends on the situation, and what kinds of boundaries are being crossed within the test in question.

Integration tests come in handy for things the require state.  Testing a Data Access Layer should be done with an integration test, as opposed to a unit test.  Use a real database in the tests, and let the DAL be the test for the database.  Integration tests can be used to test several aspects of state dependent functionality.  Given a logging scenario, the integration test would verify that logging occurred, and assert that the result was the expected outcome, and then cleanup.  Unit tests would test the interaction without the actual logging functionality.

Get the Terminology Right

So often in unit testing you need setup methods and tear down methods.  In order to reduce the scope of what the test is actually using, other incorporated functionality of the framework must be used artificially.

  • Fakes look like an object, but is fake for the test.
  • Mocks are fake objects that decide if the test passes.  Assert against mocks to pass or fail tests.
  • Stubs help your test run.  Don’t assert against them, they just mimic the system.

Assertions

One assert is plenty for any unit test.  However, you might have more than one assert for a unit test if an object result needs to have a specific combination of property values.  That still boils down to being one assertion because the combination of assertions dictate a single expected result.

Test Names

Name unit tests with the Name of the Method, Scenario, and Expected Behavior.   Including this kind of information helps reduce the amount of time a programmer would have to spend figuring out what the unit test is supposed to do, and furthermore encourages the test to stay on track; it keeps intentions clear.

Related Links:

The Art of Unit Testing: with Examples in .NET — http://www.amazon.com/Art-Unit-Testing-Examples-NET/dp/1933988274/ref=sr_1_1?ie=UTF8&qid=1249321351&sr=8-1

Monday, August 03, 2009 1:45:24 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
Hanselminutes | Integration Testing | Roy Oscherove | Scott Hanselman | Unit Testing

John Nelson

mugshot I am a passionate C# Developer working in ASP.NET on an e-commerce solution for ticketing software. I work across all of the application layers, including server side functionality, and client side programming with jQuery and MS Ajax. Although my full time job is in WebForms, I spend many of my off hours working with MVC. I am especially interested in productivity and good programming practices.

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
John Nelson
Statistics
Total Posts: 25
This Year: 3
This Month: 1
This Week: 0
Comments: 1