我目前正在研究一个庞大的 Rails 测试套件。我无法透露具体细节,但整个套件(单元/功能/某些集成)的运行时间可以长达 5 分钟。

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

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

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

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

谢谢!

有帮助吗?

解决方案

为了获得良好的测试套件而设置实体之间的所有依赖关系可能会出现一些问题。无论如何,这仍然比维护大量的固定装置容易得多。

赛程:

  • 难以维持关系(尤其是多对多);
  • 由于更多的数据库命中,测试套件运行时间通常会更慢;
  • 测试对模式的变化非常敏感。

工厂:

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

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

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

其他提示

奥列格的回答很好,但让我提供一下同时使用这两种方法的人的观点。

一段时间以来,Fixtures 一直是 Rails 社区的替罪羊。每个人都了解固定装置的缺点,但没有人真正拥护其优点。根据我的经验,工厂本身很容易变得像固定装置一样难以维护(这实际上取决于模式,但我离题了)。工厂的真正优势在于选择性地更换基于固定装置的痛苦。让我们来谈谈一些细节。

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

我想说,根据您真正需要关注的测试套件的大小 持续集成 将您的发展提升到一个新的水平。无论你加快多少速度,开发人员仍然需要等待很长时间。也许看看 自动测试 以及在个人层面上提供帮助。但最终 CI 将允许您在不牺牲开发人员敏捷性的情况下维持测试纪律。

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

我持有的一个有争议的信念是,在其他条件相同的情况下,我更喜欢 1 次功能测试而不是 20 次单元测试(使用 Rails 的说法)。为什么?因为功能测试证明发送给用户的最终结果是正确的。单元测试非常适合了解功能的细微差别,但最终,您仍然可能在界面上出现错误,从而破坏整个网站。功能测试让我有信心进行部署,而无需在浏览器中实际加载页面。我知道我可以将所有内容存根并测试两个接口并获得相同的覆盖范围,但如果我可以在一个简单的测试中测试整个堆栈,而牺牲一点 CPU,我更愿意这样做。

那么我对于固定装置的最佳实践是什么?

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

另外,给大家推荐一下 杰·菲尔兹的博客 以获得真正好的实用测试建议。我最喜欢 Jay 博客的一点是,他总是承认测试是非常针对特定项目的,对一个项目有效的方法不一定适用于另一个项目。他缺乏教条而注重实用主义。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top