【问题标题】:TDD FIRST principleTDD FIRST 原则
【发布时间】:2021-01-22 22:22:50
【问题描述】:

我不明白为什么TDD FIRST principle 没有在以下代码中得到遵守。

这些是我对 FIRST 原则的注释:

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

测验问题:

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

# 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

什么 FIRST 原则没有被遵循?

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

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

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

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

【问题讨论】:

    标签: tdd


    【解决方案1】:

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

    【讨论】:

    • 如果一周中的每一天都有单独的测试,那将是遵守的,对吧?
    • @Renan:不,如果一个人可以注入一个日期并验证它是否在它认为是今天的日期时做了正确的事情,那将是坚持的。届时,您可以一次全面地进行全面测试,而无需考虑当前日期,而不必等待长达一周并每天进行测试。
    【解决方案2】:

    F.I.R.S.T.F.I.I.R.S.T.FASRCS

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

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

    [更新]:

    隔离可以表示:

    • 单元测试将功能与 SUT(被测系统)隔离开来。您甚至可以从一个功能中分离出功能。这在单元测试或它们的相关组件测试和集成测试之间划清了界限,当然还有系统测试。

    • “测试隔离失败。开发人员永远不必对测试或被测试的代码进行逆向工程才能知道出了什么问题。每个测试类名称和测试方法名称以及断言文本都应该准确说明错误和在哪里。”参考:History of FIRST principle

    • 单元测试可以与它在不同的开发人员工件(类、包、开发项目)和/或交付工件(Dll、包、程序集)中测试的 SUT 隔离。

    • 单元测试,测试同一个 SUT,尤其是它们包含的 Asserts,应该在不同的测试函数中相互隔离,但这只是一个建议。理想情况下,每个单元测试只包含一个断言。

    • 单元测试,测试不同的 SUT,应该相互隔离,或者在不同的类或其他提到的工件中与其他类型的测试隔离。

    独立可以表示:

    • 单元测试不应相互依赖(显式独立),除了特殊的“setup”和“teardown”函数,但即便如此,也有待讨论。

    • 特别是单元测试应该是顺序无关的(隐式独立)。结果不应依赖于之前执行的单元测试。虽然这听起来微不足道,但事实并非如此。有些测试无法避免进行初始化和/或启动运行时。如果之前启动了一个共享(例如类)变量,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) 的公共接口。

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

    关于可能更多的重音和含义声称不完整。

    参见此处的 cmets。

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

    • 完全控制SUT:单元测试应该完全控制SUT。我认为这实际上与独立于测试和运行时环境相同(例如使用模拟等)。但是因为独立性太暧昧了,花一个单独的字母是有道理的。

    • A自动化(与可重复和自检有关,但不一样) 同样)。这需要一个测试(运行器)基础架构。

    • Sma​​ll,简单或用他的话来说:“易于实施”(再次,相关,但不相同)。通常与“快”有关

    • R相关:明天的测试应该是相关的。这是最难达到的要求之一,根据“学校”的不同,在 TDD 期间也可能需要进行临时单元测试。当测试只测试合约时,这是可以实现的,但这可能不足以满足高代码覆盖率要求。

    • C始终如一的结果:实际上是“足够”独立性的结果。一致性是某些人在“可重复”中包含的内容。存在本质上的重叠,但它们并不完全相同。

    • S简明解释:在命名、整个测试的结构,特别是作为关键行的assert的语法方面,应该清楚测试什么,可以测试什么如果测试失败,那就错了。与“测试隔离失败”相关,见上文。

    鉴于所有这些具体点,应该比以前更清楚,编写(好的)单元测试几乎是简单的。

    【讨论】:

    • 不会独立包含独立吗?至少这是我对这个词的解释。
    • 这两个术语的含义似乎相似,但详细地列出了您对它们的含义。隔离在这里主要是指恕我直言,即 1. 单元测试隔离功能,理想情况下仅包含一个断言,并且与集成或系统测试完全不同。 2. 单元测试通常被隔离在单独的类甚至项目/包/程序集中,但将它们与 SUT 隔离并不一定意味着它们确实独立于 SUT,很明显。
    • 对独立性的理解或强调显然不同。独立于什么?测试对 SUT 的完全独立性?并不真地!独立于 SUT 的实现(与公共接口相比)?是的,这是测试策略(和测试生命周期)的重要一点,但并非所有单元测试都满足这一点。其他测试的运行顺序的独立性是关键点之一。非常琐碎,测试相互隔离是独立于它们相互独立(尤其是顺序独立)的:-)
    • 好的,抱歉开了个玩笑。我的意思是,您可以将它们收集在一个类甚至一个测试功能中,那是另一回事。更多的独立性:环境的独立性是单元测试的一个重要属性。如果您需要数据库或连接网站,则不是单元测试。这再次与“可重复”有关,但又不意味着相同。好吗?
    【解决方案3】:

    独立且可重复

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

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

    【讨论】:

    • 我认为“独立”代表:对其他测试的依赖。示例中不是这种情况。
    猜你喜欢
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多