0

テストがあるとプルリクしやすい

印象としてそんな感じがする。

だいたいプルリクする時って、バグを見つけて直すのはすぐできるんだけど、自分の修正が何か別のところで副作用を起こしているかもしれない、という不安があってグダグダ色々検証したり他の部分のコードも一応読んだりする時間の方が長いと思う。
そういう時にとりあえずテスト通っていれば、テスト書いたリポジトリ主がokしているような気になってくるから、すぐプルリク出せる。

なるべくrake testとかnpm testとかコマンド一発実行すればテストが走るようにしておいてくれるとプルリクしやすくてうれしい。

プルリク受け入れる側も、Travis CIとかでプルリク自体にテスト通過しましたバッジがついていると安心感がある。


テストの書き方色々ある

去年からnode.js使い始めて、色々作ってるんだけどテストの書き方色々ある気がするのでメモしておく。
具体的な書き方は各リポジトリの中見ればわかる。


テストが書きにくいものは内部ライブラリのテスト書く

UIとか画像処理のテストとか書きにくい。
あとhubot scriptのテストの書き方がよくわからない。robot.respondとか、ユーザーの入力にフックしてるようなのの書き方がドキュメントどこ探しても見つからなかった。

hubot-rss-readerの場合、rss-checkerという内部ライブラリをhubot scriptと別ファイルに作っておいて、mochaでテスト書いた。hubot scriptの方はテスト書いてない。
それをgrunt-simplemochaで実行できるようにして、さらにgrunt testをnpm testから実行できるようにしている。package.jsonのscriptsにコマンドが書けるので便利。

{
"name": "hubot-rss-reader",
"private": false,
"version": "0.6.5",
"description": "Hubot RSS Reader",
"main": "scripts/hubot-rss-reader.coffee",
"scripts": {
"test": "grunt test" (注:これがnpm testで実行できる)
},
(略)
.travis.ymlを置いて、GitHubからTravis CIへのフックを設定すればgit pushしたりプルリク受けたりするだけでTravis CI上でnpm testが走るようになる。


アカウント情報を暗号化してTravis CIに保存できる

gyazo-api npmのテストでは、毎回gyazoに画像をアップロードしてリスト取得して削除している。
oauthのaccess tokenが必要なので、travis encryptしてtokenを保存している。

% travis encrypt GYAZO_TOKEN=a1b2cde --add env
これを実行すると.travis.ymlに環境変数を暗号化して保存できる。

language: node_js
node_js:
- '0.10'
env:
secure: asdfadajowejfoaiwejfoawiejfpaiup(暗号化されたtoken)

Travis CI: Environment Variables


ローカルで実行する時は普通に環境変数でtokenを渡せばtest実行できる。
% GYAZO_TOKEN=a1b2cdef npm test


サーバーでtest実行できない時は、lintだけでもかけておく

というかlintは設定するコスト低いので全てのプロジェクトでかけるようにはしている。

testできないものの例としては、node-ble-firmataはあらかじめ特別なファームウェアを書き込んだBLE付きArduinoを用意する必要があるので、これはどうやってもTravis CIでテスト実行できない。
しょうがないので、testは手元でやるとして、CIではcoffee-lintだけかけておく。coffeeはわりと文法間違える人いるのでlintだけでもあるとなんか安心感が違う。

普通にnpm installするとbluetooth関係のnpmをインストールしようとしてCライブラリが無くてTravis CIではビルド失敗するので、devDependenciesだけワンライナーでインストールするようにした。

language: node_js
node_js:
- '0.10'
install: node -e 'console.log(Object.keys(require("./package.json").devDependencies).join(" "))' | xargs npm install
script: npm run lint
これでnpm run lintだけが実行される。

ちなみにnpm install –devしたらdevDependenciesだけインストールできそうだったんだけど、依存解決が無限ループして20分ぐらいインストールし続けて終了するのでやめた。


複数の言語でテストする

socket.io-client-simple gemなんかがそうで、nodeで立てたsocket.ioサーバーにrubyで接続して通信できるかテストをしている。

.travis.ymlでメイン言語をrubyにして、それとは別にnodeのバージョン指定をするとrubyもnodeもインストールされる。npm installはbefore_scriptのタイミングでやると、gemのインストール→npmのインストール→rake test実行 という順番になる。
language: ruby
node_js:
- '0.10'
rvm:
- '2.1.2'
before_script:
- npm install


slackに通知する


Travis CI: Configuring Build Notificationsに書いてあるが、slackでtravis integrationを追加してtokenを取得してから、

% travis encrypt "[account]:[token]" --add notifications.slack

で.travis.ymlに通知設定が保存される。CI終わったらslackに通知が来る。


その他

あとは、READMEにサンプルコードの実行方法を書いておいたり、基本的な機能がすぐ試せる実行コマンドを付けておくとissueとかのトラブルシュートに役立つ。なんかきかれたら「〜〜を実行できる?」とか質問しやすい。

coffee-lintで1行の文字数が最大80文字という設定がデフォルトになってるけど、80文字というのは昔のパンチカードの文字数が80文字だったからMacとかのターミナルの横幅もデフォルト80文字になって未だに引きずっている意味のない数値らしいので、80文字にこだわる必要はない。
むしろ長いURL文字列を作る時とかに書きにくくなる。coffee-lintでは0を指定すると制限解除できる。

    coffeelint:
options:
max_line_length:
value: 0

0

Travis CIに環境変数を設定する

参考

Travis CI: Environment Variables – Secure Variables


環境変数をセット

.travis.yml にenvを設定すれば環境変数がセットされた状態でtestが走る
language: node_js
node_js:
- '0.10'
env:
GYAZO_TOKEN=a1b2cdef123456hogehoge

テストコードの中で使える
gyazo = new Gyazo process.env.GYAZO_TOKEN
gyazo.upload "#{__dirname}/test.jpg"


暗号化

APIのtokenとかを晒したくない場合は

% travis encrypt "GYAZO_TOKEN=a1b2cdef3456asdfhogehoge" --add env

すると”secure: ~~~~”という暗号化された文字列になってenvに追加されて、Travis CIのサーバーで実行時に復号される。

0

Travis-CIがnodejs 0.1を使おうとして死ぬ

1時間ぐらい前からTravis-CIの挙動が変わった。
いきなりテスト通らなくなったので何事かと思ったら、node 0.1をインストールしようとして死んでた。

nvm use 0.1



.travis.ymlにこう書いていると、0.10が0.1になる。
language: node_js
node_js:
- 0.10

Travisのgemで.travis.ymlにtokenを暗号化して埋め込んだりしているとわかるけど、travisはyaml設定ファイルの値が数値だったら0.10とかを0.1にしてくる。
Rubyで0.10.to_fすると0.1になるみたいな感じ。


nvm use 0.10してくれるようにする

普通に文字列で”0.10″指定すればいい
language: node_js
node_js:
- "0.10"


俺のリポジトリけっこう色んな所で0.10と書いているので全部直すの面倒くさい


0.10を数値として扱うのはyamlの仕様なので、v0.10のように書いて文字列として認識させるというのもアリですね