用于为具有多个执行路径的函数编写测试的TDD过程

时间:2011-03-13 20:05:04

标签: unit-testing tdd

在进行测试驱动开发之后,我遇到了一个我需要编写的函数,它与以下类似:

public MyClass DoSomething(string value)
{
    SomeClass existCheck = repository.Get(value);

    if(existCheck == null)
        throw new InvalidOperationException("SomeClass must exist to do something");

    if(existCheck.MyClass != null)
        return existCheck.MyClass;

    MyClass myClass = new MyClass()
    {
        // create object
    };

    return myClass;
}

使用TDD,我需要编写单独的测试

  1. 断言抛出异常
  2. 断言现有SomeClass已退回
  3. 断言返回新的MyClass
  4. 我先编写all三个测试然后编写代码,还是编写每个测试,然后编写测试通过所需函数的功能,然后编写下一个测试,代码编写功能等。 ?

4 个答案:

答案 0 :(得分:4)

我一直认为,对于TDD,你应该采用红灯绿光方式采取婴儿步骤。我将按以下步骤进行:

  1. 为existsCheck == null场景编写测试,该测试将失败(红灯)
  2. 为方案1做必要的工作,然后重新运行测试(绿灯)
  3. 为existsCheck.MyClass!= null场景编写第二个测试,该测试将失败。您通常可以通过复制第一个测试并进行修改来完成此操作。
  4. 修改方法,使测试1和2都通过。
  5. 对最终执行路径重复步骤3和步骤4.
  6. 通常,我发现随着方法的进行,您可以继续进行测试,然后在每次到达分支时复制测试,将每个测试定制到每个不同的路径。

答案 1 :(得分:2)

为每个预期的行为编写单独的测试。

一个好的经验法则是每个测试通常应包含一个断言。

编辑 - 回答实际提出的问题......

TDD过程是编写每个测试,让它通过,然后重构你所做的。只有在完成后才能继续编写下一个测试。

从技术上讲,你可以预先编写其他测试,但是将它们注释掉,就好像它们还没有被编写一样。尽管如此,在未来的测试中花费的时间很少,因为你可能会发现它们是错误的测试,基于你做的第一个通过,然后重构你之后做的。

答案 2 :(得分:2)

TDD的基本工作流程是红色/绿色/重构

  1. 首先编写测试,它应该失败(红色)。

  2. 尽可能少地编写生产代码(并尽可能简单)以使测试通过(绿色)。

  3. 重构保留绿色状态的生产代码。

  4. 如果您发现并非所有内容都已实现,请从第1点开始。因此,在您的情况下 - 您可能先编写所有测试,然后为第一个分支实现写入测试的所有内容,通过写第一个条件,为第二个分支写入测试,使其通过等使其变为绿色

    在我看来,在开始实际代码之前有一个完整的问题描述(完整的测试套件),而不是从测试代码切换到生产代码,这很好。

答案 3 :(得分:0)

这取决于你的攻击角度。如果你已经找到了整个类的模式 - 你的问题就是这个 - 然后你写了所有的测试。如果您的代码以较小的步骤发展,那么您当时就会进行测试。 TDD的关键点是首先编写测试。