Node.js 断言库与其他断言库

Node.js assert library vs. other assert libraries

根据node.js断言库documentation:

The module is intended for internal use by Node.js, but can be used in application code via require('assert'). However, assert is not a testing framework, and is not intended to be used as a general purpose assertion library.

我一直在寻找 Chai 作为替代断言库(没有 BDD API,只有断言 API),最后我发现断言功能非常好相似。

为什么 Chai 的断言库是更好的断言库?它做的一切都比 node.js 做的(除了在可用断言方面更丰富,但这只是语法糖衣)。即使是简单的事情,例如执行断言的总数,也无法在两者上获得。

我是不是漏掉了什么?

我想既然没有人给我任何好的反馈,我会在使用 node.js assert 和 chai 的 assert 一段时间后尝试提供一些关于我原来问题的信息。

最后的答案是在功能方面它们是相同的。 chai 的断言存在的唯一原因是,如果您阅读代码,您可以更好地理解测试,但仅此而已。

例如,使用 Node.js:

测试空值

assert(foo === null);

并使用 chai:

assert.isNull(foo);

它们完全等价,并且坚持 node.js 断言会限制您的依赖列表。

更新(2017 年 4 月):Node.js 不再警告人们不要使用 assert 所以下面的答案现在已经过时了。不过,为了历史利益而保留它。

这里是the answer I posted to a very similar question on the Node.js issue tracker

https://github.com/nodejs/node/issues/4532 和其他问题暗示了文档建议不要使用 assert 进行单元测试的原因:存在边缘情况错误(或者至少肯定是意外)和缺失的功能。

多一点上下文:知道我们现在所知道的,如果我们再次成为 designing/building Node.js 核心,assert 模块将不存在于 Node.js 或者由更少的函数组成——很可能只是 assert()(目前是 assert.ok() 的别名)。

至少从我的角度来看,这样做的原因是:

  • assert 中完成的所有事情都可以在 userland
  • 中轻松完成
  • 核心工作最好花在其他地方,而不是完善可以在用户空间完成的单元测试模块

其他人可能会选择在此处添加或不添加其他上下文(例如,为什么在所有条件都相同的情况下,我们倾向于保持核心较小并在用户空间中做事)。但这就是所谓的三万英尺的景色。

由于 assert 已经在 Node.js 中存在了很长时间,并且很多生态系统都依赖于它,所以我们不太可能(至少目前我能说的是最好的)永远删除 assert.throws() 和朋友。它会破坏太多东西。但是我们可以阻止人们使用 assert,并鼓励他们使用用户空间模块,这些模块由深切关心他们的人维护,他们积极修复边缘案例错误,并在有意义时添加很酷的新功能。这就是全部内容。

是的,如果您对简单案例进行直接断言,assert 可能会满足您的需求。但是如果你长大了 assert,你会更好地使用 chai 或其他什么。所以我们鼓励人们从那里开始。这对他们(通常)更好,对我们(通常)更好。

我希望这对您有所帮助并能回答您的问题。

免责声明:我是 assertthat 模块的作者,我将在本回答中引用该模块。

基本上,您可以使用 Node 自己的 assert 模块实现所有其他模块可以实现的功能,例如 Should.jsexpect.jsassertthat。它们的主要区别在于表达意图的方式。

从语义上讲,下面几行代码都是等价的:

assert.areEqual(foo, bar);
foo.should.be.equal(bar);
expect(foo).to.be(bar);
assert.that(foo).is.EqualTo(bar);

在语法上,有两个主要区别:

首先,should 语法仅在 foo 不等于 nullundefined 时有效,因此它不如其他语法。其次,可读性有所不同:assert.that(...) 读起来像自然语言,而其他的则不然。

毕竟,Chai 只是一些断言模块的包装器,可以让您的工作变得更轻松。

所以,长话短说:不,没有技术上的原因为什么偏爱一个而不是另一个,但可读性和null兼容性可能是原因。

希望对您有所帮助:-)

PS:当然,在内部,它们的实现可能不同,所以可能会有一些细微的事情,例如如何检查相等性。正如免责声明中所说,我是 assertthat 的作者,所以我可能有偏见,但在过去的几年里,我不时遇到 assertthat 比其他的更可靠的情况,但正如所说,我可能是有偏见。

因为没有人提到它,我想我会提到摇滚明星程序员 Guillermo Rauch's article(link 是为了 Web Archive 备份)关于为什么你应该避免使用 expect 风格的框架而选择更简单的 assert 风格测试。

请注意,他是expect.js的作者,所以他曾经有过不同的想法。我也是。

他提出了一个详尽的论点,但基本上是为了减轻 API 超负荷的精神负担。我 永远不会 记得我写的是 should 和 expect 的哪种方言。是 .includes(foo).to.be.true() 还是 .includes(foo).to.be.true 还是 ...

TJ Holowaychuck 编写了一个名为 better-assert 的断言库以获得更好的输出 which you might check out