【问题标题】:Unit testing multiple asserts单元测试多个断言
【发布时间】:2014-10-16 09:13:19
【问题描述】:

我正在尝试使用 MSTest 对 C# 中的方法进行单元测试。我正在测试 ChangePasswordAsync 方法强制密码复杂性。我的问题是我想用一系列参数测试这个方法。目前我有一个带有多个断言的单元测试来测试不同的参数,这是一个合理的解决方案吗?

我知道当我使用其他单元测试框架时,有办法用不同的参数测试方法。我可以在方法上使用一个属性来实现这一点吗?我的示例单元测试如下:

    /// <summary>
    /// Ensures that a password must meet the password complexity of a digit and an alphanumeric, 8 digits long and one
    /// special character.
    /// </summary>
    [TestMethod]
    public void TestPasswordComplexity()
    {
        var result = _UserManager.ChangePasswordAsync(_TestUser.Id, "Password123!", "1!").Result; //Changes the password.

        Assert.IsFalse(result.Succeeded);

        result = _UserManager.ChangePasswordAsync(_TestUser.Id, "Password123!", "123456789").Result; //Changes the password.

        Assert.IsFalse(result.Succeeded);

        result = _UserManager.ChangePasswordAsync(_TestUser.Id, "Password123!", "123456789!").Result; //Changes the password.

        Assert.IsFalse(result.Succeeded);

        result = _UserManager.ChangePasswordAsync(_TestUser.Id, "Password123!", "abcdefghijk").Result; //Changes the password.

        Assert.IsFalse(result.Succeeded);

        result = _UserManager.ChangePasswordAsync(_TestUser.Id, "Password123!", "abcdefghijK1!").Result; //Changes the password.

        Assert.IsTrue(result.Succeeded);
    }  

或者,您是否会将每个测试分成单独的单元测试?

【问题讨论】:

  • 每次测试有一个断言。拆分成不同的测试并相应地命名它们
  • 即使有多个断言,这在逻辑上也是一个单一的测试——你已经很好地命名了它并且它按照它所说的去做——它测试了密码的复杂性。将其分解为多个测试方法只会增加需要执行的测试数量。
  • @TomRedfern 你说的不是真的。如果第三个断言可能会失败,那么打破单独的测试将导致更好的理解和更好的可维护性。在上述场景中,只有一个测试会失败,但如果每个测试有一个断言,那么其他 4 个测试仍然有效。这样你就不用去调试找行了,导致测试失败。
  • @Dom84 我承认你关于测试失败解决粒度的观点——是的,你可以节省 10 秒时间,而不必调试测试。但是,您会如何称呼应该返回失败并输入“123456789!”的测试方法?公共无效的ShouldNotSetPasswordValue123456789!()?对我来说,当前测试方法的失败意味着我以某种方式破坏了密码复杂性检测算法。这就是我要解决问题所需要知道的全部内容。
  • 有点偏题,但我会特别考虑使用 specflow Scenario Outlines,因为它使添加新案例变得非常简单

标签: c# asp.net unit-testing mstest


【解决方案1】:

您可以添加数据行注释。

[TestMethod]
[DataRow ("1!")
[DataRow ("123456789")
[DataRow ("123456789!")
...
public void TestPasswordComplexity(string pass)
{
    var result = _UserManager.ChangePasswordAsync(_TestUser.Id, "Password123!", pass).Result; //Changes the password.

    Assert.IsFalse(result.Succeeded);
}

它将使用pass参数传递的每个数据行运行测试方法。

为第五个Assert.IsTrue(result.Succeeded) 案例创建一个单独的方法

【讨论】:

    【解决方案2】:

    为每个测试编写一个带有含义全名的单独单元测试方法。 因此,当稍后测试失败时,您很容易发现问题所在。

    您必须区分不同的测试和不同的测试参数。 你的一些断言会失败,因为密码由于某种原因很弱,有些 应该通过。

    如果您确实需要不同的参数,可以使用DataSource(参见http://msdn.microsoft.com/en-us/library/ms182527.aspx),您可以在其中添加外部源作为输入的excel文件。

    例如,您可以使用 excel 源测试通过密码。

    【讨论】:

      猜你喜欢
      • 2011-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多