重要的是,我正在尝试通过先编写所有测试,然后再创建代码来进行TDD。问题在于,“先编写所有测试”绝对不是“进行TDD”。测试驱动开发包括许多“红-绿-重构”周期的小重复:
- 将单元测试添加到测试套件中,运行它并观察它失败(红色)
- 仅向被测试系统添加足够的代码以使所有测试都通过(绿色)
- 在保持所有测试通过的同时改进被测试系统的设计(通常是通过消除重复)(重构)
如果您一开始就编写整个庞大的测试套件,那么您将花费很长时间才能达到“绿色”(所有测试都通过)状态。
“但是,应用程序无法编译,因为我的对象或方法不存在。”
这是任何编译语言的典型问题;这不是TDD问题本身。这意味着,为了观察新测试失败,您可能必须编写一个最小的存根,以使编译器满意。
例如,我可以编写以下测试(使用NUnit):
[Test]
public void DefaultGreetingIsHelloWorld()
{
WorldGreeter target = new WorldGreeter();
string expected = "Hello, world!";
string actual = target.Greet();
Assert.AreEqual(expected, actual);
}
我需要编写大量的代码才能让应用程序编译,并使测试失败:
public class WorldGreeter
{
public string Greet()
{
return String.Empty;
}
}
一旦我构建出解决方案并看到了失败的测试,我可以添加代码使第一个测试通过:
public string Greet()
{
return "Hello, world!";
}
一旦所有测试都通过,我就可以查看受测系统并确定如何改进设计。但是,在进行重构之前,完成“红色”和“绿色”步骤对于TDD学科非常重要。
“我认为整个重点在于,随着您开发测试,您可以开始看到重复等问题,以便在编写单行代码之前进行重构。”(引用)
Martin Fowler将
refactoring定义为“一种有纪律的技术,用于重新组织现有的代码体,
更改其内部结构而不改变其外部行为”(强调添加)。如果您还没有编写任何代码,则没有什么可以重构的。
“所以问题是,是否有方法可以做到这一点,还是我做错了?”(引用)
如果您想进行TDD,则恐怕您做错了。您可能能够通过您正在做的事情交付出色的代码,但这不是TDD。无论是否存在问题,这都取决于您自己决定。