3

类通常通过使用以下语法编写的测试进行测试,这些语法由大量测试框架(例如 Ruby 的 Unit::Test;或本例中的 MiniTest)提供:

class TestLolcat < MiniTest::Unit::TestCase
  def setup
    @lolcat = Lolcat.new
  end   
  def test_that_lolcat_can_have_cheezburger
    assert_equal true, @lolcat.i_can_has_cheezburger?
  end
end

或者使用第二种语法编写的测试,由一组重叠的测试框架提供(例如 RSpec;或者在这个例子中,MiniTest 再次):

describe Lolcat do
  before do
    @lolcat = Lolcat.new
  end
  it "must be able to have cheezburger" do
    @lolcat.i_can_has_cheezburger?.must_equal true
  end
end

(可能还有其他语法系列也适用于测试类方法和属性,但这是我感兴趣的两个。)

我想知道的是:这两个语法家族的正确名称是什么?

如果您想了解更多关于我为什么要问的信息,请参阅该行下方。


我问这个问题的原因是搜索网络并没有产生明显的共识。例如,MiniTest 文档将上面的第一个语法称为“单元测试”语法,将第二个语法称为“规范”语法。相比之下,Michael Hartl将用第二种语法编写的类方法和属性测试描述为“单元测试”。用这种语法编写的测试测试由多个类的交互产生的更高级别的功能,他称它们为“集成测试”

我还看到人们将第一种和第二种语法分别描述为"Test::Unit style""RSPec-esque""TDD"语法和"BDD"语法。第二种语法的其他名称包括'should-like syntaxit syntax

我的理解(含糊地表明 Hartl 是正确的)如下:

  • TDD是一种实践,而不是一种测试语法。具体来说,通常是编写一个失败的测试(例如单元测试或集成测试),然后编写代码使测试通过,然后在适当的情况下进行重构,然后重新开始循环。
  • BDD也是一种实践,但它确实对测试语法做出了一些有限的规定。具体来说,它是遵循 TDD 的做法,但在测试名称中使用“应该”作为第一个单词,并在适当的情况下嵌套测试代码以提供上下文。
  • 单元测试是一种实践,而不是一种测试语法。特别是测试单个代码单元的实践(例如类方法或属性)
  • 单元测试是在单元测试过程中编写的测试,与使用的语法无关。
  • 集成测试是一种实践,而不是一种测试语法。特别是测试由多个类的交互产生的高级功能的实践。

但是,这仍然不能完全解决问题。显然,我不是测试实践命名法、测试类型或测试语法方面的专家。对于上面给出的两种语法,我能想到的最好的名称分别是"'assert' syntax""'it ... do' syntax"。除非这些名称被广泛使用,否则我需要您的建议,StackOverflow 用户!

4

4 回答 4

3

我不确定每个都有一个公认的定义。

我喜欢以这些方式思考它们。

迷你测试版更像是一种断言

rspec 版本更像是一个规范

后者是为了引导您远离对“测试”的强调,而更多地是为了从利益相关者的角度排除需求。

于 2012-06-21T12:08:09.657 回答
3

如果我们分享一些关于 BDD 和 TDD 的历史,它可能会澄清一些事情。

早在 2003 年,TDD 选择的单元测试框架是 JUnit。Dan North 开始编写 JBehave 作为 JUnit 的替代品,使用“should”而不是“test” ——因此,BDD 语法。现在这看起来与您在 Ruby 中所做的(以及 RSpec 所做的)不太相似,但尽管如此,RSpec 是作为同一事物的 Ruby 版本创建的。JBehave 从未嵌套测试代码;它只有“应该”用于单元级示例,然后是其他一些用于运行全系统场景的 gubbins。Dan 将场景运行器迁移到 Ruby,在那里它成为 RSpec 故事运行器,然后最终成为 Cucumber。

因此,“它...应该”语法绝对是单元级 BDD。大多数人都熟悉 BDD 作为全系统场景,但这并不是 BDD 的起点。如今,BDD 并不是一种真正的实践。这是一种直接用于项目愿景的迷你方法——以防万一你遇到类似的困惑。并且 JBehave 2.0 被重写以处理场景和步骤,并且失去了单元级测试以及模拟框架,因为那时 JUnit 和 Mockito 运行良好。但是,尽管如此,这就是“应该”开始的地方。

现在......一旦你使用“必须”而不是“应该”,你就会失去“应该”提供的不确定感。使用“应该”可以让您提出很多问题,其中最重要的是“应该吗?” 所以,任何使用“必须”而不是“应该”的东西都不再是真正的 BDD 语法了。这是一个混合体。

顺便说一句,我们在谈论 BDD 时尽量避免使用“测试”一词,因此它们不是在测试过程中编写的单元测试;它们是在设计代码的过程中编写的类行为方式的示例。

于 2012-06-25T08:09:19.810 回答
0

在处理软件时,需要区分“什么”和“如何”:程序应该做什么,它是如何工作的。

恕我直言,重要的是要记住在开发的所有阶段两者之间的区别。这种区别支持几个原则,例如针对接口编码责任驱动设计合同和断言设计以及单元测试。

唉,将这两个概念解耦并不总是那么容易。诸如排序之类的经典示例很容易处理:存在几种排序算法(如何排序),它们都产生一组排序的元素(什么),可以很容易地表示为断言、契约、不变量。对于业务代码,情况可能变得不太清楚。

我相信这两种语法从根本上实现了相同的目标,但第二种方法有助于思考“什么”,而不是“如何”。让我们考虑两个陈述:

断言值 % 2 = 0

值应该是偶数

它们强制执行相同的不变量,但第二个更强调“什么”,并且更易于阅读。

Smalltalk 使用例如这种should措辞,但测试是类似于 Ruby 中的命令式代码。

SetTestCase>>testAdd
    empty add: 5.
    self should: [empty includes: 5]

不幸的是,我的题外话仍然没有回答你的问题,而且评论太长了。

于 2012-06-21T12:45:35.310 回答
0

测试方法没有全球公认的语法名称。大多数单元测试工具都鼓励某种约定,比如 JUnit 鼓励所有测试方法名称都以“test”开头,现在通过 @Test 注释已经不需要了。

大多数单元测试工具都建议开发人员同意的某种约定。测试方法名称没有语法,因为目标受众是应该很容易掌握测试方法功能的开发人员。

如果您正在寻找测试上下文中的定义,请查看 Gerard Meszaros 的“xUnit 测试模式”一书。作者对不同的术语进行了一些澄清。他对“测试替身”的定义已被多次引用。

于 2012-06-21T12:43:21.043 回答