その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

be-let-it-be書いた

github.com

be-let-it-beというコマンドラインツールを書きました。これはRSpecのスペックファイル中に存在する letlet! を自動的に可能な限り let_it_be に書き換えるというものです。

$ be-let-it-be convert path/to/your_spec.rb

というふうに簡単に使うことができます。

let_it_beの効用

test-profに含まれているメソッド (宣言?) です。

letlet! はテストごとに実行されるのに対して let_it_be はテスト間で使い回されます *1。データベースがからむプロジェクトでRSpecを使っているとしばしば let 等の中でfactory_botを呼び出してレコードを作ったりすることになるわけですが、 let_it_be を使うとそれがテスト間で1回で済むことになるためテストの実行時間を短くできる可能性が出てきます。

let_it_be の効用の詳細については既に先行している有用な情報がありますのでそちらに譲ります:

というわけで、be-let-it-beによって可能な限り let_it_be に書き換えると自動的にテストの実行時間が短くなることが見込めるわけです。

どのように動くのか

富豪的な挙動ではあって、

  1. 与えられたスペックファイル内の letlet! を抽出してくる
  2. let/let! の出現した順から let_it_be に書き換えてテストを実行する。通ったら let_it_be の書き換えを維持し、通らなかったら元に戻す
  3. 2を全て終わるまで繰り返す

というものになっています。つまり let/let! の個数ぶんの回数テストが実行されることになる……のでこのあたりはもうちょっとなんとかしたいなとは思っているという感じです *2


また、出現した順にやっていくというのも最適解では無いとは思っており、本来であれば一番テスト実行時間が短くなる組み合わせを探索するのが良いのだろうとは思うのですが、しかし組み合わせ爆発が起こることが容易に想像できることや、ローカルでのテスト実行時間が案外ブレるのでそれを素朴に指標として使うことができないなどといった理由からここには手を付けていないという状況になっています。


というような感じではありますがちゃんと動くし、その結果についても一定満足というような感じではあります。


余談ではありますが、最初のバージョンでは let/let! の抽出にperser、コードの書き換えにunperserを使っていたのですが、 id:tomo_ariさんから「Prism使ったら良いんじゃないすか」というアドバイスをもらったのでそのようにしました。Prismを使うとparser挙動はもちろん、unparser的なことも一挙にできて便利で良かったです。

まとめ

be-let-it-beのご紹介でした。実戦投入されています。

実際に実行時間が短縮されている様子

なかなか良い感じです。ぜひご活用ください。

*1:つまり高々1回の呼び出しで済む

*2:二分探索的にやれるようにするとか?