nikkie-ftnextの日記

イベントレポートや読書メモを発信

続・Pythonで書いたGaugeのstep実装をパッケージにして配布したい 〜gauge validateだけでなくgauge runを通すまで〜

はじめに

七尾百合子さん、お誕生日 69日目 おめでとうございます! nikkieです。

前回gauge validateを通すのに私は夢中になっていたのですが、gauge validateは通ってもgauge runが通らないことに気づいていませんでした。

ハマった末にgauge validategauge runも通す設定を見つけました。

目次

結論:Gaugeのstep実装のPythonパッケージをインストールした環境を別に作る

名前は何でもいいのですが、gauge-projectとしましょう。
ここに仮想環境を作って、Gaugeのstep実装のPythonパッケージをインストールします1

% mkdir gauge-project
% cd gauge-project
% python3.12 -m venv venv --upgrade-deps
$ source venv/bin/activate
(venv) % python -m pip install 'playtest2@git+https://github.com/ftnext/playtest2-python'

アプリケーションのE2Eテスト環境を設定します2
python.propertiesには、gauge-projectのsite-packages下の絶対パスSTEP_IMPL_DIRに設定します(macOSの例です)。

STEP_IMPL_DIR = step_impl,/Users/.../gauge-project/.venv/lib/python3.12/site-packages/playtest2

gauge-projectの仮想環境を有効にし、E2Eテストのディレクトリに移動します(テスト対象のアプリケーションは別途起動しておきましょう)。
以上の設定でgauge validategauge runも通ります。

% gauge validate specs
Python: 3.12.8
No errors found.

% gauge run specs
Python: 3.12.8
# リクエストとレスポンスをロギングするサンプルアプリのテスト
  ## GETリクエストが送れる       ✔ ✔ ✔ ✔ ✔ ✔

Specifications: 1 executed      1 passed        0 failed        0 skipped
Scenarios:      1 executed      1 passed        0 failed        0 skipped

Total time taken: 110ms

全容はこちらから3

先駆者IBMさんの gauge-web-app-steps のREADMEを読み込んで気づきました4
Quick StartSTEP_IMPL_DIR絶対パスで指定してるぞ...」

ハマっての学び

gauge validategauge runとでspecの扱いが違う

ログを見たところ、gauge rungauge validateをまず実行する認識です。
GaugeはgRPCを使っているっぽく、どのように動いているかはまだ明確には理解できていませんが、使われていそうな箇所に検討をつけました。

gauge validateが通った設定でgauge runが通らなかったのは、specやstepの処理が異なるからなのだと思います。

gauge runはstep実装をどのようにimportするのか(load_impls()読み解き)

gauge validateを通した設定のまま、最初はE2Eテストのディレクトリの仮想環境にpip installしていました。

STEP_IMPL_DIR = step_impl,.venv/lib/python3.12/site-packages/playtest2

今回の学びから、E2Eテストのディレクトリの仮想環境をSTEP_IMPL_DIRに指定する方法は、getgauge自体のソースコードを修正しない限り動かないと思われます。

E2Eテストのディレクトリが、Gaugeのproject_rootとして扱われます。
動作を理解するポイントはこちら
https://github.com/getgauge/gauge-python/blob/v0.4.10/getgauge/impl_loader.py#L35

base_dir = project_root if impl_dir.startswith(project_root) else os.path.dirname(impl_dir)

stepを実装したファイルのディレクトリ(impl_dir)が

  • project_root以下にある場合
    • stepを実装したファイルのパスからbase_dirproject_root)までが剥ぎ取られて5Pythonのモジュールパスの文字列となります
    • .venv.lib.python3.12.site-packages.playtest2.steps相対パス扱いになりimportlib.import_module()でエラー
    • 仮想環境の名前を変えて作り直すも、venv.lib.python3.12.site-packages.playtest2.stepsとなり、venvは標準ライブラリにあってもvenv.libはないのでエラー
    • (仮に仮想環境名がクリアできてもsite-packagesはモジュール名に使えないハイフンを使っているのでここでも落ちそう)
  • project_root以下にない場合(例:この記事で取り上げたgauge-projectディレクトリ)
    • stepを実装したファイルのパスからbase_dirsite-packagesまで)が剥ぎ取られます
    • playtest2.stepsのようになるので、gauge runがアクセスできるPython環境にパッケージがあればimportできます

このことに気づいて、gauge-projectの仮想環境を有効にしてgauge runで動かすようにしました。
gauge-projectの仮想環境ではなく、E2Eテストのディレクトリの仮想環境を有効にする場合、そちらにも同様のパッケージのインストールが必要になります。
2つ仮想環境を扱うと将来混乱しそうなので、gauge-projectの仮想環境だけを扱う方法をこの記事では結論としました。

終わりに

GaugeのstepのPython実装をパッケージにして配布するのはつまづきどころが多く、思った以上に大変でした。
GitHubからインストールして動くようにできたので、落とし穴にはハマりきったはず。
この記事はパッケージのREADMEに活かされます。
PyPIでの公開をお楽しみに〜


  1. GitHub - ftnext/playtest2-python: Python port of https://github.com/uzabase/playtest2PyPIに公開準備中です
  2. gauge init pythonしている前提です
  3. 先日の記事の簡単なWeb APIにE2Eテストを書きました
  4. https://github.com/getgauge/gauge-python/blob/v0.4.10/getgauge/impl_loader.py#L78