Hubotの追加機能作成をテストで楽にする

Hubotで追加機能を作るときに一番大変なのは、やはりテストの部分だと思います。
普通に頑張ると、起動してbotにメッセージ送って、動かなければ止めて修正…といった、
面倒な手順を踏むことになります。
また、普通に起動するとエラーも吐いてくれないため、デバッグは非常に困難です。

しかし、テストを書いて開発をする場合、メッセージ送信やメッセージのデータ取得など、
Hubotに依存する部分をstubで置き換えるのはとても面倒な作業です。

そこで、作りたい機能をパッケージ化して作成することで、
トライアンドエラーをする部分を最低限に絞って開発することができました。

Hubot用パッケージの構成

Hubotはpackage.jsonのmainに指定したファイルをロードしてくれるため、
ここにhubot用のスクリプトを書くことで、Hubotスクリプトをnpmパッケージで管理できます。

さらに、以下のようにhubotスクリプトから、処理をまとめたオブジェクトの特定のメソッドを呼び出すことで、
Hubotの連携部分と実際の処理を分けることができます。

PackageClass = require('./package-name/package-class.coffee').PackageClass
module.exports = (robot) ->
  package_class = new PackageClass
  robot.respond /test call (\d+)( \w+)?/, (msg) ->
    arg1 = parseInt msg.match[1]
    arg2 = msg.match[2]

    msg.reply package_class.testCall(arg1, arg2)

フォルダ構成は以下のようになります。

parkage-root/
 ├ package.json
 │
 ├ src/
 │  ├ hubot-command.coffee
 │  └ package-name/
 │     └ package-class.coffee
 │
 └ test/
    ├ test-helper.coffee
    └ test-package-class.coffee

このように構成し、package-classに対してテストを作成することで、
Hubot固有の部分を最小限に減らし、通常のnpmパッケージのように開発できました。

前述の通り、hubotとやりとりをするhubot-commandに対してテストをするのは手間がかかります。
ですが、やっていることは正規表現の結果をクラスのメソッドに渡すだけなので、
手作業でやってしまう方が簡単で早いです。

参考

hubot-scfesはこの方針に則って作ったため、参考になるかもしれません。
https://github.com/ota42y/hubot-scfes