As I was pondering a new topic to blog, I stumbled into one this morning. I was running some ideas by a few Headspringers, and they provided several options. I decided to go with a hybrid of their suggestions. What I originally planned to blog was a way to test Enumeration subclasses of the Enumeration class from Tarantino. What I ended up with was an even better way to test them. This is not an unusual happenstance at Headspring. If you talk to other Headspringers, you’re going to learn something new. It never ceases to amaze me how often I’m learning something. I like to think I’m doing some teaching, too, but I’m confident that I’m currently learning more than teaching.
In case it isn’t clear by the title, part of becoming a Headspringer is to learn from the great people you get to work with every day. So, if you’d like the opportunity to work with talented, passionate people, we are hiring!
Now let’s get to the original idea of testing the Enumeration subclasses. I will walk through my original code, then what Mr. Brandon Barry showed me, and why it’s an improvement. Read the rest of this entry »
Change is inevitable. It is a simple fact of life which permeates into just about everything. Software development is no exception. Many software development life cycles have evolved and others have come into existence in an effort to help us deal with change. Programming languages, tools and techniques are also continuously evolving as well. Yet with all these improvements many project teams continue to struggle with change.
What can we do about change? The truth is change doesn’t have to be hard. There are many things we can do such as plan for change, design for change, and code for change. Read the rest of this entry »
TestCase is one way you can run parameterized tests with NUnit. An example of how this is useful is testing a whitelist or blacklist. You only need to write the test once, then pass in your items to test some sort of output. If the requirements change and words need to be added to or removed from your list, you simply add another entry without the need for writing another test or set of tests.
I’ve found myself using TestCase (formerly RowTest) more and more often. If you see lots of very similar tests that shared assertions, or test method names with numbers/values in them, these are signs that you might be wanting to use TestCase. Let’s take a look at the following examples. Read the rest of this entry »
Earlier this year, I bought a car—my first new car. Although it fills me with sanctimonious hybrid glee (it really does), it’s making me neurotic with instrument panel indicator lights. The low-tire-pressure indicator after the weather turned cold. The insistent exclamation point from the airbag computer in my seat. The glaring amber beacon from the Integrated Motor Assist battery. I’ve never had so many things go wrong with a car!
Or have I?
Incorporating automated tests into your Continuous Integration build process can feel similar. You’re suddenly presented with all these errors. Your product seems to be broken all the time. You liked it better when things were quiet and you didn’t know how bad it was. Read the rest of this entry »
In my first post in the Unit Testing Best Practices series, I introduced you to the basic lifecycle of an NUnit test fixture. This time, we’re going to see what happens when we give our tests a common test fixture base class.
Why a base class?
There are two cases where having a base test fixture can be useful in keeping your test code simpler:
- You have lots of the same kind of tests. Maybe you’re writing integration tests for your persistence layer. Your tests are going to all be performing some similar operations, like creating a database connection. Maybe they all need to reference an Inversion of Control container like StructureMap or Autofac in order to retrieve repository instances. You don’t want to write that boilerplate code for every fixture, do you?
- You have a hierarchy of classes that need testing. If you have a base class in your domain, you will probably want to set up a parallel type hierarchy of test fixtures. In this case, a base test fixture gives you one place to define tests that verify the base class invariants to which all your derived classes need to conform.
The Code
When I sit down to write a unit test, my first step is to describe for myself, in English instead of code, what I intend to test. The words I choose give clues as to the structure of the test and the style: interaction-based versus state-based. I’ll describe an example below.
RhinoMocks, and other mocking frameworks like Moq and TypeMock, are a support structure that let you write briefer, more expressive unit tests. RhinoMocks simplifies the quick creation of fake classes that your class under test relies on and interacts with. You can use those fakes for both styles of tests; RhinoMocks can make assertions about interactions in interaction-based tests, and it can provide non-exception-throwing behavior when you just need a stand-in for your state-based tests. I listen to the language of my description to know how I want to use that Rhino Mock.
For example, your application might have an EmailDispatcher that decides which emails to send, then calls an EmailService to send the emails. You’d like to unit test the logic in the EmailDispatcher without sending thousands of real emails. This is a perfect scenario for RhinoMocks. Read the rest of this entry »
Okay, I admit it. Sometimes I write unit tests second instead of first. I also bite my nails and rest my elbows on the dinner table. But when I’ve got a bug to fix, and I’ve already found the offending line, I can hardly resist the urge to just… just… change it. I’ll follow up with unit tests afterwards, promise.
I admit this to you because admitting my wrongs is a step towards rehabilitation. I admit this to save you pain. Learn from my example. Test-second is so much less efficient than test-first. Consider the following workflow:
- Reproduce, identify, debug the issue.
- Fix the code.
- Compile and try it out.
- Write a test that proves I fixed it.
- Compile and run the test.
- Change the code back to make sure my test really proves what it is trying to prove.
- Compile and see the test fail.
- Re-fix the code.
- Compile and see the test pass.
I humble myself before you. How much time am I wasting there? It’s embarrassing. Read the rest of this entry »