IDEでRubyのデバッグをしたい
RSpecでテストを書いていて、テストをデバッグしたい時がある。ググってみるとprintfデバッグに毛が生えたようなものばかり引っかかって、そんな貧弱な環境でテストコードをデバッグするのは避けたいなぁというのが、正直な気持ち。有料の統合開発環境であればさっくりできるのかもしれないけど、勝手E2Eテストに予算がつくわけもないから、無料でなんとかしたい。どうやらVisual Studio Codeでできるらしいので、やってみた。Railsは関係ないよ。
rdebug-ideを使う
RubyをIDEでdebugするための仕掛けとして、rdebug-ide を使用する。確か、NetBeans でもRubyのデバッグのためにrdebug-ideを使っていたはず。
デバッグ対象のプログラムをrdebug-ideから動かして、IDEからブレークポイントを設定したり、変数の値を覗いたりするのだ。
Visual Studio CodeでRubyの開発環境を整える
Visual Studio CodeによるRubyのデバッグ | Developers.IOあたりを参考に。ただ、Rubyの開発で厄介なのは、
- RubyはそのPC全体向けにインストールされているものを使うのか、プロジェクトごとにシステムとは異なるバージョンを使うのか。
- ライブラリはシステム全体に入れるのか、プロジェクトごとに分けるのか。
という検討項目があることだ。どういう環境になっているかを把握した上で、適宜記事中の表現を読み替えていく必要がある。
この記事では
- 対象環境はWindows 7 64bit
- Ruby2.2がそのPC全体向けにインストールされている
- プロジェクトはbundlerを使用して、ライブラリはプロジェクトごとに分けている
という想定で記述している。
Visual Studio Codeの設定は、プロジェクトのディレクトリ/.vscode/ に置くようになっている。当初は.settings ディレクトリだったようだが、最近のバージョンでは変更になっている。
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for rdebug-ide",
"type": "Ruby",
"request": "attach",
"cwd": "${workspaceRoot}",
"remoteHost": "127.0.0.1",
"remotePort": "1234",
"remoteWorkspaceRoot": "${workspaceRoot}",
"preLaunchTask": "rdebug-rspec.bat",
"internalConsoleOptions": "openOnFirstSessionStart"
},
{
"name": "RSpec - all",
"type": "Ruby",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "/Ruby22-x64/bin/bundle",
"args": [
"exec",
"rspec",
"-f",
"d",
"${workspaceRoot}/spec"
],
"useBundler": true,
"pathToBundler": "c:/Ruby22-x64/bin/bundle.bat",
"pathToRDebugIDE": "c:/Ruby22-x64/bin/rdebug-ide.bat",
"env": {
"BROWSER": "chrome"
}
},
{
"name": "RSpec - active spec file only",
"type": "Ruby",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "/Ruby22-x64/bin/bundle",
"args": [
"exec",
"rspec",
"-f",
"d",
"${file}"
],
"useBundler": true,
"pathToBundler": "c:/Ruby22-x64/bin/bundle.bat",
"pathToRDebugIDE": "c:/Ruby22-x64/bin/rdebug-ide.bat",
"env": {
"BROWSER": "chrome"
}
}
]
}
“name”: “Listen for rdebug-ide” がデバッグのための設定。デバッグモードにするとこのファイルの”name”に描かれている部分がメニューに表示されて、選ぶと該当するブロックの処理が実行される。デバッグするときに”listen for rdebug-ide”を選ぶと、1回目はrdebug-ideが動き出す。2回目でデバッグ対象のプログラムを動かすという仕掛け。1回目の起動内容はpreLaunchTaskにTaskを書く必要があるため、別途タスクを定義しておく。それが、これ。
.vscode/tasks.json
{
"version": "0.1.0",
"command": "rdebug-rspec.bat",
"isShellCommand": true,
"args": ["${file}"],
"showOutput": "always"
}
commandに実行するプログラムを書くのだが、rdebug-ideではなく、バッチファイルを起動するようにしている。テスト対象のプログラムを動かす際、環境変数の設定など事前にやっておくことがある場合は、バッチファイル中で設定を行ってからrdebug-ideを起動するようにして実現する。
rdebug-rspec.bat
@echo off set BROWSER=chrome bundle exec rdebug-ide --host 127.0.0.1 --port 1234 -- vender\bundle\ruby\2.2.0\bin\rspec -f d %1 exit
rdebug-ideの引数は、.vscode/launch.json に書いたものと同じhost, portにしておく。
テスト結果が画面に出力されるので、読みやすいようにフォーマットを指定している。デバッグ対象のファイル1つを実行すれば十分なので、rspecの引数の最後は%1にして、指定されたファイルを指定する。
RSpec(Ruby)プログラムをデバッグする
うまく設定できたかどうかを確かめるために、実際にデバッグ起動をしてみる。
デバッグ対象のシナリオの途中にブレークポイントをセットしてから、VS Codeをデバッグモードにしてメニューから「Listen for rdebug-ide」を選択して実行。画面にデバッグ出力のエリアが現れて
Fast Debugger (ruby-debug-ide 0.6.0, debase 0.2.1, file filtering is supported) listens on 127.0.0.1:1234
と表示されたら、準備完了(バージョンは違うだろうから、よきに)。
もう1回実行して、ブレークポイントで止まれば設定完了。
rdebug-ideはシステムとプロジェクトの両方にインストールしてみた。どちらかでいいような気もするのだが、RSpecプログラムをデバッグするのが目的なので、これでよしとする。他にも意味のない設定が残っていそうなので、指摘する記事を書いて欲しいなぁと。ググってもRailsでのやり方ばかり引っかかって、意外と情報が少ない気がするのだ。