# Thursday, February 28, 2008

You call that Snow!

Next time anyone complains about weather in Calgary I gotta forward this picture of a snow pile outside a Canadian Tire in Quebec... it was probably 50 feet high...

#    Comments [0] |
# Tuesday, February 26, 2008

Unit Test / Data Generation

I’ll admit that I have a love/hate relationship with Unit Testing.  Unit Testing has absolutely saved my bacon a number of times where a seemingly inconsequential change would have crippled our software. The reality is that the only way you can verify that those tiny changes don’t wreck havoc is to script your testing for known results. By having your build process validate those results you add a very strong safety net to your development process.

But… in most software systems there’s this pesky layer that throws a real wrench into the entire thing – it’s called the database.

The problem is this… a Unit Test is meant to be autonomous. It should be free standing and require no external dependencies. In reality the code you’re executing typically interacts with an existing database and performs INSERTS/UPDATES/DELETES to verify that certain functions still work. What get’s awkward is that the “Unit Test” database is typically an external dependency for your Unit Tests – it just has to be there be in the correct state or the Unit Tests will crash hard. Things like database schema changes, new testing datasets, and changing database locations really screw the unit tests up.

I’m going to describe a solution to this problem that we’ve been using for the last couple weeks. It’s worked extremely well by streamlining issues we had with databast style unit tests and by increasing our code quality. Everything here is based on Visual Studio 2005, nUnit, and nAnt but it’s more the concept that’s interesting.

How It Works!

We started off by adding a special project as part of each module called the Schema. Basically this is a simple class library with a bunch of embedded SQL scripts. These SQL scripts are responsible for taking a database and putting it into a known state for the Unit Tests. Execution of these scripts is done by a class called the SchemaManager, it has three methods which will become obvious in a minute.

The Unit Tests now add a reference to the Schema project. As a nUnit Setup Method we'll call out to a special class called the TestConfiguration. This TestConfiguration will be responsible for triggering the SchemaManager. Here's what a typical Unit Test in our UnitTest project would look like.

The TestConfiguration is a little more interesting. It uses a singleton pattern to create a SchemaManager, tell it to Drop the current Schema, and then Create it fresh. This executes the Drop Table/Procedure commands to clear out our database, and then uses the Create Table commands to make a fresh database.

Perfect! Now the database schema is in a state that our Unit Tests can work with – table are there, stored procedures are there, life’s good.

Now we need to create some canned data before we start our tests. Things like maintenance objects, customer codes, etc. are all expected to be in the database before our Unit Tests run so we need to create scripts in our UnitTest database which setup this data. Something like this...

We’ll embed this scripts into the UnitTest project and then change our TestConfiguration so that it gets the SchemaManager to insert this data after calling CreateSchema. We'll simply use the ExecuteResourceSql call we defined above and call it from our TestConfiguration.

And that's pretty much it! I think the beauty of this SchemaManager is that is makes the database a source-controlled resource. Instead of having some unknown dependency that the unit tests must rely on, the unit tests actually create their environment using scripts generated by the developer. If the developer breaks the Schema or the Business Logic, the unit test will catch it right away and any failed unit tests are expected to be logic errors instead of logistical problems between the development and unit test environments.

If you have any comments or suggestions on this area please drop me a line - it's a very interesting (and often underused) development practice!

PS - The foundation for a lot of this stuff is from a 4guysfromrolla posting, check it out for more details...

http://aspnet.4guysfromrolla.com/articles/040605-1.2.aspx

#    Comments [0] |
# Saturday, February 09, 2008

The Danger of Little Issues...

I came across a great article a couple weeks back about the danger of little issues... the foundation of this article was that every day we get interupted in ways that force us to change what we're focused on, deal with an emergency, and then re-focus back on the task at hand.

This articule suggested that these "shifts" cause us to lose more time then if we could just merrily work through one project at a time... makes sense, huh?  

What's really interesting is that this article suggested that the LITTLE things actually cause you more long-term grief than the big things. The reasoning was that when you come across a big issue you learn in a big way... and subconsciously take action to resolve it in the future. The problem with little issues is that they only take 1/2 an hour to resolve... and you become complacent in resolving them... twice a week... for a year.

 

Why is this worth mentioning? Today while setting up for our NADA trade show (www.nada.org) I ended up spending an hour trouble-shooting some file location issues on our demo server. It's a stupid virtual-drive issue that only occurs in certain environments and generally takes me about an hour to figure out.

The trouble is that we've grown complacent in spending an hour on this issue... instead of focusing on why we need a virtual-drive in the first place. If we'd reworked our pathing a year ago, I wouldn't get bothered by this every few weeks.

 

Once you identify the "Little Issue" it's all about committing yourself to resolving it... we're in mad-panic trade show mode right now so let's see what we can do after we get back from San Francisco...

To be continued...

#    Comments [0] |