Railsでの製作Tips Redmineのプラグイン製作

Redmine3でのテストあれこれ〜minitest

投稿日:2015年5月9日 更新日:

RSpec or Minitest?

RSpecも使えるみたいだけど、Redmine本体のFixtureを使うのは簡単ぽくなかったので、今回はMinitestを使った.

RedmineでRSpecを使うには、以下を参照
RedmineのプラグインをRSpecでテストする
Redmine pluginの開発について当初自分が疑問に思ってたことに回答

MinitestはRailsにTest/Unitに代わって同梱されるようになったテストスイート.Rubyの標準ライブラリだったらしいけど、Ruby2.2からgemになったぽい.よく調べていない.

Redmineではプラグインやプラグイン用のモデルやコントローラをジェネレートすれば自動的にminitest用の関連ファイルを作成してくれる.

minitest用のrakeタスクも用意されている.

Minitestの基本とか

参考: minitest/{unit,spec,mock,benchmark}
Railsテスティングガイド
#327 MiniTest with Rails pro
Minitest Quick Reference

Minitestの評判を見ると、RSpecは独自のDSLだけど、Minitestはrubyと親和性が高いらしい.そのほか、拡張性が高いっぽいところの評価が高い(雑).
参考: 私がMinitestとRailsのFixturesにハマった7つの理由

Minitest is Just Ruby
参考: 「Ruby on Rails on Minitest」を翻訳してみた

で、ユニットテストがこう

メソッド名はtest_で始まらないと、テストケースと認識してくれないので注意.
そのほか、test、it、describeメソッドも使える.
まず、testメソッドは、test_なんとかに置き換えてくれる.
次に、itメソッドは、test_001_なんとかに置き換えてくれる.
describeは、testやitメソッドをグルーピングできる.
MinitestでもRSpecスタイルのDSLが書けるけど、やはりfixtureがうまく呼び出せなかったので、通常のスタイルで書いた.

Ruby MiniTest Cheat Sheet, Unit and Spec reference

fixtureはbefore_saveなどのcallbackを呼ばないので注意.callbackを使いたいならFactoryGirlとかを使う.
参考: Forcing do_save after Rails fixture load

テストはRedmineのルートで走らせる.
NAME=以下はプラグイン名.

before each/after eachはsetup/teardownメソッドを定義する.

テストしたデータはテストごとに初期化(transaction strategy?)されるけど、FixtureのデータはRAILS_ENV=testのデータベースに残ったままになるので注意が必要.

ファンクショナルテストがこんなかんじで、

Redmine本体のユニットテストを読む

Redmine本体のテストを読むのがいろいろ勉強になる.

with_settingsメソッド

test_helper.rbで定義している.あるセッティングでのテストができる.

Redmine本体のファンクショナルテストを読む

session[:user_id]とかSettingとか

どのユーザーで行動しているかが大事なので

add_permissionとremove_permission

Roleから

表示関係のテスト

だいたい、リクエストが成功しているか、正しいテンプレートを使っているか、インスタンス変数は予定した内容か、予定した要素が含まれているかといったことをテストしている.

作成・更新系のテスト

作成・更新といった操作の前後の比較、操作後のデータの確認などをテストしている.

mocha

Mochaが楽しそう

プラグイン用のフィクスチャー

参考:  RE: Testing plugins in Redmine 2.x

これを参考にtest_helper.rbに次のような設定をする.

すると、plugin_fixtureというメソッドを使えるようになるので、プラグインルートのtest/fixturesに置いたymlを読み込めるようになる.

plugin作成のこの本を読んでたら見つけたネタです.

Redmine Plugin Extension and Development

Redmine Plugin Extension and Development [Kindle本]

著者Alex Bevilacqua

出版社Packt Publishing

出版日2014年3月19日

商品カテゴリーKindle版

ページ数114

Supported by amazon Product Advertising API

プラグインのフィクスチャーと本体のフィクスチャーの関連付けがうまくいかない.
エラーは出ないんだけどidがありえない数字になってたりする.
しょうがないので関連性はあきらめて、user_idとかissue_idとかで直接指定することにした.

Redmineの本体のデータベースの構造は複雑なので、テストをするときは、まとめてデータを入れておいたほうがいい場合がある.
本体のテストを参考に、こんなかんじで.

また、オーバーライドみたいなことも可能っぽくて、例えば、プラグインのfixturesにusers.xmlを置いておけば、そちらを読んでくれるぽい.(詳細は未検証だけど、とりあえずそんな動きをしている.)

minitestのAssertionの拡張

minitest-power_assert

こんなかんじで

失敗した場合もわかりやすい

参考: minitestのオススメ設定調べてみた(アサーション編)

テスト用ライブラリ power-assert

github.com/hsbt/minitest-power_assert

minitest-ar-assertions

こんなかんじで関連のテストが書ける.

rails-dom-testing

rails/rails-dom-testing
見ての通りrailsリポジトリのgem
nokogiriを使ってdomベースでアサーションが書ける.

minitest-reporters

出力のフォーマット設定.
RailsCastsで紹介されていたturnのほうが好みなんだけど、minitestのバージョン5には対応していなかった.
Gemfileに追加したら、test_helper.rbに下記を追加.

minitest-rails-capybara

capybaraも使える
minitest-rails-capybara
github.com/blowmage/minitest-rails-capybara

マルチスレッド

標準でrequire ‘minitest/hell’すればマルチスレッドでテストしてくれるっぽい.

参考: Bow Before MiniTest
Minitest Parallelization and You

Travis CIを使った継続的インテグレーション

Travis CIとは

公式
GitHubにpushすると自動でテストをして結果を通知してくれるサービス.

参考: Travis CIを使ってみた: GitHubのレポジトリにバッジを貼りたかったから

Redmine pluginでTravis CIを利用する

Redmineのplugin用のひな形が用意されているので、これを自分のプラグインルートにコピーして、修正したうえで、GitHubにpushする.
alexbevi/redmine_plugins_travis-ci

ネタ元は上の本.

.travis.ymlの修正

適当に.travis.ymlを修正する.
plugin名に自分のプラグインの名前を入れる.
自分のプラグインでは1.9.3が動かなかったので削除した.
あと、RVMを使っているのでRubyのバージョン指定は2.1とか大雑把でもOK.もちろん、細かく2.1.6とかも指定できる.
ブランチは最初testingのみを指定していたのでとりあえずmasterにした.
このあたりフォークして自分用に作っておいてもいいかもしれない.

参考: Redmine のプラグインを Travis で CI してみた

Travis CI側の設定

そして、Travis CIで自分のリポジトリの設定をオンする.
screenshot

GitHubにpush

トリガーはpushとpull requestみたい.
pushしたあとは、テストの結果を待つだけ.
screenshot

Rubyのバージョンごとに同時にテストを実行してくれている.
screenshot

成功するとグリーンに.ログもリアルタイムで見られる.
screenshot

バッジの設定

あとは、バッジをクリックすると、貼付け用のコードが出てくる.
screenshot

これを自分のREADMEに貼り付けておけば見慣れたアレが自分のREADMEにも表示される.
screenshot

データベースをmysqlでテストする

上のスクリプトでは、travis-ciでのテスト時にconfig/database.ymlを.travis-database.ymlで上書きコピーしてる.
なので、.travis-database.ymlの設定をmysqlにすればよい.
その場合、user名はroot、パスワードは空でOK.
MySqlとPostgreSQLの場合は、rake db:migrateの前にデータベースを作っておく必要があるので注意.
公式では、before_scriptで作る例があるけど、bundle exec rake db:createをしてもテストは通った.

複数のデータベース環境でのテスト

例えば、MySqlとSQLiteの環境でテストしたい場合
envをうまく使うことができる

yamlで&なんとかというのは初めてみたけど、yamlでエイリアスを設定する機能
参照: YAMLのアンカー&エイリアス

で、travis.ymlの方でenvごとにテストすればOK.
この場合、各Rubyのバージョンで各env環境でテストするので2×2=4通りのテストをすることになる.

参考: How to test your rails application with Travis CI on different databases engines

COVERALLSでカバレッジを計測

こんなスライドをみて、カバレッジ計測も追加.

Gemfileに追加

そして、bundle

test_helper

test_helper.rbの最初に追加.

参考: Coverallsで特定のファイルのみ集計対象にする

.coverall.yml

使用しているciのサービス名を書く.

coverallsに登録してpushして待つ

screenshot

バッジをREADMEに追加

スライドをみていろいろ追加してしまった.
screenshot

未解決の課題

failするとrakeがエラー

原因がよくわからなかった

rubyの実行に失敗してるぽいんだけど理由がわからない.
Rakeのshで外部コマンドを実行する

simplecov (解決!)

minitestの問題というより、Redmineのプラグインでカバレッジをどうやればいいのかわからない.
こんなかんじで設定してみたけど、0/0 coverage100%で1行も認識していない様子.

もともと、Redmineはsimplecovを使っているので、テストの際にCOVERAGE=trueを指定すればよかった.

すると、Redmineのルートにcoverageディレクトリができてるので、そこで、適当なサーバを立ち上げればOK
gem adsfなら4文字で簡易なwebserverを立ち上げることができる.

screenshot

Coverallsを利用することにした.

Guard

guardについては、RedmineのルートにGuardfileを作って、guard-shellを使ってこんなかんじで動いてる.

pluginルートで、ruby test/unit/**_test.rbは動くのに、plugrinルートのGuardfileからのguard-shellでrubyのコマンドを呼び出しても、undefined method ‘active record’になってしまう.
プラグインのルートで動かせるようにしたかったが、できなかった.

@netzpiratさんが亡くなっていたとはorz
guardの新しいメンテナを募集しているようです.

-Railsでの製作Tips, Redmineのプラグイン製作
-, , ,

執筆者:

関連記事

Rails5でAjax処理をActionCableを使ってリアルタイム同期化

By: Mike Johnston – CC BY 2.0 目次1 はじめに2 サンプル掲示板3 ActionCableでリアルタイム化4 チャンネルを購読して、ストリームで分配する5 c …

Railsでプロパティと同名のメソッドを作る

By: Images Money – CC BY 2.0 例えば、Projectというモデルにname、contentというプロパティがあるとき、nameというメソッドを作って、ちょっと改 …

Rubyのメソッドの引数について

By: Jared Tarbell – CC BY 2.0 目次1 HackerRank2 メソッドの引数3 デフォルト値4 *をつけた可変長引数(rest引数)5 キーワード引数6 ** …

railsのpathヘルパーでスラッシュの代わりにピリオドになっちゃうのでrails consoleでいろいろ試した

By: Nicolas Raymond – CC BY 2.0 目次1 問題2 解決3 pathとurlのヘルパーのあれこれ 問題 次のような環境で [crayon-599c958bb24 …

RailsのフォームにjQuery UIのSliderを使う

By: woodleywonderworks – CC BY 2.0 目次1 jQuery UI Slider2 ライブラリを読み込む3 コード4 できた jQuery UI Slider …