当字符串是另一个字符串的选定有序子集时,单元测试应该失败

本文关键字:字符串 单元测试 失败 子集 另一个 | 更新日期: 2023-09-27 18:29:39

我第一次在visualstudio2013中编写单元测试。

我正在尝试编写一个测试用例来确保:新密码不应包含用户全名的任何4个连续字符。

假设用户的全名是:"John Yan",那么如果用户输入密码"HnYa@123",它应该会失败。

这是我的代码

[TestMethod]
public void Password_Contain_4_Successive_Characters_Of_User_FullName()
{
    UserInformation u = new UserInformation();
    string newPassword = "Mave@123";
    string username = "mary@mywebsite.com";
    var browser = BrowserWindow.Launch(browserURL);
    ClickLink(browser, "Patient");
    ClickLink(browser, "here");
    EnterText(browser, "username", username);
    ClickButtion(browser, "Reset");
    browser.Close();
    var changePasswordBrowser = BrowserWindow.Launch(browserChangePasswordURL);
    EnterText(changePasswordBrowser, "UserLogin", username);
    EnterText(changePasswordBrowser, "TemporaryPassword", u.GetTemporaryPassword(username));
    EnterText(changePasswordBrowser, "NewPassword", newPassword);
    EnterText(changePasswordBrowser, "ConfirmNewPassword", newPassword);
    ClickButtion(changePasswordBrowser, "Submit");
    Assert.AreEqual(newPassword, u.GetUserPassword(username));
}

如果新密码包含用户全名的4个连续字符,那么我应该使用哪个Assert.,这样单元测试就会失败?

当字符串是另一个字符串的选定有序子集时,单元测试应该失败

虽然目前接受的答案似乎解决了你的确切问题,但感觉你并不是在问正确的问题。单元测试的目的是确保您的生产逻辑完成您期望它做的事情,而不是实现您的业务逻辑。

看看你的问题,你的要求似乎是:

  • 当用户设置新密码时,请确保它不包含用户全名中的连续4个字符。(目前尚不清楚发生这种情况时应该发生什么,但我假设会对用户/故障响应进行某种反馈)

这是一个需要在生产代码中实现的业务规则。所以,在伪代码中,你会有:

if(StringContainsSuccessiveCharacters(newPassword, u.GetFullName(), 4)) {
    // Handle Error Situation
}
else {
    // Password is fine, proceed (save to db, do other checks etc)
}

在测试中,您将提供不同的全名和密码(例如在@Ruskin的测试案例中),以练习您的代码,并确保当新密码确实包含4个连续字符时,会出现可观察到的错误场景,而当没有时,会发生成功场景。所以,你可能会得到这样的测试:

WhenPasswordContains4SuccessiveCharactersFromNameErrorShouldBeDisplayed() {
    string fullName = "John Yan";
    string newPassword = "HnYa@123";
    // Do setup stuff (mocks/browser etc)
    // Try and set password to newPassword
    // Validate that validation error was triggered
    // Which could be as simple as checking that the password isn't changed
}
PasswordCanBeChangedWhenAllValidationRulesPass() {
    string fullName = "John Yan";
    string newPassword = "ZYXW@123";
    // Do setup stuff (mocks/browser etc)
    // Try and set password to newPassword
    // Validate that success condition, such as navigating to new page
    // or that the password is actually updated.
}

关键是,你的测试是为了确保你的生产代码达到你想要的效果。如果你看看问题中的示例测试,你可以看到你提供了newPassword的值。在编写测试时,您就知道newPassword是否包含FullName中的相关字符。为它添加断言并不能测试您的生产代码,它所做的只是测试您是否正确连接了测试。

没有一个assert方法,因此如果一个字符串包含另一个字符串的任何结果子字符串,它就会失败。但是您可以使用以下代码实现此功能

  var userName = u.GetUserPassword(username));
  for (int i = 0; i < userName.Length; ++i)
    for (int j = i + 1; j < userName.Length; ++j)
      if (newPassword.Contains(userName.Substring(i, j - i)))
        Assert.Fail();

上面标记的答案不适用于下面的所有测试用例,请尝试以下操作:

[TestCase("Ruskin", "rusk")] // will fail test
[TestCase("Ruskin", "skin")] // will fail test
[TestCase("Ruskin", "Ruski")] // will fail test
[TestCase("Ruskin", "Ruskin")] // will fail test
[TestCase("John Yan", "HnYa@123")] // will fail test
[TestCase("Ruskin", "bob")] // will pass test
[TestCase("Ruskin", "ru5k")] // will pass test
[TestCase("Ruskin", "niks")] // will pass test
public void Password_Contain_4_Successive_Characters_Of_User_FullName(string userName, string password)
{
    var groupsOfFour = new List<string>();
    // do checks to make sure password/username are at least 4 characters etc
    string userNameWithoutSpaces = userName.Replace(" ", "");
    for (int i = 0; i < userNameWithoutSpaces.Length; i++)
    {
        groupsOfFour.Add(userNameWithoutSpaces.Substring(i, 4));
        if (i + 4 >= userNameWithoutSpaces.Length)
            break;
    }
    Assert.IsEmpty(groupsOfFour.Where(s => password.IndexOf(s, StringComparison.InvariantCultureIgnoreCase) > -1));
}