【问题标题】:Pluses and minuses of using Factories in a Rails test suite?在 Rails 测试套件中使用工厂的优点和缺点?
【发布时间】:2009-04-20 13:12:56
【问题描述】:

我目前正在研究一个庞大的 Rails 测试套件。我无法详细说明,但整个套件(单元/功能/某些集成)的运行时间可以超过 5 分钟。

我们完全依赖于固定装置,并且我们没有像应有的那样嘲笑和存根。

我们接下来的几个冲刺将完全专注于测试套件,包括提高覆盖率、编写更好的测试以及最重要的是编写更高效的测试。

因此,除了在我们的测试中进行更多的嘲笑和存根之外,我们正在考虑用最有可能的 Factory Girl 替换我们的固定装置。我看到很多快乐的人在做类似的情况,但一直找不到关于搬到工厂的任何缺点的好资源。在使用来自各种资源的基准时,我看到了一些较慢的基准,但无法确定为什么工厂很好,这就是您可能不想使用它们的原因。

谁能告诉我为什么或为什么不应该使用工厂?

谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby testing refactoring factories


    【解决方案1】:

    Oleg 的回答很好,但让我提供一个同时使用两者的人的观点。

    Fixtures 在一段时间内一直是 Rails 社区的鞭挞男孩。每个人都了解固定装置的缺点,但没有人真正支持自己的优势。根据我的经验,工厂本身很容易变得和固定装置一样难以维护(这实际上取决于模式,但我离题了)。工厂的真正优势在于选择性地替代基于固定装置的疼痛。让我们谈谈几个细节。

    第一个问题是性能。如果您可以在不访问数据库的情况下测试您的大部分应用程序,那么您将看到显着的加速,但对于大多数应用程序,我认为在不完全访问数据库的情况下进行测试是不明智的。在某些时候,您想测试整个堆栈。每次模拟或存根时,您都在对可能包含细微错误的接口做出假设。因此,假设您需要在相当大比例的测试中访问数据库,事务夹具(您正在使用事务夹具对吗?)很可能比为每个测试实例化整个环境要快得多。

    我会说,您的测试套件的大小确实需要查看 Continuous Integration 以将您的开发扩展到一个新的水平。不管你把它们加速多少,开发者等待的时间仍然很长。也许也可以查看autotest 以在个人层面提供帮助。但最终 CI 将允许您在不牺牲开发人员敏捷性的情况下保持测试纪律。

    夹具真正发光的地方是功能/集成测试。我的看法是,fixture 应该为要测试的应用程序设置一个健康的基础状态。大多数单元测试并不真正需要这个。您可以使用工厂获得非常好的单位覆盖率。然而,当涉及到功能测试时,任何给定的页面都可能会遇到几十个模型。我不想在每个测试中设置所有这些东西。随着我构建越来越复杂的场景,我越来越接近重新创建一个全局数据状态,这正是灯具最初设计的目的。

    我持有的一个有争议的信念是,在其他条件相同的情况下,我更喜欢一个功能测试而不是 20 个单元测试(使用 Rails 的说法)。为什么?因为功能测试证明发送给用户的最终结果是正确的。单元测试非常适合了解功能的细微差别,但归根结底,您仍然可能在界面上遇到一个会破坏整个站点的错误。功能测试让我有信心在没有实际加载浏览器页面的情况下进行部署。我知道我可以把所有东西都存起来并测试两个接口并获得相同的覆盖率,但如果我可以在一个简单的测试中测试整个堆栈,但需要消耗一点 CPU,我宁愿这样做。

    那么我对固定装置的最佳做法是什么?

    • 为每个模型设置几个以涵盖最广泛的数据类别
    • 在添加跨越许多模型和控制器的主要新功能时,添加一些新的固定装置来代表主要状态
    • 除了添加/删除字段外,避免编辑旧夹具
    • 将工厂用于更小/更本地化的变化
    • 使用工厂来测试仅在少数测试中需要的分页或其他大规模创建

    另外,让我推荐Jay Fields' blog 以获得非常好的实用测试建议。我最喜欢 Jay 的博客的一点是,他总是承认测试是非常特定于项目的,适用于一个项目的不一定适用于另一个项目。他缺乏教条,但很注重实用主义。

    【讨论】:

      【解决方案2】:

      在设置实体之间的所有依赖项以获得良好的测试套件时可能会出现一些问题。无论如何,这仍然比维护很多灯具要容易得多。

      夹具:

      • 很难维持关系(尤其是多对多);
      • 测试套件运行时通常会因为更多的 DB 命中而变慢;
      • 测试对架构的变化非常敏感。

      工厂:

      • 您将在当前单元测试中未测试的所有内容存根;
      • 您准备与工厂一起测试的实体。这就是工厂展示其真正优势的地方——设置新的测试用例很容易,因为您不需要为此维护大量的 YAML 文件;
      • 你专注于测试。如果测试需要改变场景,你不要改变你的心态。只要存根合理且工厂易于定制,就应该没问题。

      因此,工厂似乎是一个不错的选择。我看到的唯一可能的缺点是:

      • 您从固定装置迁移所花费的时间;
      • 保持一组合理的场景可能需要一些努力。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-24
        • 2012-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-24
        • 2019-05-21
        • 1970-01-01
        相关资源
        最近更新 更多