ASP.NET MVC, BDD, Specflow and WatiN: putting the application in a specific state

asp.net-mvc, bdd, specflow, watin

Solution

For this, we have a specific Given step, that looks something like this in Gherkin:

Given I am signed in as user@domain.tld

Like you mentioned, this step basically reuses other steps to sign in the user. We also have an "overload" that takes a password, in case the test user has a non-default test password:

Given I am signed in as user@domain.tld using password "<Password>"

[Binding]
public class SignInSteps
{
    [Given(@"I am signed in as (.*)")]
    public void SignIn(string email)
    {
        SignInWithSpecialPassword(email, "asdfasdf");
    }

    [Given(@"I am signed in as (.*) using password ""(.*)""")]
    public void SignInWithSpecialPassword(string email, string password)
    {
        var nav = new NavigationSteps();
        var button = new ButtonSteps();
        var text = new TextFieldSteps();
        var link = new LinkSteps();

        nav.GoToPage(SignOutPage.TitleText);
        nav.GoToPage(SignInPage.TitleText);
        nav.SeePage(SignInPage.TitleText);
        text.TypeIntoTextField(email, SignInPage.EmailAddressLabel);
        text.TypeIntoTextField(password, SignInPage.PasswordLabel);
        button.ClickLabeledSubmitButton(SignInPage.SubmitButtonLabel);
        nav.SeePage(MyHomePage.TitleText);
        link.SeeLinkWithText("Sign Out");
    }
}

I think this is the best approach, since you should not be able to guarantee that all of the tests run in a specific order.

You may also be able to do this with a SpecFlow tag though, and have that tag execute BeforeScenario. That might look something like this:

Feature: List the products 
    As an authenticated user
    I want to list all the products

@GivenIAmAuthenticated
Scenario: Get Products
    Given I am on the products page
    When I click the GetProducts button
    Then I should get a list of products

[BeforeScenario("GivenIAmAuthenticated")]
public void AuthenticateUser()
{
    // code to sign on the user using Watin, or by reusing step methods
}

...should I put the MVC application in a specific state?

When signing in users, it's not the MVC application that needs to be put into a specific state, but rather the browser that needs to be put into a specific state -- namely, writing the authentication cookie. I'm not sure if you can do this or not, given that the auth cookie is encrypted. I always found it easier to just let SF walk though the authentication steps at the beginning of each scenario.

Problem

I'm new to BDD, Specflow and WatiN. I would like to use these tools to automate acceptance tests for my ASP.NET MVC application. I've already figured out how to basically use these tools, and I successfully built my first acceptance test: Log on to the website. Here is the Gherkin for this test: ``` Feature: Log on to the web As a normal user I want to log on to the web site Scenario: Log on Given I am not logged in And I have entered my name in the username textbox And I have entered my password in the password textbox When I click on the login button Then I should be logged and redirected to home ``` Now, I would like to write a bunch of other tests, and they all require the user to be authenticated. For example: ``` Feature: List the products As an authenticated user I want to list all the products Scenario: Get Products Given I am authenticated And I am on the products page When I click the GetProducts button Then I should get a list of products ``` What bugs me is that to make this test independent of the others, I'd have to write code to log on the website again. Is this the way to go? I doubt. I'm wondering if there are best practices to follow for testing scenarios like that. Should I keep the browser open and have the tests run in a specific order, on the same browser? Or should I put the MVC application in a specific state?

Original source