RSpecのデバッグ環境をVS Codeで構築する

RSpecのデバッグ環境をVS Codeで構築する

IDEでRubyのデバッグをしたい

RSpecでテストを書いていて、テストをデバッグしたい時がある。ググってみるとprintfデバッグに毛が生えたようなものばかり引っかかって、そんな貧弱な環境でテストコードをデバッグするのは避けたいなぁというのが、正直な気持ち。有料の統合開発環境であればさっくりできるのかもしれないけど、勝手E2Eテストに予算がつくわけもないから、無料でなんとかしたい。どうやらVisual Studio Codeでできるらしいので、やってみた。Railsは関係ないよ。Ruby

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でのやり方ばかり引っかかって、意外と情報が少ない気がするのだ。

この記事へのコメント

Loading Facebook Comments ...

No Trackbacks.