是否有办法在测试失败时触发npm的posttest ?如果包中。json包含
"scripts": {
"pretest": "echo pretest",
"test": "some_failed_test_or_error",
"posttest": "echo posttest"
}
$ npm test
将回显"pretest"而不回显"posttest"。
如果我使用mocha并且测试失败,即使mocha没有触发任何异常(只是一些简单的失败assert(true==false)
),我也会得到相同的行为。
我在pretest上启动一个资源,我想在posttest上杀死这个资源,无论测试本身通过还是失败
MacOS OS X 10.9.4, npm版本1.4.21,节点v0.10.30.
算出来了。不确定以下内容是否适用于Windows。bash ||
操作符后跟空注释:
,更改退出代码
例如,使用mocha:
"scripts": {
"pretest": "echo pretest",
"test": "mocha || :",
"posttest": "echo posttest"
}
这个问题的另一个答案简洁而简短,但有点不正统。我知道,如果我使用它,每次我回来看到"||:"时,一个大大的问号就会在我头上形成。它是如此简洁,你甚至可能会错过它。它需要文档在某个地方。
我花了一点时间寻找一个更正统的解决方案,在这里找到了:https://github.com/npm/npm/issues/5493
你需要npm-run-all
"test": "npm-run-all the-actual-test run-after-test-even-if-failed --continue-on-error"
但是你不能使用"pretest"或"posttest"作为pre和post脚本的名称,因为它们会运行两次。
我认为这里有一个更好的解决方案:我在项目的根目录中添加了一个非常简单的bash脚本nofail.sh
,它只是以下内容:
"$@" || true
然后,我在npm test
命令的开头添加了./nofail.sh
,像这样:
"scripts": {
"pretest": "echo pretest",
"test": "./nofail.sh mocha",
"posttest": "echo posttest"
}
如果您不喜欢添加bash脚本,或者需要一些跨平台的东西,suppress-exit-code
是一个似乎符合要求的节点包,只需安装它并使用suppress-exit-code
而不是./nofail.sh
。
但是为什么呢?
首先,我认为它更清楚地说明了正在发生的事情——我们忽略了测试命令中的失败代码。但更重要的是,这允许您像往常一样将参数传递给test命令,这样它仍然可以工作:
npm test -- test/to/run.js
其他两个解决方案都打破了这种情况:在|| :
中,参数被传递给:
命令†,在那里它们什么都不做,而在all-in-one中,它们被传递给npm-run-all
。
这在我们的项目中特别麻烦,因为我们的基本测试脚本有几个配置参数,然后我们有几个"套件";定义为单独的脚本,指定一组给定的测试文件作为参数。因为我们不能运行npm test -- --spec "tests/some-suite/*.spec.js"
,我们必须在每个套件中重复基本测试运行器的配置和设置,除了在每个脚本的末尾出现奇怪的|| :
之外,这使得事情变得更加冗长和混乱。
使用此解决方案,可以在npm test
中给出一次基本测试配置,然后由所有套件使用,并且一切都更清晰,更易于维护。
但如何?
$@
是一个特殊的变量,它被设置为传递给脚本的任何参数。如果npm脚本是真正的bash脚本,我们可以简单地运行mocha "$@" || true
并完成它,但它们不是,所以它们没有访问该变量的权限。
--
传递的任何参数。然后,它将这些参数作为命令运行,并忽略结果,这正是我们想要的。引用$@
可以确保正确处理任何引用的参数。
†虽然有时使用类似,但:
实际上并不是一个"注释"。在任何有意义的意义上,它都是一个像其他命令一样的内置命令,并且在Bash的手册中有这样的文档:
(参数):
没有影响;该命令除了展开参数和执行任何指定的重定向之外,什么也不做。返回零退出码。
这些天:
只是一个令人困惑的保留,从早期的true
没有广泛使用。我建议这些天使用true
,它实现了相同的功能,并使其更清楚正在发生的事情。