代码之家  ›  专栏  ›  技术社区  ›  ryeguy

为什么cucumber被认为是集成测试工具而不是单元测试工具?

  •  12
  • ryeguy  · 技术社区  · 14 年前

    这一直困扰着我。为什么人们说rspec中的单元测试而黄瓜中的集成测试呢?我不是问为什么这些测试是必要的-我知道集成和单元测试之间的区别。我只是不明白,考虑到cucumber完全可定制的语法,为什么它不用于单元测试?

    在我看来,为cucumber和rspec编写的代码量是一样的,唯一的区别是,对于cumber,您将测试逻辑与测试编写分开。

    5 回复  |  直到 13 年前
        1
  •  9
  •   Igor Zevaka    14 年前

    在使用cucumber进行单元测试时有很多开销。不仅要编写特性,还要使用单独的代码将它们映射到实现中。

    单元测试意味着编写速度和执行速度都非常快。当然,cucumber关注的是最终用户体验,这主要是由于编写特性时使用的语言。

    为了刷新,功能将包含以下内容:

    作为系统的利益相关者
    我想做一个活动
    这样我就能从中得到一些好处

    Given a precondition
    When I perform an action
    Then something should happen
    

    开头的段落通常被忽略,它为操作设置上下文并解释 为什么? 有事发生了。由于使用了自然语言,这些东西很容易展示给非程序员,以便获得一些反馈。

    现在,用这些来进行单元测试充其量看起来很尴尬。首先,终端用户的关注点建议了一种更为集成的方法,因为该特性没有提到mock和UI/逻辑分离。一、 e.像下面这样的功能看起来很奇怪:

    Given a that a database mock is configured with the following data
    | ID  | Username |
    | 0   | igor     |
    When call FindAll on User Repository
    Then I get the following user back
    | ID  | Username |
    | 0   | igor     |
    

    而且,随着SUT变小(即类),操作的上下文也就不那么重要了。用户存储库不关心上下文,例如,它不关心它的使用者是普通用户还是VIP用户。一个简单的组件(它应该是SRP之后的组件)是基于其输入的完全确定性的。

    因此,单元测试是为了验证你所写的是正确的,而cuccmber测试是为了验证你所写的内容是否满足某种更高的目的,将系统的行为放在上下文中。

        2
  •  5
  •   Lunivore    14 年前

    Cucumber解决了一组特殊的问题——让那些不容易阅读代码,当然也不会编写代码的业务涉众参与进来,并在自动化场景中的各个步骤之间提供重用。这些场景通常还涵盖行为的多个方面,记录整个系统的功能,并经常涵盖跨多个组件的整个用户旅程。cumber鼓励的基于步骤的体系结构非常适合处理这些场景。

    它还引入了一整套其他问题。首先,您需要将Cucumber场景绑定到一组fixture,这样就有了另一个抽象层,使得它们的编写速度变慢。其次,英语比代码更难重构——即使是像Ruby这样的动态语言(在C#和JBehave、SpecFlow、Cuke4Nuke和Cuke4Duke这样的Java变体中,这种差异仍然更明显)。很难判断是否仍在使用步骤,也很难维护场景。在各个步骤之间管理状态也比较困难。

    对于单元测试,受众是技术性的。理想情况下,类具有单一的职责,几乎没有重复,因此重用步骤并不重要。当我们想要改变一个代码元素时,我们倾向于寻找其命名约定与文件或类匹配的测试,因此一对一的映射是理想的。

    由于Cucumber的管理费用,并且由于我们无法从Cucumber提供的作为其管理费用回报的好处中获得价值,RSpec更适合在单位级别上的行为。(JUnit、NUnit等也是如此)

    如果你错过了黄瓜的“给的,什么时候,然后”,试着添加它们作为评论。这对我很有效。

        3
  •  1
  •   danielz    14 年前

    一般来说,Cucumber测试比传统的单元测试编写得更高。例如,当您单元测试一个特定的模块时,您的重点是只测试与系统其他部分隔离的模块功能。系统其他部分的接口通常应该用模拟对象表示。

    另一方面,Cucumber专注于从UI一直到数据持久层的系统测试。

    单元测试=机械工程师在安装在安全带上的实验室环境中测试他的新发动机。

    黄瓜测试=测试车手把它放在赛道上旋转。

        4
  •  0
  •   carlosayam    13 年前

    单元测试是测试特定的 单元 孤立的代码。通常的粒度是类中的一个方法(或几个交互方法)。

    集成测试的重点是测试应用程序堆栈的许多层。例如,可以运行一个集成测试来检查代码与数据库的交互。大多数集成测试集中在两层或三层对象上。

    Cucumber测试尤其倾向于关注完整的应用程序堆栈,因为它们通过在界面和应用程序的所有层(从UI到后端服务(数据库、文件系统、网络等)中模拟真实用户来运行应用程序。

    底线:

    单元测试检查一段特定的代码是否遵守它与世界其他地方的契约。。。

    而黄瓜测试检查 相互作用 几段代码(一些人可能会说是一段垂直的代码)中的另一个优点是测试本身读起来像普通英语。

        5
  •  0
  •   mrcallahat    11 年前

    根据Aslak Helles¸y的说法,Cucumber不是一个测试工具,而是一个协作工具(用于BDD)。他最近发表了一篇关于这种明显误解的文章:

    https://cucumber.pro/blog/2014/03/03/the-worlds-most-misunderstood-collaboration-tool.html

    也就是说,有很多测试是在可接受级别以下编写的,这些测试将落在集成测试层的周围。即,

    Given a user at 123 Evergreen Terrace
    When I lookup their name
    Then I get Homer Simpson
    

    而不是

    Given an address
    When I lookup a name
    Then the home owner name is displayed
    

    这没什么用 cukes.info 显示为命令式示例(而不是声明式)。

    Cucumber测试与Rspec、Test::Unit或MiniTest单元测试相比运行缓慢。它们有很多开销(加载环境(包括所有页面对象类、解析功能文件和实际执行测试)可能需要几分钟时间。运行Cucumber单元测试要比运行集成等价测试快,但不如运行更轻的测试(如上面提到的三个)快。

    (我正在回答这个老问题,因为这是我在寻找Cucumber的集成测试替代品时得到的第一个答案之一)