Правильный способ реализации фоновых шагов в SpecFlow
В настоящее время я учусь использовать SpecFlow и хочу написать функцию, которая будет включать в себя тесты для регистрации пользователя.
У меня есть первый тестовый пример, Зарегистрируйте действительного пользователя. Это будет включать в себя ввод имени пользователя, электронной почты, пароля и пароля для подтверждения. Нажмите "Отправить", и пользователь должен быть зарегистрирован и добавлен в БД.
Мой следующий тестовый случай был бы недопустимым, когда я выполнял описанные выше шаги, а затем пытался зарегистрировать пользователя с тем же именем пользователя, что должно вернуть ошибку. Из того, что я могу понять из примеров, которые я нашел, я могу использовать "Фон" в своем файле.feature, чтобы указать шаги, которые я хочу выполнить перед каждым сценарием в файле.feature . Это может включать создание шага в разделе "Фон" для регистрации пользователя и вызов методов, которые были созданы в случае "Действительный пользователь регистра". Этот вопрос помог мне немного, но также поднял больше вопросов для меня, поскольку я не могу понять правильное использование доступных тегов и хуков.
Мои вопросы:
- Должен ли действительный контрольный пример находиться в том же файле, что и остальные сценарии? Если раздел "Фон" вызывается для каждого сценария в этом файле объектов, это приведет к сбою действительного теста (так как это, по сути, допустимый тестовый случай)
- Это правильный способ структурировать мои тесты? Я читал о хуках SpecFlow, которые можно использовать [BeforeScenario]/[AfterScenario] и т. Д., Но я не уверен, когда их следует рассматривать поверх тега Background.
- Я чувствую, что существует много дублирования, которого можно избежать, например, просто ссылаться на действительный тестовый пример как шаг в другом тесте, а не создавать шаг для него, а также тестовый пример, но, возможно, именно так SpecFlow является должен работать, не так ли?
Пока что для этого теста у меня есть следующее в моем файле.feature .
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
И мой файл шагов выглядит примерно так:
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);
}
1 ответ
Я думаю, что вы пытаетесь перейти к использованию фона, на самом деле не имея ничего общего с вашими сценариями.
SpecFlow довольно надежен в том, что вы можете использовать много шагов, если вы просто создадите согласованную структуру для ваших шагов.
Давайте начнем с вашей функции. Эта функция читается как скрипт разработчика. Функции должны представлять какую-то бизнес-цель. Терпите мое, потому что я не знаю, каковы ваши цели бизнеса
Feature: Register New Users
In order to perform task that only registered users can do
As a web site user
I want to register for the site
Теперь, когда мы знаем, почему мы пишем код, мы можем приступить к разработке сценариев для достижения этой цели.
Given I am not registered for the site
And I have filled out the registration form as follows
| Field | Value |
| username | testing |
| email | testing@gmail.com |
| password | 123456 |
| password confirmation | 123456 |
When I submit the registration
Then the response code should be '200'
And the database should have an unverified user
Это создает ряд sstepscenarios, но вы получите немедленное повторное использование, потому что теперь вы передаете свои переменные для заполнения регистрационной формы и проверки кода ответа.
Так что теперь ваш логин уже принятый сценарий может измениться на
Scenario: Username taken
Given a user has registered with the following information
| Field | Value |
| username | testing |
| email | testing@gmail.com |
| password | 123456 |
| password confirmation | 123456 |
And I have filled out the registration form as follows
| Field | Value |
| username | testing |
| email | testing@gmail.com |
| password | 123456 |
| password confirmation | 123456 |
When I submit the registration
Then the response code should be '400'
Так что теперь единственный шаг, который вам нужно реализовать, это первый шаг
Данный пользователь зарегистрировался со следующей информацией
и так как шаги - это просто код, вы можете называть уже определенные шаги из вашего первого сценария следующим образом
[Given(@"a user has registered with the following information")]
public void GivenAUserHasRegisteredWithTheFollowingInformation(Table table)
{
GivenIHaveFilledOutTheRegistrationFormAsFollows(table);
WhenISubmitTheRegistration();
ThenTheResponseCodeShouldBe(200)
}
Что касается Крюков, я использую их для более технических вещей. Я много занимаюсь тестированием, которое использует Selenium. Я создаю ловушку @web, которая запускается перед сценарием, чтобы раскрутить Selenium и разорвать его после завершения сценария. Я проделал то же самое с тестированием API в том смысле, что, возможно, вы захотите раскрутить HttpClient до того, как сценарий разорвется, а потом - вниз. Вы также можете сделать такие вещи, как очистка базы данных или очистка и заполнение до известного состояния, прежде чем вы действительно начнете тестирование.
Я надеюсь, что это отвечает на все ваши вопросы.