单元测试:敏捷并知道要测试什么?根据要求进行测试

时间:2012-07-22 16:49:23

标签: unit-testing tdd bdd

之前,我曾经只是为了测试一个方法是否有效来实现单元测试。但是在其他地方读完后,看来我应该在方法失败时进行测试。

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

这些要求来自哪里?

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

然后我根据需求从这个用户故事中创建任务。

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

我想我应该测试一下这个方法(作为用户故事的一部分的任务的一部分)的功能应该如何,但我还应该测试它应该在什么时候失败?

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

有没有人知道有关此主题的更多资源或链接?

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

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

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

因此,对于您的示例,传递给方法的字符串必须不超过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个字符
  •   

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

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

毕竟,该方法正在做所有这些事情。如果方法正在做某事,那应该测试一下。最终,代码所做的一切应该至少有一个映射到需求的相应测试。

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

如果有一行代码没有通过测试执行,那么为什么那行代码呢?如果没有测试,则不需要它。如果没有要求,请将其删除。

答案 2 :(得分:1)

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

当您覆盖所有幸福路径时,请继续边界测试。因此,当它应该是8个字符的密码时,然后对7,8,9个字符进行测试并覆盖其中的场景。

在您完成所有快乐路径和边界测试之后,问问自己如何编写失败测试?如果您能解决它,那么请写下来。如果应该提出异常,则覆盖它。考虑到这一点,您可以轻松地找出应该测试的内容以及不必要的内容。