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?