Adventures in BDD for an ASP.NET MVC 2 and jQuery Project

I’ve played with Cucumber testing for a Ruby on Rails project, and I wanted to be able to a) automate and b) document some complex scenario testing for one of my ASP.NET MVC apps.

I downloaded SpecFlow 1.5 and NUnit 2.5.9. Because I am testing a web application, I also needed a browser automation library. I already use Selenium for recorded tests in FireFox, but decided to try WatiN 2.0.

When testing with a Cucumber-style setup, there are three parts:

  1. The feature specification, written in Gherkin

    Feature: Searching
       In order to view documents
       As a user
       I want to be able to search for a particular document
    
    Scenario: Search by Document Title
       Given I am on the search page
       And I am logged in
       Then I should see a textbox labelled "Title"
       When I click the button labelled "Search"
       Then I am on the document page
    

  2. The step definitions, using the library that will drive your application (your model for a console app, or your browser automation library for a web app – this example uses WatiN)

           [Given(@"I am on the (.*) page")]
            public void GivenIAmOnThePage(string pageName)
            {
                var browser = new IE();
                browser.GoTo("http://localhost:xxxx/Home/" + pageName);
                Assert.That(browser.Title, Is.EqualTo(pageName));
            }
    


    (notice that you can use regular expressions and capturing groups to pass parameters into your method)

  3. The actual code that provides the functionality being tested

I started out by following the SpecFlow screencast. The basic steps in VS 2008, using Red-Green-Refactor, are as follows:

  1. Add a new project to your solution (use a Class Library) called [ProjectName]Specs.
  2. Add references to the nunit.framework.dll and techtalk.SpecFlow.dll (I had to add a reference to WatiN.Core.dll as well)
  3. Add > New Item… > SpecFlow Feature File
  4. Run the tests in NUnit. They will show green but with 1 inconclusive test
  5. Add > New Item… > SpecFlow Step Definition. Call it StepDefinitions
  6. Go to the text output tab in NUnit and copy the provided step definition stubs into your Step Definition file
  7. Implement the steps
  8. Run your tests again and check that they pass

The demonstrator appears to have TestDriven.net installed, but you can run the tests by opening the NUnit GUI from your Start menu and opening your spec project’s dll. Then, next time you build the project in VS the tests will automatically run in NUnit. (Remember to check all 3 boxes under Tools > Settings > Test Loader > Assembly Reload in NUnit.)

For examples of implementing the steps with WatiN, I looked at Steve Sanderson’s article on using SpecFlow with ASP.NET MVC, and Deran Schilling’s articles part 1 and part 2 are useful too, particularly the solution for the
System.Threading.ThreadStateException: The CurrentThread needs to have it's ApartmentState set to ApartmentState.STA to be able to automate Internet Explorer. at WatiN.Core.IE.CheckThreadApartmentStateIsSTA()
error which IE threw.

To debug the step definitions, when you have NUnit running select Debug > Attach to Process… in VS and choose nunit.exe from the processes list.

But my experiment ground to a halt when I needed to wait for an AJAX response from my jQuery validation. I tried to use Omar Al Zabir’s WatinN to Automate Browser and Test Sophisticated ASP.NET AJAX Sites (see also Robert Koritnik’s response to How to wait for jQuery Ajax requests to complete from WatiN? on StackOverflow), which involves injecting JavaScript to keep track of the AJAX requests in progress, but it kept failing with a JavaScript TypeError saying that the variable was undefined. My applications make extensive use of AJAX, so this was a show stopper.

The solution was inspired by Dima Kovalenko’s article Selenium wait for AJAX (the right way!!!). Because my project uses jQuery I didn’t need to inject JavaScript to count AJAX calls – I could use WatiN’s Eval method to test for $.active == 0 instead.

Advertisements

About Jennifer Phillips Campbell

Software Developer and Medieval Historian
This entry was posted in Testing. Bookmark the permalink.