4

我开始使用 JavaScript 的测试驱动开发,但我想开始在我的不同项目中使用它。

我想知道典型的错误是什么以及如何避免它们?

另外,我想知道我应该阅读什么以使测试驱动开发更容易学习和应用于我的代码。

提前致谢。

4

3 回答 3

10

我在使用 TDD 时遇到的最大问题是开发人员对单元测试没有信心。糟糕的单元测试浪费的时间多于节省的时间。混乱的、不可信的、不可维护的、不可读的测试很快就被淘汰了,厌倦的开发人员需要时间想要再次自动进行单元测试。

Per Fagrell 提出了一些很好的观点,尤其是在每次更改后运行测试方面;在任何测试更改之前和之后运行测试应该成为第二天性。


构架:

将 QUnit 视为您的 JS 测试框架:http ://docs.jquery.com/Qunit

我有一个带有依赖标记的测试工具页面,并且测试在页面加载时运行得非常好。

你可以按照

  • 安排
  • 行为
  • 断言

使用 QUnit 进行单元测试的流程。

但是,您必须手动实现测试设置和拆卸方法并在测试方法中调用它们。这些将通过保持所有测试的条件相同并防止测试依赖于它们的运行顺序来帮助隔离测试用例。

在您将使用的其他语言中寻找有用的框架。NUnit在 .NET 中非常流行。


隔离:

Per Fagrell 也对隔离提出了一个很好的观点。在开始测试之前,应该彻底理解单元测试(测试功能原子的一个方面)和集成(测试多个原子如何协同工作)之间的区别。如果您在测试方法中有多个断言,则您不是单元测试,需要更改您的测试方法。


约定:

来自优秀的单元测试艺术的一个很好的命名约定是MethodUnderTest_Condition_ExpectedBehaviour例如

Expand_TextVariable_ExpandsText

同一本书中保留您的测试:

  • 值得信赖
  • 可维护
  • 可读

否则,您和其他开发人员将不会费心运行测试。


假货:

一个常见的误解是两种假货之间的区别:存根模拟

通过将代码所依赖的功能抽象到接口中来在代码中创建接缝。例如,控制器不依赖于具体的存储库,它将依赖于 IRepository。

然后一个存根实现这个 IRepository 并返回伪造的值;它用于隔离控制器代码以隔离运行。例如GetCustomer(),将创建一个新客户并将其返回,而无需调用真正的存储库或任何商店。存根永远不会针对. 模拟
就像 一个存根,除了它可以保存可以测试的值。例如,您的模拟将接受该值并可以断言。模拟可以针对.AddCustomer(Customer customerToBeAdded)

看看一个测试隔离框架(或模拟框架),它可以为给定的接口自动创建假货。

对 mock 用途的误解导致不止一个开发人员创建了一个 mock 来测试功能,然后针对 mock 本身编写测试。


资源:

我已经提到了单元测试的艺术,我彻底推荐它。这是一本书,连同 Code Complete,如果办公室着火了,我会去拿。

希望有帮助。

于 2010-12-16T12:31:53.970 回答
3

确保您的测试只测试一项功能。名称和断言也应该与之完全一致。例如,如果您将 expand() 函数添加到变量处理程序,那么测试应该(大致)称为 test_expands_variables 或 should_expand_defined_variable 或任何符合您命名约定的名称,并且断言应该在返回值或副作用上的函数调用。一个常见的错误是断言设置步骤,但是设置中的任何功能都应该有自己的测试,并且该断言已经到位。如果您在任何地方都断言相同的事情,那么突然很难看出您应该修复哪个测试。

了解整个 TDD 循环的一个很好的起点是尝试一些 code-kata。罗马数字转换器是首先编写测试的常见介绍。一开始,在每一个微小的变化之后都对运行测试保持冷静。一旦你掌握了它的窍门,你就会感觉到你需要/应该有多么痴迷,但是对于初学者来说,让节奏保持正常通常需要非常迂腐。

于 2010-12-16T11:48:49.853 回答
0

通过 Christian Johansen 的“测试驱动的 JavaScript 开发”一书,我开始接触 Javascript 中的 TDD。它非常棒,几乎解决了 TDD 的所有方面并将其应用于 JS:http ://tddjs.com/

于 2011-01-30T16:35:20.583 回答