我目前正在学习使用 SpecFlow,并想编写一个功能,其中包括注册用户的测试。
我有第一个测试用例,注册一个有效用户。这将涉及输入用户名、电子邮件、密码和确认密码。单击提交,用户应注册并添加到数据库。
我的下一个测试案例将是一个无效案例,我将执行上述步骤,然后尝试使用相同的用户名注册用户,这应该会返回错误。从我找到的示例中可以理解,我可以在 .feature 文件中使用“背景”来指定要在 .feature 文件中的每个场景之前执行的步骤。这将涉及在后台部分创建一个步骤来注册用户并调用在有效注册用户案例中创建的方法。这个问题对我有所帮助,但也为我提出了更多问题,因为我无法理解可用标签和挂钩的正确用法。
我的问题是:
- 有效的测试用例是否应该与其他场景在同一个文件中?如果该功能文件中的每个场景都调用了背景部分,那么它将导致有效测试失败(因为它本质上是有效的测试用例)
- 这是构建我的测试的正确方法吗?我已经阅读了可以使用 [BeforeScenario]/[AfterScenario] 等的 SpecFlow 挂钩,但我不确定何时应该在背景标签上考虑这些挂钩。
- 我觉得可以避免很多重复,例如仅将有效的测试用例引用为另一个测试中的一个步骤,而不是为它创建一个步骤以及一个测试用例,但也许这就是 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);
}