After my latest post-of-admitting-failures I got some really nice feedback from a lot of people. Apparently there are others out there who think that a failure is great learning opportunity. OK – I will most certainly continue down that path.
I actually write these post as I code along. It’s forward only mode in other words… Almost.
One of the nicest things that happened as a result from the last post was that Darren Cauthon gave me some insightful comments and patches to go with them. This “social coding” that is going on, on www.github.com (a.k.a. programmers Facebook) is really, really cool.
Darren has done a lot of stuff in and around the SpecFlow project, for example the SpecFlow Assist (table helpers) that is really great. So I value his opinions a lot. He gave me 4 points to think about and I thought I comment them here as I learned a lot from them and think maybe you will to:
- Line up your SpecFlow tables correctly. This is a great point that will make the feature-files be readable outside Visual Studio. I think that the readability is a key feature of BDD so totally agree there. Committed!
- Don’t use asserts in the When-step. Totally agree on this! The Given/When/Then mantra is from the outset a development of the Arrange/Act/Assert. Don’t assert in the act step seems reasonable and give you a better separation of concerns in your step definitions. Committed!
- Split you step definition files into files per thing or concept. Great tip! Didn’t think at all of that – but it makes a lot of sense and also pushes me to think about keep the steps clean from state and other smells, so they easily can be stitched together in other scenarios. Committed!
- Use SpecFlow 1.5. I actually thought of this the moment I realized that NuGet didn’t give me the latest version of SpecFlow. There are some great additions to SpecFlow especially the one Darren mentions. So I guess I go manual and include the SpecFlow 1.5 myself. Or maybe I can upgrade the NuGet-version of SpecFlow? Committed!
OK – with the aid of GitHub and not to mention Darren the project is now in great shape.
But really - it’s just to hard to grasp git sometimes. I finally applied Darrens changes as a patch. I am a damaged Microsoft developer who haven’t adjusted to the bash/dos command only world of git.
On with tasks at hand.
Updating the specs for the Homepage
The current scenario lacks a little bit of information. When you navigate to the homepage of the application you should not only see the top three favorited Kanban boards, there should also be a list of the newest additions. The simplest way to do that is simply to augment the current scenario with a new Then-statement. Like this:
The observant reader sees that I done a few minor tweaks to the scenario title and the When-step as well since it didn’t fit or read very well.
Ok – this of course fails since I haven’t implemented the step yet. Yada, yada, yada – it’s all been explained before. Finally, led and driven by my scenario, I ended up with this new When step definition:
And this, rather ugly, action method for the Index action of the KanbanBoard Controller:
Let me be the first to the possibilities for improvement here. I was thinking of using CQRS as my architecture for this application, but didn’t because that would be to many things at once. I might go back and redo the application CQRS style as an exercise to learn it later.
Right now I’m satisfied with this. It keeps my focus on the stuff I wanted to learn and the scenarios will be a great guide when I redo the architecture later. Wow – I’m looking forward to it already.
Let me also here declare my standpoint on TDD and Scaffolding (see this). Ok – I going to treat the generated repository code as not mine. I actually added the DebuggerNonUserCode attribute to the repository, until I need to change it. The rest of the code will be touched on and hence tested, even though I sense that it will be much more BDD than TDD.
Writing an end to end acceptance test
Right now the application doesn’t work if you actually run it. That’s one of the drawbacks of writing your step definitions against the controller level of the application. The gain is that you get faster test execution (NOT to be underestimated) and also a much faster writing experience.
But I sure want the application to work. . So I will have a few integration tests that will run end to end – from the HTML down to the metal in the SQL database.
Since I haven’t yet this process will force me to install an IoC Container (Ninject baby) and to setup and configure the database (SQL CE which looks nice… and is free). NuGet will do the heavy (?) lifting for me. And my scenarios will guide me.
Writing the scenario
I created a new project for the acceptance tests (called… drum-roll; AcceptanceTests). These are tests and that is something different than the specifications in the Specs-project. They will run different, be written different and do different stuff – I don’t want any strange connections between the two. At least not now. I intend use tags to separate out the slow end-to-end test from the fast specifications.
Another thing to think about is that we’re now running against another application an hence another application domain. For these scenario the internals of the System Under Test (SUT) is truly a black box. That is important to think about for test data for example. How can I load the database with known test data? Or can I write my scenario in a way that the test data is irrelevant or not as important?
Remembering that this is tests and not specifications I settled for the last option and wrote the following feature file:
And now I started to implement the steps since they all fail with the inconclusive status, to start with. This time I created a step definitions class for the home page, I think that further down the road the need for different pages will become evident.
Also, before long I needed WatIn to easy write automations for the browser. Not found on NuGet, sadly. I had to download and add manually. Feels old school already. I also ripped this wrapper for the browser from Steven Sandersson.
Finally here is the step definitions with the first step implemented, so that I need to write production code:
When I run this I get the following error; know as the yellow screen of no Dependency Injection controller set:
One gotcha that I ran into with WatIn on the way was that I needed to set the “Embed Interop types” property of the reference to Interop.SHDocVw.dll to false:
But then this first step ran and showed me the error above.
Inject some Ninject please
OK – to solve this I need a dependency injection framework. Ninject has MVC 3 version so I’ll go with that. One NuGet command later… I have one class and method to add the following one line to register my KanbanRepository:
Boom – Ninject installed! Man – I LOVE NuGet. It’s super-slick to work with.
More errors – become database
The “sad” part is that only got me to my next error. The model returned is empty which has to do with the database not being present and hooked up. From this blog post I can see that I’m just a simple NuGet addition away from solving that.
He he… no, actually the MvcScaffolding install from NuGet did that for me… I just found out.
But I was wrong – you actually need some configuration in order to get a bit further. The connection string is missing. To add that you need to know about some conventions.
The connection string should be named the same as your DbContext class which in my case gives me the following connection string:
Ok – and now, speaking of super-slick a new SQL CE database is now created in the App_Data folder. So I included it in my project and double click it. And here I was stopped in my tracks.
I haven’t read the Scott Gu post fully. It’s even called Visual Studio 2010 SP1, I felt stupid and started to install Visual Studio 2010 SP1. Which took me the rest of the night – it actually took 2 hours to run. Can’t remember an installation that took so long. But hey – the it worked. And when that was done I could open the database and add some data.
Now I ran into a problem where “model don’t implement IEnumerable”. This has to do with that my ViewModel holds two collections for TopFavorited Kanban boards and Latest’s Additions. So I changed the loop from looping over the model to loop over the TopFavoritedKanbanBoards. And boom – data in my view. Ugly but there for the first time. It’s alive!
I couldn’t live with that layout so I did a very simple update of the view to this:
And that looks like this:
That is not pretty I know. But that is a start and I can complete my acceptance test with that layout.
Completing Acceptance tests
With all these changes it’s been a while but, where I left of the When-step (“I navigate to to the homepage”) passed, and the Then-steps was failing. Here is the complete acceptance scenario again:
The Then-steps are easily implemented using WatIn and the infrastructure in place:
This session (although it stretched several days) felt so much better. I’m now hooked into a database and have seen the first signs of the site working.
I am already longing to continue.