复制Node.js`assert`断言spec`expect`

与使用自定义的开发人员友好检查的非断言代码相反,

class Some { constructor(arg) { if (Array.isArray(arg) && arg[0] === 'foo') this.foobar = arg.concat('bar').join(''); else console.error('Bad Some constructor arg'); } } 

目前testing的代码与Node assert断言具有合理有意义的message参数:

 class Some { constructor(arg) { assert.deepEqual(arg, ['foo'], 'Some constructor arg'); this.foobar = arg.concat('bar').join(''); } } 

这个说法是有的

  • 保持代码平坦和可读
  • 对调用堆栈的不正确使用提供有意义的反馈
  • 防止函数执行,不会进一步传播错误
  • 抛出错误并将error handling留给调用者

目前的规格可能如下所示:

 it('...', () => { let some = new Some(['foo']); expect(some).to... 

它会通过 – 在规范中声称有令人满意的用法,它在testing代码中声称有不良的用法。

重叠代码断言的一部分可能是偶数

 it('...', () => { const { AssertionError } = require('assert'); let some = new Some(['foo']); expect(some).to... expect(() => new Some(['bar']).to.throw(AssertionError); 

所以我们在这里基本假设testing工作的一半已经在代码本身完成了,并且assert并跳过细节( to.not.throw和匹配的AssertionError消息)。

上面的例子使用了Mocha + Chai,但同样的事情适用于Jasmine。

  • 如果应用程序断言被视为任何其他代码行,并加上规范断言( 抛出而不是抛出AssertionError消息匹配),采取快捷方式的后果是什么?

  • 除了expecttesting覆盖工具(伊斯坦布尔)是否可以考虑assert应用程序代码中的断言?

  • 可能testing跑步者被这个事实弄糊涂了,而不是规范声明抛出一个错误?

在实践中certificate或驳斥“断言断言”点的成功的开源JS项目的一些例子也是有帮助的。

如果应用程序断言被视为任何其他代码行,并加上规范断言(抛出,而不是抛出,AssertionError消息匹配),采取快捷方式的后果是什么?

我不会推荐的。 这就像testing一个testing:虽然技术上是可能的,但通常你不这样做,因为这是不值得的成本。

除了期望,testing覆盖工具(伊斯坦布尔)是否可以考虑断言应用程序代码中的断言?

你想要得到什么样的行为? 通过unit testing,这个testing非常清晰:运行testing并监视访问哪个代码。 但是,如何处理assert(在代码中)呢? 如果assert语句是通过一些unit testing达成的,那么代码显然是被testing覆盖的。 如果不是,那么围绕assert语句的一些代码应该被testing覆盖吗? 您要计算多less代码? 这一切都变得非常讨厌,我不相信有一些适当的解决scheme存在。

此外,整个testing覆盖率至less是很臭的 – 事实上,存在一些代码的testing告诉你它的正确性太less了!

可能testing跑步者被这个事实弄糊涂了,而不是规范声明抛出一个错误?

这是(IMO正确)由威廉回答的。 还是有什么缺失? 🙂

如果应用程序断言被视为任何其他代码行,并加上规范断言(抛出,而不是抛出,AssertionError消息匹配),采取快捷方式的后果是什么?

应用程序声明是通知开发人员不正确使用某段代码,理想情况下它们不会发生在生产中。 如果确实发生了,那么它们就像一个标准的错误所做的那样,作为一个工具来识别出什么地方出了问题。 但理想情况下,它们是发展过程中的第一道防线,只有这样才能发生。 (因此这就是为什么在某些语言中你可以一起禁用运行时断言的原因之一)

如果你编写了一些使用断言的类来确保input参数是有效的,或者程序没有被不一致的使用,那么把这个逻辑放在unit testing下也是很有意义的。 如果你想在某个时候改变断言,你想要testing一下你不会破坏别人的代码。

除了期望,testing覆盖工具(伊斯坦布尔)是否可以考虑断言应用程序代码中的断言?

是。 如果你设置了一个触发断言的unit testing,然后在chai中捕获它,那么这个代码path将显示在你的覆盖报告中。 这是没有任何其他的代码path,除非我不理解你的问题。

可能testing跑步者被这个事实弄糊涂了,而不是规范声明抛出一个错误?

当你使用assert模块编写断言时,会抛出一个AssertionError 。 这是assert模块的AssertionError类。 当chai抛出一个错误时,它也会抛出一个AssertionError ,但是这将是一个来自chai模块的完全不同的类,它们只是共享这个名字。 就这一点而言,对于来自何处的断言不应该有任何混淆。
通常你不会在testing代码中通过try / catch结构捕获断言,所以这真的不应该是一个问题。

通常,断言testing的复杂性要低得多,然后进行unit testing。 但是,断言结束和unit testing应该开始的地方确实没有正式的定义。 更多阅读:

https://softwareengineering.stackexchange.com/questions/18288/are-asserts-or-unit-tests-more-important

我通常推荐两种我相信涵盖的方法:

  1. 在unit testing中做testing(我知道它和运行时断言不一样,但是你可以testing你的健壮性在unit testing中起作用)

  2. 结构化代码,使退出条件首先发生并return 。 然后,您可以在其中编写validation后validation代码的平面(缩进)空间。 如果你喜欢,你可以编写自己的logging器/处理程序或“调用者中间件”来中断致命错误的执行。