为什么 Mocha 测试用例应该是无状态的?

2024-04-26

这是一个常见的建议,即Mocha 测试用例不应共享状态。鉴于 Mochas 测试用例执行的强烈顺序性,我真的不理解这个建议。还有更多——我认为这很可疑。

如果测试用例(即使是异步测试用例)严格地一个接一个地执行,则不存在时间竞争问题或其他不可预测的执行顺序的风险。

让我们看一下这个 Mocha 结构:

describe
   describe
     it1
     it2    // async
     it3
   describe
     it4
     it5
describe
   describe
     it6    // async
     it7    // async
     it8
   describe
     it9
     it10

测试用例将始终以清晰的顺序执行,it1,it2,... it10,独立于它们是同步还是异步,甚至独立于描述的层次结构。以下结构将产生完全相同的输出:

describe
   it1
   it2    // async
   it3
   it4
   it5
   it6    // async
   it7    // async
   it8
   it9
   it10

在单个describe()中的测试用例之间共享数据可以使测试用例之间的通信变得更加容易和舒适,以便:

  • 重用测试代码并避免在每个(或 其中一些)测试用例。钩子在这里很方便,但有时却很方便 预期的控制比他们提供的更多
  • 减少测试执行时间 - 可以节省大量时间,避免太多除了满足有关无状态性的建议之外什么也不做的钩子。

支持在测试用例之间使用共享数据的另一个事实是 Mocha 代码的这种简单而漂亮的结构。不同级别的describe()允许对最终共享数据进行简单、清晰的范围管理。

我看到的唯一负面影响是,当“全局变量”被“滥用”时,代码会变得更难理解、遵循和维护。无论如何,通过严格的编码,没有什么是无法避免的。

这里有什么我不知道的吗?


It is possible使用 Mocha 运行非无状态且相互依赖的测试。这不是摩卡的样子designed为了。归根结底,如果您想在测试之间强加依赖关系,当然可以。但它也有一些警告。

针对错误的事情进行优化

您引用了在测试之间共享状态的优势:

减少测试执行时间

Sure. 在其他条件相同的情况下,我们宁愿有一个运行时间更少的测试套件。在大型测试套件上,不重置测试之间的状态可能会节省大量时间运行整个套件时。然而,事实是“其他一切”并不相同:

  • 运行整个套件应该通过一个自动化流程来完成,该流程报告哪些内容通过了,哪些内容失败了。换句话说,不应该有人坐在那里waiting使整个套件得以完成。

  • 当出现故障或正在实施新测试时,开发人员将只想运行失败的测试或新测试,而不是整个套件。如果套件的设计使得测试 1 到 N-1 必须在测试 N 运行之前运行,那么开发人员等待获得他真正关心的测试结果的时间就会更长。所以他可以坐在那里以 X 美元/分钟的速度摆弄他的拇指。 “多任务”并不是答案,因为事实证明,切换任务会产生认知成本。 (“好的,测试完成了……等等,问题又出在哪里?”)

测试选择

您可以使用--grep选择特定的测试。这是非常有用在大型测试套件上,以避免浪费时间来运行您不关心的测试。因此,我们假设您的测试标题是it1, ... it10你用--grep it7。由于 Mocha 将所有测试相互独立,因此它只会运行任何测试before and beforeEach钩子适用于it7并运行测试(然后运行任何after and afterEach钩子适用于它)。它不会运行it1 to it6跑步前it7。为了让它运行这些测试,你必须制作一个--grep涵盖所有必要的测试,这当然总是possible做但不愉快。

在浏览器中运行 Mocha 时获得的 HTML 界面中,如果您希望 Mocha 只运行某个测试,则可以单击该测试。同样,如果您想要修复单个失败的测试,这将非常有用。如果失败的测试依赖于在其之前运行的一堆测试,则根本没有与此简单单击等效的操作。

测试订单

一般来说,如果您的测试必须按特定顺序运行,则必须小心确保拆分在多个文件中的测试将按测试运行所需的顺序加载。

例如,它将是possible使用全局结构在不同文件中存储的测试之间共享状态。但是,当测试位于不同的文件中时(其中一个文件不not require另一个),Mocha 处理文件的顺序完全取决于读取包含文件的目录时文件系统列出文件的顺序。有一个--sort适合那些想要基于字典排序的可预测顺序的人的选项。如果你想强加你自己的任意顺序,那么我想你必须命名你的文件01foo.js, 02bar.js, etc.

无论是使用 Node.js 运行 Mocha 还是在浏览器中运行 Mocha,都是如此。我有一些套件,其中测试文件是用 RequireJS 加载的。请求模块 A、B、C 不能保证它们会按照 A、B、C 的顺序加载,除非声明 C 依赖于 B(也可能是 A)并且 B 依赖于 A。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Mocha 测试用例应该是无状态的? 的相关文章

随机推荐

  • 我可以为我的 r 闪亮界面使用 index.html 和 ui.r 吗?

    在参照this http shiny rstudio com articles html ui html关于如何完全用 HTML 构建闪亮的应用程序 我想知道是否有任何方法可以将这种方法与传统的 ui r 方法结合使用 Reason Thi
  • Akavache 的 GetObject 在等待时挂起。知道这里出了什么问题吗?

    我有一个 Xamarin Forms 应用程序 在我的 App 类中包含以下代码 是的 这只是演示该问题的示例 public App BlobCache ApplicationName MyApp BlobCache EnsureIniti
  • Laravel 验证 - 输入必须是数组中的项目之一

    Laravel 5 中是否有内置验证器来检查值是否在我的白名单值数组中 例如 rules field name gt required in array yes no maybe There s in http laravel com do
  • 如何在测试执行之前强制使用 Spring 上下文的新版本

    我用SpringJUnit4ClassRunner用于编写集成测试 我也用 DirtiesContext对于将上下文置于损坏状态的测试 并且效果很好 但现在我有一个测试 在静态初始化器中设置一个重要的 SystemProperty 该初始化
  • 如何从电子邮件地址检索姓名

    使用javascript 我们如何从字符串中删除 gmail com或 aol com 以便只留下名称 var string email protected cdn cgi l email protection 只会是 johdoe 吗 我
  • 如何在Android Studio 1.0.0中更改logcat字体大小? [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 如何在Android Studio 1 0 0中更改logcat字体大小 我只找到了在 Android Studio 中
  • Lambda 演算和教会数字混淆

    我正在尝试了解 lambda 演算和丘奇数字的基础知识 我已经进行了大量的阅读和练习 但我似乎一直试图了解某些函数是如何工作的 我坚持的例子如下 也许有人可以解释我哪里出了问题 1 的丘奇数可以表示为 f x f x The exponen
  • 如何将 Python 中的 MS Botframework 部署到 Azure

    我一直在玩 Botframework 并尝试从 git 上传示例代码https github com Microsoft botbuilder python tree master samples EchoBot with State ht
  • 在 Mobile Safari 中重用 HTML5 音频对象

    我希望在 iPad 上的 Mobile Safari 中运行的 Web 应用程序上播放一个简短 小于 1 秒 的音频文件 以响应用户输入 同时将事件和音频播放之间的延迟降至最低 在页面重新加载之间可以多次触发播放 因此我想缓存音频文件 以下
  • Django allauth Facebook 本地开发

    我在用着Django allauth https github com pennersr django allauth对于正在开发的网站的 Facebook 身份验证 并进行了相应的设置 在 facebook 的 facebook 应用程序
  • 在 PyGTK 中,显示 PNG 文件的简单方法是什么?

    以下 PyGTK 代码在窗口中显示 PNG 文件 是否有更简单或更好的方式来显示 PNG 文件 例如使用 gtk DrawingArea 例如 如何调整文件大小 import gtk import pygtk pygtk require 2
  • 使用 datashader、holoviews 和 bokeh 进行地理映射时出现问题

    我正在尝试使用全息视图 数据着色器和散景将谷歌手机历史记录位置映射到地图上 大部分与 datashader 网站中给出的示例非常相似 但是当我这样做时 地图叠加不起作用 因为纬度 经度被破坏了 import datashader as ds
  • igraph (R) 中仅在根和终端顶点上添加标签?

    inst2 c 2 3 4 5 6 motherinst2 c 7 8 2 10 11 km c 20 30 40 25 60 df2 data frame inst2 motherinst2 df2 cbind df2 km g2 gra
  • 带有任意 AND 子句的动态 spring data jpa 存储库查询

    我在用着Spring data jpa repositories 需要提供不同字段的搜索功能 搜索前输入字段是可选的 我有 5 个字段EmployeeNumber Name Married Profession and DateOfBirt
  • java中如何销毁进程

    我写了下面的代码 要从 Java 应用程序运行 bat 文件 我使用 process exec 但蝙蝠有时可能会挂起 所以我需要为此过程设置一个超时 我启动一个新线程并在线程中新建一个进程 我在线程中设置超时 并在超时时杀死线程 但我发现超
  • 在 React 组件中使用绝对路径

    如何使用根目录中的绝对路径并更改根目录来导入组件 import Modal from project app src Components Modal import Main from Constants 我想要将根目录更改为我可以从 sr
  • 如何通过更新和多重选择将多个输入构建到我闪亮的应用程序中?

    我正在构建一个flex dashboard shiny应用程序与datatable并尝试建立两个输入作为此选择datatable每个选项都有一个 全部 选项 第一个问题是如何限制第二个选择 user 通过选择第一选择 team 然后 使用这
  • Javascript 生成器:理解它们

    我很确定我对生成器的理解本质上是被破坏的 所有在线资源似乎都是冲突的 这导致了极其困难和令人困惑的学习体验 据我了解 yield关键字使当前正在执行的代码块能够等待一个值而不是抛出要在回调内执行的剩余代码 因此 正如大多数教程所指出的 您可
  • URI/URL 和 String 有什么区别?

    这是出于好奇 不需要代码 我尝试使用世界上最好的搜索引擎来获取答案 但没有发现任何有价值的东西 有什么区别URI URL以及表示该 URI URL 的字符串 为什么我们必须解析它 将字符串解析成什么URI URL对字符串进行不同的处理 为什
  • 为什么 Mocha 测试用例应该是无状态的?

    这是一个常见的建议 即Mocha 测试用例不应共享状态 鉴于 Mochas 测试用例执行的强烈顺序性 我真的不理解这个建议 还有更多 我认为这很可疑 如果测试用例 即使是异步测试用例 严格地一个接一个地执行 则不存在时间竞争问题或其他不可预