0
Help us understand the problem. What are the problem?

posted at

updated at

使用するテスト言語と期待される生成テストコード

お気に入りのテストフレームワークのDSLを使用した場合、どのようなコードが生成されるかご存知ですか?

開発者としては、知っておくと面白いかもしれないね。もしかしたら、直接書くことができないほど恐ろしいものかもしれない。あるいは、minitestのテストセットよりも簡単かもしれない。

とにかく、RSpecとminitestの間に終わりのない議論を避けながら、この質問に答えようとするために、この記事の目的のためにRSpecクローンプロジェクトを使用する。

RSpec cloneとは?

このプロジェクトは、正確、セキュリティ、標準化を重視したRSpecのミニマリストな再実装だ。

コミュニティのRSpecスタイルガイドに記載されているガイドラインとベストプラクティスを実施したいという思いから、このRSpecクローンはRSpecのDSLのほとんどを含み、魔法の力を使わずに期待される結果を表現する。

What did you RSpec?

早速ですが、フレームワークがどのようにテストを構築・実行するのかを理解するために、DSLの構文と生成されたRubyのコードの対応関係をご紹介する。読みやすくするために、これらの対応関係はメソッドごとにまとめられている。

DSLからRubyへ

describe メソッド

これを書くと

RSpec.describe String do
end

このコードが生成されることを期待している:

Class.new do
  private

  def described_class
    String
  end
end

context メソッド

これを書くと

RSpec.context "when in a context" do
end

このコードが生成されることを期待している:

Class.new do
end

subject メソッド

これを書くと

RSpec.describe ".subject" do
  subject do
    "foo"
  end
end

このコードが生成されることを期待している:

Class.new do
  private

  def subject
    "foo"
  end
end

エンベデッド describe メソッド

これを書くと

RSpec.describe ".describe" do
  describe "embedded describe" do
  end
end

このコードが生成されることを期待している:

base = Class.new do
end

Class.new(base) do
end

let メソッド

これを書くと

RSpec.describe ".let" do
  let(:answer_to_everything) { 41 + one }
  let(:one) { 1 }
end

このコードが生成されることを期待している:

Class.new do
  private

  def answer_to_everything
    41 + one
  end

  def one
    1
  end
end

before メソッド

これを書くと

RSpec.describe ".before" do
  before do
    puts "hello"
  end
end

このコードが生成されることを期待している:

Class.new do
  private
  
  def initialize
    puts "hello"
  end
end

expect メソッド

これを書くと

RSpec.describe "#expect" do
  it { expect(41.next).to be(42) }
end

このコードが生成されることを期待している:

description = Class.new do
end

require "matchi/rspec"
require "r_spec/clone/expectation_target"

example = Class.new(description) { include Matchi::Helper }
sandbox = example.new
sandbox.instance_eval { ExpectationTarget::Value.new(41.next).to be(42) }

そして、このメッセージを期待している:

Success: expected to be 42.

Rubyでのテストが楽しい

テストを書かないのであれば別ですが、このようなDSLインターフェイスを使用する利点は、エラーの可能性がある追加のロジックを仕様書に導入することを制限し、アルゴリズムの複雑さが少ない優れたRubyパターンの使用を奨励し、Rubyコードをより短く、より(機械)可読にすることだ。

Adam Hawkinsさんから

RSpecはテストのためのドメイン特化言語で、minitestはrubyだ。

どちらも好きなので、RSpecクローンも気に入っていただけると嬉しい。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?