如何testing一个Grunt任务? 理解和最佳实践

理解如何编写复杂的Gruntfile.js并在testing中使用它,我有点Gruntfile.js 。 我是否正确使用Grunt? 我想问社区的帮助,并以另一种方式作出贡献。

我正在为Grunt写一个新的任务 ,并希望在Github和npm上为广泛的读者推出它。 我想为这个任务进行自动化testing(我想学习如何正确执行)。

我想testing不同的选项组合(现在大约15个)。 所以,我应该多次:

  • 运行清理
  • 运行我的任务设置下一个选项
  • 运行testing并将选项对象传递给testing

一些非工作代码,以便更好地理解:

Gruntfile:

 grunt.initConfig({ test_my_task: { testBasic: { options: { //first set } }, testIgnore: { options: { //another set } }, //... } clean: { tests: ['tmp'] // mmm... clean test directory }, // mmm... unit tests. nodeunit: { tests: ['test/*.js'] //tests code is in 'tests/' dir } }); grunt.registerTask('test', ['test_my_task']); 

当知道options对象时,我知道如何检查tmp/文件夹是否处于所需的状态。

问题在于把事情放在一起。

我会问只是模板代码作为答案,npo需要把工作的例子。

PS:你可以提出另一个testing工具,nodeunit不是必须的。

PPS:废话,我现在可以写在这个纯JavaScript了! 也许我做错了,我想把Grunt放入unit testing? 但我想testing我的任务如何在Grunt中传递的不同选项在真实环境中工作…

你可能想看看grunt-lintspacesconfiguration。 testing看起来像这样 ,这似乎是一个很好的方法来做到这一点。 grunt-lintspaces使用nodeunit,但是现在看起来很多插件。

如果你不想testing实际的咕噜声输出,而不是testingfunction,你可以使用grunt-mocha-test – https://github.com/pghalliday/grunt-mocha-test ,我正在使用grunt-available-taskstesting 。 我更喜欢个人testing的描述风格,它读得很好; 使用这个的好处是你实际上testing了你的插件,而不用在你的Gruntfile中包含大量的configuration; 即testing代码应该在testing中。

Grunt已经过很好的testing,所以testing它的configuration是否合适是没有意义的。 只要testing你自己的插件的function。

你想要做的是添加一些黑盒 /集成/端到端,和/或“烟雾”testing 。 对插件进行这样的testing+unit testing是非常好的(独立于咕噜声,正如其他响应所暗示的那样)。

除了unit testing之外,您通常如何检查应用程序是否在顶层作用? 通常通过读取控制台输出,通过检查文件系统(检查文件是否被创build),通常通过捕获与外界的交互。 例如,nodeunit生成xml文件,如果你在代码中破坏某些东西, grunt nodeunit的状态退出应该是非零的,如果testing通过,状态应该是0。

在这种types的testing中,你并不是真的想知道你的应用程序是如何在最低级别工作的(比如在unit testing中),但是如果某个级别的任何事情发生中断,你不想错过它,希望看到的细节,让您(至less)手动重现失败。

提示:编写更多的unit testing肯定不是一个好主意(比如在javascript中打包bash调用,并执行I / O操作)

就我而言,除了普通的unit testing,我发现最近的烟雾testing策略+ bash是一个非常有用的东西。

用一个简单的帮助文件,可以创build一个“testing框架”:)(在我的真实版本中,它添加了ANSI颜色,缩进等,但在这里并不重要)。

 # tests-utils.sh test_case() { # we need some description description="$1" # we need an actual step, a command that you would invoke # from the shell to test the plugin command_to_execute="${2}" # we also need to see some progress and some basic info echo -e "[test case] $description]" echo "${command_to_execute}" # it shouldn't crash immediately, because we want to record # and print the output, etc. set +e # we don't want to see the output of the command, unless it fails ${command_to_execute[@]} > log 2>&1 rc=$? if [ $rc -ne 0 ]; then cat log echo -e "Error, command exit code: $rc" exit $rc fi # almost RAII ;) set -e } 

然后,写一些烟雾testing:

 #!/usr/bin/env bash # include the utils source ./tests-utils.sh # stop if any of steps fails set -e # This basic tests protect against malformed package.json, # missing packages (if you install something manually, # and forget to save it in the package.json, it works, unless # you have a fresh install), bad file expressions in a Gruntfile, # and many more... rm -rf node_modules test_case "npm install must work" "npm install" rm -rf *.js.xml test_case "must provide tests that are passing" "grunt test" test_case "tests must produce xml results" "[ -f someUnitTest.js.xml ]" rm -f coverage.json test_case "must provide coverage" "grunt coverage" test_case "coverage must produce json results" "[ -f coverage.json ]" # and so on... 

有时创build一个引用项目并不是一个坏主意:一个项目是你的插件的一个人造的用户。 我可以包含简单的package.json(它有一个链接到你的插件),Gruntfile.js,一些“foo”实现,“foo unittests”等,然后你可以在烟雾testing中使用该项目。