Igata(鋳型)というテストの雛型作成ツールを作った

昨年登壇した福岡Rubyist会議04では、「Ruby本体のparse.yをサードパーティライブラリとして使えるようにする」という試みについて発表しました。


gamelinks007.hatenablog.com


speakerdeck.com


またその時に作ったライブラリのKanayago(金屋子)はこちらです。


github.com


当時はまだ一部のASTノードしか対応しておらず、実際にライブラリとして利用するのは難しい状況でした。登壇後も細々と実装を続け、つい先日ようやく全てのASTノードに対応しました。


「これでRubyのコードがパースしていじれる」ようになったので「せっかくだし何かKanayagoを使ったツールを作りたいな」と思い、Igata(鋳型)というツールを作ってみました。
Rubyのコードを渡すことでMinitestまたはRSpecのテストコードの雛型を作ってくれるツールになります。


テストの雛型作成ツールを作ろうと思ったきっかけとしては、後述する omochi の存在と、「実務でも使えるツールの方がドッグフーディングとして良さそうだ」と考えたからです。


github.com


利用シーンとしては

  • テストコードがないライブラリへの追加するテストコードを生成
  • Railsなどで仮置きで実装したモデルのコードへテストを生成する

などを考えています

主な利用シーンとしては、既存のコードベースにテストを追加する場面を想定しています。


また実装の着想としてはRubyKaigi 2024のLTで紹介されていた omochi から得ました。 僕自身もLTで登壇しており、ちょうど前の枠が omochi の発表だったこともあり印象に残っています。


github.com


speakerdeck.com


「テストコードを生成する」という点では omochi と同じ方向性のツールですが、Igataでは「複数のテストフレームワークに対応したい」「テストを書く際に面倒な構造を自動生成したい」「RubyのASTノードを直接扱いたい」といった意図を持って実装しています。

使い方

基本的にはCLIツールとして利用します。


# デフォルトではMinitestの雛型が生成される
bundle exec igata lib/user.rb > test/test_user.rb

# -f rspecでRSpecの雛型が生成される
bundle exec igata lib/user.rb -f rspec > spec/user_spec.rb


例えば以下のようなコードを渡すと


class User
  def initialize(name, age)
    @name = name
    @age = age
  end

  def adult?
    @age >= 18
  end
end


以下のようなMinitestの雛型を生成したり


# frozen_string_literal: true

require "test_helper"

class UserTest < Minitest::Test
  def test_initialize
    skip "Not implemented yet"
  end

  def test_adult?
    # Comparisons: >= (@age >= 18)
    skip "Not implemented yet"
  end
end


このようなRSpecの雛型を生成することができます。


# frozen_string_literal: true

require "spec_helper"

RSpec.describe User do
  describe "#initialize" do
    it "works correctly" do
      pending "Not implemented yet"
    end
  end

  describe "#adult?" do
    # Comparisons: >= (@age >= 18)
    it "works correctly" do
      pending "Not implemented yet"
    end
  end
end


Kanayago経由でメソッド内の条件分岐などの情報が取得できるので Comparisons: >= (@age >= 18)のようなコメントも追加で出力するようにしています。 こうしたコメントを自動で出力することで、テスト設計時に条件分岐の意図を素早く把握できますし、将来的にはLLMを活用してテストケースを自動生成する際の補助情報としても活かせるのではと思ってこうしています。


今後

一旦は個人的に作っているライブラリなどで試しつつ、Railsのrequest specやmodel specなども対応していきたいと思います。 またKanayago自体の改善やparse.yに投げているキーワードの位置情報を追加対応なども進められれば、より便利なテストの雛型を生成できるようになると考えています。