Continuing our recent BDD theme I thought that it would be useful to show an example of combining SpecFlow and coded UI tests for automated acceptance testing using the UI. SpecFlow is a popular open source Acceptance Test Driven Development and Behaviour Driven Development framework for .NET.
There are some posts out there about how to do this, but no step by step examples. I thought that I would fill in the gaps and also submit the code to the SpecFl0w guys.
An example of a SpecFlow scenario is
As you can see it is plain text with no testing framework ‘noise’ getting in the way.
With SpecFlow you can generate .feature files that can be executed by a variety of test runners. Features contain multiple scenarios which get turned into unit tests. Out of the box SpecFlow supports NUnit, MSTest and xUnit. We are going to add support for CodedUI.
I have downloaded the SpecFlow examples and we will be working with the BookStore sample.
I have created a new Visual Studio 2010 Test Project called BookShop.AcceptanceTests.CodedUI. I have copied the structure of the other samples and re-created the same folders.
Copy in the ReferenceBookList class and BookSteps class. These should work as is.
There is a great post here which gets us started. Follow these instructions to build a new generator that will decorate the tests for Coded UI. I have included this with the attached code. You will need to copy this dll (SpecFlow.CodedUI.Generator.dll) into your SpecFlow bin folder.
Looking at the Selenium sample we can see what sort of coded UI tests we need to create.
Firstly we need a test to perform the simple search. I launch a new coded UI and click into the search field, enter a title and then hit search. At this point generate the code. It is a good idea with coded UI to keep the methods really small. That way you can compose them in different ways.
I have called this method PerformSimpleSearch. We also need a way to validate that the list should exactly contain a certain book. Start the coded UI editor again and create as assertion on the html cell with the name of the book. I have called this TitleMatches. I also created an assertion on the rows property of the table. We can use this to make sure that there are no extra books in the list.
I created one more method in my coded UI test and that was to close the browser. Called CloseBrowser (funnily enough)
Right thats all the coded UI tests we need. Now we can wire these up to our SpecFlow project. If we copy the outline of the SearchSteps class from the selenium project we see:-
[When(@"I perform a simple search on '(.*)'")]
public void PerformSimpleSearch(string title)
From here we can insert the calls to the Coded UI functions to validate behavior. So inside this method we can add
codedUI.PerformSimpleSearchParams.UISearchTermEditText = title;
This uses the feature of coded UI that enables us to specify parameters to methods using the Params properties. So we can leverage both the power of coded UI and SpecFlow together. The next method looks like this:-
[Then(@"the book list should exactly contain book '(.*)'")]
public void ThenTheBookListShouldExactlyContainBook(string title)
again we can fill this in with
codedUI.HasExactBookCountExpectedValues.UIItemTableRowCount = 2; //one for header row
codedUI.TitleMatchesExpectedValues.UIDomainDrivenDesignCellInnerText = title;
Great, so now we can run our first SpecFlow test. Navigating to the TestView window we can see
And running it shows us SpecFlows great readable output.
I have also updated the code to make the second test work. See the attached sample.
Code is here.