19 Jul 2011

Testing with Simple.Data and SpecFlow

One of the most important lessons you can learn about tools like Cucumber and SpecFlow is the need to get your entire application into the specs.  When you execute your specs, you’re supposed to be running your application, not a bunch of stubs and mocks that won’t be in your live application.  That’s what integration testing is about -- testing the integration of all of the pieces that you (should) be unit-testing.

From my personal experience, one of the biggest hurdles to proper integration testing with SpecFlow is handling the database.  Let’s be honest, getting data in-and-out of a database can be a huge pain, even with today’s most popular tools.  In fact, data access can be so difficult, I and many others have actually left that part out of our specs.  We swap out in-memory databases, our specs run, we go green... and then we run our application and get a big database error.  Tests that go green when the app is broken aren’t that helpful, right?

Well, earlier this year I listened to a Herding Code podcast about a tool called Simple.Data, and it’s changed everything for me.  Over the course of a few months, Simple.Data has turned the most painful part of building an application into the most fun.  Simple.Data has removed the barrier between my specs and the database.  

Here’s a basic scenario.  I want to test that when someone submits a form to create an account, the account record is created in the database.  



Let’s start with the two steps here that relate to the database, “Given the following accounts exist” and “Then the following accounts should exist.”  The first is responsible for loading the accounts into the database, and the latter is responsible for asserting that records in the database match what is in the table.

The standard methods for doing data access can be pretty expensive, at least in terms of code and abstractions.  Heavy tools (like Entity Framework and NHibernate) require a certain amount of setup and wiring-up to specific objects and assemblies, and lighter tools (like direct SQL calls) sometimes require extra work or the loss of helpful libraries.

Enter Simple.Data.  Simple.Data is a library that makes data access incredibly simple, but without giving up the core features we want out of an ORM.  I’ll just show you the step definitions below and let the code speak for itself.



This code is pretty simple.  Before each scenario, the account table is cleared so each test will have a clean database.  In the “Given the following accouns exist,” SpecFlow’s CreateSet<Account>() method is used to quickly create a set of accounts from the table.  And in the “Then the following accounts should exist,” we pull out all of the accounts from the database and use SpecFlow’s CompareToSet to make sure that the records match what is in the table.

And Database.Open()?  That’s a Simple.Data method that finds a default connection string in my test config, connects to the SQL database, and returns a dynamic object which can be used to access the database.  

Pretty simple, right?  You can check out the full solution on Github at http://bit.ly/nlg177.  You can also read the Simple.Data wiki at http://bit.ly/nV8dYl, or listen a recent Herding Code podcast on Simple.Data at http://herdingcode.com/?p=305.