I am learning to use SpecFlow at the moment, and want to write a Feature which will include the tests to register a user.
I have the first test case, Register a Valid User. This will involve entering the username, and email, a password and a confirmation password. Click submit and the user should be registered and added to a DB.
My next test case would be an invalid case where I would do the above steps and then try to register a user with the same username, which should return an error. From what I can understand from examples I have found, I can use "Background" in my .feature file to specify steps that I want to execute before each scenario in the .feature file. This would involve creating a step in the Background section to register the user and calling the methods that were created in the Valid Register User case. This question has helped me a bit but also raised more questions for me as I cannot understand the proper usage of the tags and hooks available.
My questions are:
- Should the valid test case be in the same file as the rest of the scenarios? If the Background section is called for every scenario in that feature file then it would cause the valid test to fail (as it is essentially the valid test case)
- Is this the right way to go about structuring my tests? I have read about the SpecFlow hooks that can be used [BeforeScenario]/[AfterScenario] etc. but I'm not sure when these should be considered over the Background tag.
- I feel like there is a lot of duplication that could be avoided, for example just referencing the valid test case as a step in another test, rather than creating a step for it as well as a test case, but maybe this is how SpecFlow is supposed to work, is it?
So far for this test case I have the following in my .feature file.
Feature: RegisterUser
In order to register a user successfully
A valid username, email, password (and confirmation password) must be entered
@register
Scenario: Valid Register User
Given I have entered a username "testing", an email "testing@gmail.com", a password "123456" and a confirmation password "123456"
When I press submit
Then the response code should be 200
And the user should be added to the database with verfied set to False
Background:
Given I have registered a user "testing", "testing@gmail.com", "123456" and "123456"
@register
Scenario: Username Already Taken
Given I have entered a username "testing", an email "testing1@gmail.com", a password "123456" and a confirmation password "123456"
When I press submit
Then the response code should be 400
And my steps file is something like this:
using NUnit.Framework;
using System;
using System.Net.Http;
using TechTalk.SpecFlow;
namespace Tests.Specs
{
[Binding]
public class RegisterUserSteps
{
private RegisterUserModel userInfo = new RegisterUserModel();
private RegisterUserController user = new RegisterUserController()
{
Request = new HttpRequestMessage(),
Configuration = new System.Web.Http.HttpConfiguration()
};
private ApiResponse response = new ApiResponse();
private static string userTableName = "usersTable";
private static string userTablePartitionKey = "USER_INFO";
private static string userTableRowKey = "testing@gmail.com";
[Given(@"I have entered a username ""(.*)"", an email ""(.*)"", a password ""(.*)"" and a confirmation password ""(.*)""")]
public void GivenIHaveEnteredAUsernameAnEmailAPasswordAndAConfirmationPassword(string p0, string p1, string p2, string p3)
{
userInfo.Username = p0;
userInfo.Email = p1;
userInfo.Password = p2;
userInfo.ConfirmPassword = p3;
}
[When(@"I press submit")]
public void WhenIPressSubmit()
{
response = user.Register(userInfo);
}
[Then(@"the response code should be (.*)")]
public void ThenTheResponseCodeShouldBe(int p0)
{
Assert.AreEqual(p0, response.Status);
}
[Then(@"the user should be added to the database with verfied set to False")]
public void ThenTheUserShouldBeAddedToTheDatabaseWithVerfiedSetToFalse()
{
UserEntity user = AzureUtilities.RetrieveEntity<UserEntity>(userTableName, userTablePartitionKey, userTableRowKey);
Assert.IsNotNull(user);
Assert.AreEqual(userInfo.Username, user.Username);
Assert.AreEqual(userInfo.Email, user.RowKey);
Assert.IsFalse(user.Verified);
}
[Given(@"I have registered a user ""(.*)"", ""(.*)"", ""(.*)"" and ""(.*)""")]
public void GivenIHaveRegisteredAUserAnd(string p0, string p1, string p2, string p3)
{
//Using methods here that have been defined in previous steps
GivenIHaveEnteredAUsernameAnEmailAPasswordAndAConfirmationPassword(p0, p1, p2, p3);
WhenIPressSubmit();
ThenTheResponseCodeShouldBe(200);
}