Jun 30

We have a steadily growing collection of small extension methods (including the usual .IsNullOrEmpty(), .To<T>(), etc.), along with corresponding unit tests, setup at my work. I spent some time a few weeks ago increasing the test coverage from around 70% to 100%, along with making the unit tests a bit more robust.

After setting up a build script for the project and adding it to our continuous integration server (which I’ll blog about shortly), I found a few check-ins that were breaking old unit tests. Emails were automatically sent out, by the CI server, about the failed tests and broken builds, but it turns out too many of us were forgetting to run the unit tests before doing our check-in (obviously). We don’t have TestDriven.Net or Resharper – though we’ll likely be ordering copies of the later any day now – so we have no easy way of running the tests besides the standard MbUnit GUI. Yuck.

A few days later I ran into this helpful piece of information, I think perhaps from JP Boodhoo, though I’m not positive. Anyway, if you have a separate assembly for your unit tests, simply go to the property page of that project, click the “Build Events” tab along the left, and enter this in for the post-build event:

"$(ProjectDir)..\UtilityLibrary.Core\Internal\Tools\MbUnit\MbUnit.Cons.exe" "$(TargetPath)"

This statement assumes you have your project checked out to something like C:\MyProjects\UtilityLibrary, and under there you have UtilityLibrary.Core for your actual code, and UtilityLibrary.UnitTests for, well, your unit tests. This command starts in the UnitTests forlder, goes up a directory (into C:\MyProjects\UtilityLibrary) and right back into the Core folder, which has the MbUnit library/program in it. If your situation is at all different, you’ll have to adjust this command accordingly, but it’s a good start.

Now your unit tests will be ran as a step in compiling your solution, and the compilation will fail if any of the unit tests fail:

Useful for smaller utility projects like this, but I imagine it’d become a pain in the ass for larger projects that take a bit of time to compile on there own, never mind having to run the unit tests on top of that every time. Sometimes you just want to see if the code compiles, not necessarily run all the tests too.

Jun 18
KISS Is Hard
icon1 Darrell Mozingo | icon2 Testing | icon4 June 18th, 2008| icon3No Comments »

KISS LogoNo, I’m not referring to the band, but the KISS principle (Keep It Simple, Stupid), and its close cousin, the idea of YAGNI (You Ain’t Gonna Need It).

They’re hard. Sure, they might seem easy at first glance, but they are both deceptively hard. This is especially true if you have any sort of background in your problem domain, and let’s face it, most of us do if we’re writing the usual problem tracking or invoice tracking applications. You know what I’m talking about: you start with an empty solution in front of you, tasked with creating your companies next, say, customer management system, and you start walking through the new application in your mind.

“Well,” you say to yourself, “I’m going to need a Customer object, a customer repository to store the object, a Job object, maybe an invoice object, tables and repositories for each of those, and I’m sure they’re going to ask for filtering next, so I might as well save myself the time and throw in a few specification and filtering classes.” This process goes on for a while and before you know if you’ve pumped out a few dozen classes and added all sorts of neat functionality.

Odds are, though, some, if not most, of those classes will end up either going unused or be heavily modified before the features are finished. Hence the above two principles (or ideas or whatever you want to call them). Wait until the last reasonable moment to add additional complexity to your application, but do so with a bit of judgment. Sometimes you simply know you’re going to need something, like a database back-end, so don’t start with text files just for the sake of keeping it simple. For the vast majority of decisions, though, you should use the simplest implementation until you find justifiable evidence that proves you need something more complex.

KISS and YAGNI go hand-in-hand with test driven development. Write your test, then write the simplest code you can to make the test pass. The code can always be refactored later to extract classes, interfaces, patterns, et cetera. I understand that your training as a developer is hard to resist – that urge to create things you’re pretty sure you’ll need while you’re working in a particular area. Resist it.

I’m starting on a new project at work, and it’s a particularly large project at that. It lends itself incredibly well to TDD, and so far the YAGNI ideal and TDD practice has proven themselves very versatile and helpful. As we’re unsure on how to split up the work load this early in the project, we’re working together (3 developers) on a machine with a projector. We’re constantly reminding each other not to over complicate things and toss in hooks and features we might someday need. Trust me, I literally mean almost every feature we add we’re reminding each other to go with the simpler implementation, because it really is that hard to overcome. We’re trying to stick to today, not tomorrow, by making it simple, making it fast, and making it easy to understand. I think we’re doing a great job of it so far.

We’re also well assured that the dozens and dozens of unit tests we have, along with the multitude of user generated acceptance/integration tests, will give us the safety net we need to refactor and introduce new features as we move forward. I, for one, am quite looking forward to what comes next.