2013-12-12 45 views
8

我對理解如何編寫複雜的Gruntfile.js並在測試中使用它有點困惑。我是否正確使用Grunt?我想問社區尋求幫助,並以其他方式作出貢獻。如何測試Grunt任務?理解和最佳實踐

我正在爲Grunt編寫一個新任務,並希望在Github和npm上爲廣泛的受衆推出它。我想爲此任務進行自動化測試(並且我想學習如何正確執行它!)。

我想測試不同的選項組合(現在大約15個)。所以,我多次:

  • 運行清理
  • 運行我的下一個選項設置任務
  • 運行測試和傳球選擇對象來測試

一些非工作的代碼以便更好地理解:

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']); 

我知道如何檢查tmp/文件夾是否在給定options對象時處於所需狀態。

問題是把事情放在一起。

我會問只是模板代碼作爲答案,npo需要把工作的例子。

PS:你可以提出另一種測試工具,nodeunit不是必須的。

PPS:廢話,我現在可以用普通的javascript寫這個了!也許我做錯了,我想把Grunt放入單元測試中?但我想測試我的任務如何在實際環境中使用Grunt傳遞的不同選項...

回答

9

您可能想看看grunt-lintspaces配置。測試look like this,這似乎是一個很好的方法來做到這一點。 grunt-lintspaces使用nodeunit,但似乎有很多插件。

如果你不想測試實際的咕嚕聲輸出,而不是功能,你可以使用grunt-mocha-test-https://github.com/pghalliday/grunt-mocha-test,我正在使用它來爲the grunt-available-tasks tests。我更喜歡個人測試的描述風格,它讀得很好;使用它的好處是你實際上測試了你的插件的功能,而不需要在Gruntfile中包含大量的配置;即測試代碼應該在測試中。

Grunt已經過很好的測試,因此測試它的配置是否合適是沒有意義的。只需測試你自己的插件的功能。

+0

我發現了Grunt API作爲resque !!!在JavaScript中,我編程構造任何配置排列或初始狀態,然後將它們傳遞給grunt來完成這項工作。結果很簡單:從javascript調用grunt任務(例如nodeunit),然後檢查工作結果。 – Dan

1

您想要做的是添加一些black-box /集成/端到端,和/或"smoke" tests。對插件進行這樣的測試+單元測試(獨立於咕嚕聲,正如其他響應所暗示的),這是一個非常好的主意。

除了單元測試,您通常如何檢查應用程序是否在頂層作爲整體工作?通常通過讀取控制檯輸出,通過檢查文件系統(檢查文件是否被創建),通常通過捕獲與外部世界的交互。例如,nodeunit會生成xml文件,並且如果您在代碼中損壞某些內容,則grunt nodeunit的狀態退出應爲非零值,如果測試通過,則狀態應爲0.

在此類型的測試中,您真的不想知道您的應用程序是如何工作的最低水平(如在單元測試),但如果東西打破在任何級別的,你不想錯過它,大概然後你希望看到允許您(至少)手動重現失敗的細節。

提示:這是肯定不是一個好主意寫更多的單元測試(在JavaScript像包裝的bash調用和執行I/O操作)

在我除了普通的單元測試外,我發現最近的煙霧測試策略+ bash是一件非常有用的事情。

有了一個簡單的輔助文件,可以創建一個「測試框架」 :)(在我的現實版本,它增加了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 
} 

然後,寫一些煙霧測試:

#!/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... 

這不是一個壞主意,有時會造成一個參考項目:一個項目,是你的插件的人工用戶。我可以包含簡單的package.json(它有一個鏈接到你的插件),Gruntfile.js,一些「foo」實現,「foo unittests」等。然後你可以在煙霧測試中使用該項目。