hubotコマンドのregexだけをテストしたいんだよね

hubotコマンドのregexだけをテストしたいんだよね

hubot でも E2E テストをしようぜって話をしてる人がいてすげーなって思ってたんですけど、hubot: pingって叩くと PONG って書いてくるとかなら(つまりは非破壊的な動作なら)、テストしやすいなーって思ってたんですけど、例えば deploy のコマンドの返事だけを regex でテストするってのはどうもイケてるとは思いませんでした。そこで、前回、hubot でも MVWhatever しようってことで、models とかに実際呼び出されるメソッドを切り出すって話をしたので、hubot のコマンド自体にテストをしたいなーって話です。

hubot コマンドの regex 正しく吸われているかどうかのテスト

まずは mocha と chai を入れときましょう(まぁ、jasmine でも ava でもなんでもいいです)。

npm install mocha chai --save-dev

それと、どっかにつなぎにいってもいやなので、mock-adapter も入れときましょう。

npm install hubot-mock-adapter

っでは実際に regex のテストを書いてみます。まずは本体から。

# scripts/deploy.coffee
# Description
#   Deploy
#
# Commands:
#   hubot: deploy to ENVIRONMENT:REVISION

# ダミーのコントローラー
Controller = require './controllers/deploy_controller'

module.exports = (robot) ->

  robot.respond /deploy\s+([\w._-]+)\s*:\s*([\w._-]+)\s*$/, (res) ->

    environment = res.match[1]
    revision = res.match[2]
    controller = new Controller environment, revision
    controller.execute()

んでこれをテストしたい。

# test/regex/deploy.coffee
{expect} = require 'chai'
{Robot} = require 'hubot'

describe 'deploy', ->
  environment = 'production'
  revision = 'v0.1.0'
  robot = new Robot null, 'mock-adapter', false, 'test-hubot'
  # regexのテストしかしない(状態遷移についてのテストがない)ので、afterやbeforeEachのようなフックは使用しない
  regex = require('../../scripts/deploy')(robot).listeners[0].regex

  # まずは環境名とリビジョンが正しく取れるかどうかのテスト
  context 'with input = "test-hubot: deploy production:v0.1.0"', ->

    it 'gets environment and revision', ->
      match = regex.exec "test-hubot: deploy #{environment}:#{revision}"
      expect match[1]
        .to.be.equal environment
      expect match[2]
        .to.be.equal revision

  # regexにマッチしないことを確認するテスト
  context 'with input = "test-hubot: deploy production:********"', ->

    it 'does not match', ->
      match = regex.exec "test-hubot: deploy #{environment}:********"
      expect match
        .to.be.equal null

みたいな。これできれいにコマンドの regex 部分を切り分けることができましたね。コマンドが長くなってくると TYPO も結構怖かったり、コマンド数が増えてくると予期せぬ match が発生(え、このコマンドこっちにも match しちゃうのかーみたいな)するので、regex をテストしておくってのはお手軽な割に以外に大事だなーって思ってます。

あとは npm test できるように package.json に

..snip..
  "scripts": {
    "test": "mocha --compilers coffee:coffee-script/register --recursive test/"
  }
..snip..

とかやっとけばいい感じだと思います。

octobot: タコ・ソ・ノモノ