TDD FIRST原则

问题描述 投票:21回答:3

我不明白如何在以下代码中遵守TDD FIRST principle

以下是关于FIRST原则的说明:

  • 快速:快速运行(子集)测试(因为您将一直运行它们)
  • 独立:没有测试依赖于其他测试,因此可以按任何顺序运行任何子集
  • 可重复:运行N次,得到相同的结果(以帮助隔离错误并启用自动化)
  • 自检:测试可以自动检测是否通过(没有人工检查输出)
  • 及时:与被测代码同时写入(使用TDD,先写!)

测验问题:

莎莉希望她的网站在每个月的第一个星期二有特别的布局。她有以下控制器和测试代码:

# HomeController
 def index
   if Time.now.tuesday?
     render 'special_index'
   else
     render 'index'
   end
 end

 # HomeControllerSpec
 it "should render special template on Tuesdays" do
   get 'index'
   if Time.now.tuesday?
     response.should render_template('special_index')
   else
     response.should render_template('index')
   end
 end

没有遵循什么第一原则?

  1. 快速
  2. 独立
  3. 重复
  4. 自检
  5. 及时

我不确定哪个FIRST原则没有被遵守:

  • 快速:代码似乎很快,因为它的测试并不复杂。
  • 独立:测试不依赖于其他测试。
  • 可重复:每次测试都会得到相同的结果。 'special_index'如果是星期二,'index',如果它不是星期二。
  • 自检:测试可以自动检测是否通过。
  • 及时:代码和测试代码同时显示在此处。

我在测验中选择了Timely,因为测试代码是在控制器代码之后呈现的。但我提出的问题是错误的,回想起来,这不是一个好的选择。我不确定这里没有遵循哪个FIRST原则。

tdd
3个回答
32
投票

这不是Repeatable,因为星期二不是每天都有:)如果你在星期一进行这个测试你会得到一个结果,如果你在星期二运行它,另一个。


0
投票

独立和可重复

它不是独立于日期,然后它可以运行重复,但从技术上讲,你会得到相同的结果,因为你选择

对HomeController进行FIRST概念测试的正确方法是改变评估阶段之前的时间


0
投票

是的,混淆部分原因是F.I.R.S.T.关于“我”的原则不够完整或简明。在我参加的课程中,该原则被称为F.I.I.R.S.T.

第二个“我”代表“孤立”。上述测试独立于其他测试,但不在单独的类或项目中隔离。

[更新]:

隔离可能意味着:

  • 单元测试从SUT(被测系统)中隔离功能。您甚至可以通过单个功能隔离功能。这绘制了单元测试或其亲属组件测试和集成测试之间的界限,当然还有系统测试。
  • “测试可以隔离故障。开发人员不应该对测试或被测试的代码进行逆向工程,以了解出现了什么问题。每个测试类名称和测试方法名称以及断言文本应该准确说明错误和位置。”参考:History of FIRST principle
  • 可以从SUT中隔离单元测试,它在不同的开发人员工件(类,包,开发项目)和/或交付工件(Dll,包,组件)中进行测试。
  • 单元测试,测试相同的SUT,尤其是它们包含的Asserts,应该在不同的测试函数中相互隔离,但这只是一个建议。理想情况下,每个单元测试只包含一个断言。
  • 测试不同SUT的单元测试应该彼此隔离或者与其他类型的测试隔离,当然在不同的类别或其他提到的工件中也是如此。

独立意味着:

  • 除了特殊的“设置”和“拆卸”功能外,单元测试不应相互依赖(显式独立),但即便如此,也需要进行讨论。
  • 特别是单元测试应该是与顺序无关的(隐式独立性)。结果不应该依赖于之前执行的单元测试。虽然这听起来微不足道,但事实并非如此。有些测试无法避免进行初始化和/或启动运行时。只有一个共享(例如类)变量和SUT可能会有不同的反应,如果之前启动的话。你打电话到操作系统?有些dll会第一次加载吗?您已经有了潜在的依赖关系,至少在操作系统级别上 - 有时只是次要的,有时候不会发现错误。可能需要添加清理代码以达到最佳的测试独立性。
  • 单元测试应尽可能独立于运行时环境,而不依赖于特定的测试环境或设置。这也部分属于“可重复”。之前无需填写20个用户对话框。无需启动服务器。无需提供数据库。不需要其他组件。不需要网络。为了实现这一点,通常使用测试双打(存根,模拟,假货,假人,间谍......)。 (Gerard Meszaros' classic work on: xUnit patterns, here coining the name 'test double' and defining different kinds of) (Test double zoo quickly explained) (Follow Martin Fowler 2007, thinking about stubs, mocks, etc. Classic
  • 虽然单元测试永远不会完全独立于它的SUT,但理想情况下它应该尽可能独立于当前实现,并且只依赖于函数或类测试的公共接口(SUT)。

结论:在这种解释中,“隔离”一词更强调物理位置,这在某种程度上通常意味着逻辑独立性(例如,类级隔离)。

声称可能更具强调性和含义的完整性。

另见这里的评论。

但是(好的)单元测试还有更多属性:Roy Osherove在他的“单元测试艺术”一书中找到了更多的属性,我在F.I.I.R.S.T中找不到。原则(link to his book site),这里引用我自己的话(和首字母缩略词):

  • 完全控制SUT:单元测试应该完全控制SUT。我认为这与测试和运行时环境(例如使用模拟等)无关。但由于独立性如此暧昧,单独写一封信是有道理的。
  • 自动化(与可重复和自检相关,但不相同)相同)。这个需要测试(跑步者)基础设施。
  • 相关:明天的测试应该是相关的。这是最困难的要求之一,并且取决于“学校”,在TDD期间可能还需要临时单元测试。当测试仅测试合同时,这是很好的,但这可能不足以满足高代码覆盖率要求。
  • 一致的结果:有效地产生“足够”的独立性。一致性是,一些人在“可重复”中包含的内容。有重要的重叠,但它们并不完全相同。
  • 自我解释:在命名,整个测试的结构,特别是断言作为关键字的语法方面,应该清楚测试的是什么,如果测试失败可能会出错。与“测试隔离故障”相关,请参见上文。
  • 小,简单或用他的话说:“易于实施”(再次,相关,但不完全相同)。通常与“快”相关

鉴于所有这些特定点,应该比以前更清楚,编写(好)单元测试几乎都很简单。

© www.soinside.com 2019 - 2024. All rights reserved.