0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-07-03

お気に入りのテストフレームワークの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クローンも気に入っていただけると嬉しい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?