【问题标题】:Unit Testing: Agile and knowing what to test? Testing against requirements? [closed]单元测试:敏捷并且知道要测试什么?根据要求进行测试? [关闭]
【发布时间】:2012-07-22 16:49:23
【问题描述】:

以前,我实现单元测试只是为了测试方法是否有效。但在其他地方阅读后,似乎我应该在方法失败时进行测试。

例如,一个方法应该抛出一个异常,它传递了一个字符串。

这些要求从何而来?

我在一个敏捷团队中工作,因此我们会获得用户故事,其中包括应用程序功能的基本要求。这些基本要求包括非常简单要求(即密码长度最多应为 8 个字符)。

然后,我会根据该用户故事创建任务并考虑需求。

因此,在测试时……我究竟应该测试什么?

我想我应该测试该方法(它是作为用户故事的一部分的任务的一部分)以它应该的方式运行,但我还应该测试它是否应该失败?

例如,当要求最多 8 个字符时,将 12 个字符传递给方法的参数(密码)。我必须为此包含一个测试用例吗?

有没有人知道一个很好的资源或链接来解释这个主题的更多信息?

我假设没有要求,我只能测试方法是否成功以及是否失败,因为没有要求,我不知道它什么时候应该失败?

任何人都可以提供的任何帮助都会非常有帮助。

【问题讨论】:

标签: unit-testing tdd bdd


【解决方案1】:

我认为您对失败测试的阅读过多。这意味着在编写代码之前编写测试(除了总是返回无效值如 null 的存根)。这样你就知道当它失败时你有代码要写。然后,您编写代码并再次测试。测试现在应该通过了。测试驱动的开发应该总是这样工作。

【讨论】:

  • +1。更好的是,在编写代码以使其通过之前,您的测试应该失败并显示一个清晰、有意义的错误消息
【解决方案2】:

虽然您当然无法测试每一种可能性,但您应该至少测试代码中考虑的可能性。

因此,在您的示例中,传递给方法的字符串不得超过 8 个字符(顺便说一句,这是对密码的可怕要求),该方法可能看起来像这个:

public bool IsPasswordCorrect(string password)
{
    if (password.Length > 8)
        throw new ArgumentException("Password must not be greater than 8 characters.");

    return password == SomeKnownPassword;
}

目标应该是 100% 的代码覆盖率。这意味着实际执行某些操作的每一行代码都应该至少有一个相应的测试。因此,如果唯一的测试是“快乐路径”(不超过 8 个字符的字符串),那么永远不会测试 throw 行。

那行代码是为了响应需求而存在的,因此应该测试该需求。在这种情况下,您需要进行一些测试:

[TestMethod]
public void MatchingPasswordsShouldBeAllowed()
{
    // set the known password
    // set the passed password
    // call the method
    // assert that the method returned true
}

[TestMethod]
public void NonMatchingPasswordsShouldNotBeAllowed()
{
    // set the known password
    // set the passed password to something else
    // call the method
    // assert that the method returned false
}

[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void PasswordsShouldNotBeGreaterThanEightCharacters()
{
    // set the known password
    // set the passed password to something too long
    // call the method
    // assert that an exception was thrown
}

注意测试方法的名称。它们听起来像是要求。这个想法是,陈述的需求应该被分解成实际的规范。业务要求是:

  • 密码不得超过 8 个字符

但是那里有隐含的要求吗?要求如下:

  • 提供的与已知密码匹配的密码应该会导致身份验证。
  • 提供的密码与已知密码不匹配不应导致身份验证。

毕竟,方法正在做所有这些事情。如果该方法正在做某事,则应该测试该方法。最终,代码所做的每一件事都应该至少有一个对应的测试来映射到一个需求。

事实上,如果测试写得好,它们就会开始成为需求。这很好,因为这意味着相关知识(需求)可以保存在一个地方(测试),而不是多个不同的地方(测试、代码、文档、白板等)。

如果有一行代码没有被测试执行,那为什么那行代码在那里?如果没有测试,那么就没有要求。如果没有要求,请将其删除。

【讨论】:

    【解决方案3】:

    快乐路径测试开始。您的快乐路径应该基于需求中的用例。

    当您涵盖了所有成功的路径后,继续进行边界测试。因此,当它应该是 8 个字符的密码时,请对 7、8、9 个字符进行测试并涵盖相应的场景。

    在你涵盖了所有的快乐路径和边界测试之后,问问自己我怎样才能写出失败的测试?如果你能弄明白,那就写吧。如果应该提出异常,则将其覆盖。考虑到这一点,您可以轻松找出应该测试的内容以及不需要测试的内容。

    【讨论】:

      猜你喜欢
      • 2010-09-08
      • 2018-01-18
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多