43
20

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.

RSpecでit / example / specifyはどのように使い分けるのか?〜日本語で書くならexampleって本当?〜

Last updated at Posted at 2022-02-09

はじめに

最近ときどき「RSpecでit/example/specifyをどのように使い分けたら良いのか」という話題を見かけるので個人的な私見を書いてみます。

使い分けに何か決まりはあるのか? → 技術上の決まりは何もありません

it/example/specifyは技術的にはまったく同じメソッドです。なので、itexamplespecifyに置き換えても問題なく動きます。

# itを使う
it 'adds numbers' do 
  expect(1 + 1).to eq 2
end

# itの代わりにexampleを使う
example 'adds numbers' do 
  expect(1 + 1).to eq 2
end

# itの代わりにspecifyを使う
specify 'adds numbers' do 
  expect(1 + 1).to eq 2
end

日本語と英語で使い分けが必要、なんてこともありません。

# itを使う
it '数値を加算する' do 
  expect(1 + 1).to eq 2
end

# itの代わりにexampleを使う
example '数値を加算する' do 
  expect(1 + 1).to eq 2
end

# itの代わりにspecifyを使う
specify '数値を加算する' do 
  expect(1 + 1).to eq 2
end

Q. じゃあなんで同じメソッドが3つもあるの?

これはテストコードを英文として読みやすくするためだと思います。

it/example/specifyを英文らしく読めるように使い分けるなら、次のような文例が作れそうです。

  • it "adds numbers" = それ(it)は数値を加算する
  • example "addition of numbers" = 「数値の加算」の例(example)
  • specify "one plus one equals two" = 「1足す1は2であること」を示す(specify)

なので、冒頭で提示したコード例は、次のように書いた方が、技術的な差異は無くとも 英文としては ベターかもしれません。

it 'adds numbers' do 
  expect(1 + 1).to eq 2
end

example 'addition of numbers' do 
  expect(1 + 1).to eq 2
end

specify 'one plus one equals two' do 
  expect(1 + 1).to eq 2
end

参考情報:RSpecの本にはどのように書いてあるか?

洋書になりますが、「Effective Testing with RSpec 3」という本があります。本の筆者は当時のRSpecのメンテナさん(Myron Marston氏)です。この本の中ではexamplespecifyの用例として次のようなコードが載っていました。

# Quoted from Effective Testing with RSpec 3 
# 「Effective Testing with RSpec 3」から引用
RSpec.describe PhoneNumberParser, 'parses phone numbers' do
  example 'in xxx-xxx-xxxx form'
  example 'in (xxx) xxx-xxxx form'
end

RSpec.describe 'Deprecations' do
  specify 'MyGem.config is deprecated in favor of MyGem.configure'
  specify 'MyGem.run is deprecated in favor of MyGem.start'
end

たしかにこんなふうになっていると、テストコードを次のように英文っぽく読むことができますね。

  • example 'in xxx-xxx-xxxx form' = xxx-xxx-xxxx形式の例(example)
  • specify 'MyGem.config is deprecated in favor of MyGem.configure' = 「"MyGem.config"は非推奨なので、代わりに"MyGem.configure"を使うこと」を示す(specify)

Q. itは英語で書き、exampleは日本語で書く、って習ったんですけど?

これはあまり根拠のない話なので気にしない方がいいと思います。

すでに述べたように、技術的には何の制約もないので、itexampleで英語と日本語を使い分けなくてもRSpecは問題なく動きます。

違いがあるとすれば、「英文として見たときの違和感をどれだけ減らせるか」の観点かもしれません。

RSpecのitは主語を表すitなので、英文として考えるならその次に動詞(addsやisなど)が来なければなりません。

しかし、

it '数値を加算する' do

のようになっていると、"it + 日本語の文章"という意味不明な英文が出来上がってしまいます。

もちろん、この問題はexampleやspecifyを使っても完全には解消されないのですが、itに比べると若干違和感を減らせるかもしれません。

# 「数値を加算する」例(example)と読めなくもない
example '数値を加算する' do

# 「数値を加算する」ことを示す(specify)と読めなくもない
specify '数値を加算する' do

「itは英語で書き、exampleは日本語で書く」という話はたぶんこういうところから出てきたんじゃないかな〜と個人的に考えています。

もちろん、チーム内のコーディングルールとして「itは英語で書き、exampleは日本語で書く」というルールを設定するならそれはそれでOKです。ですが、RSpecの決まり事としてはそのようなルールはどこにも存在しません。

仮に「itは英語で書き、exampleは日本語で書く」というルールがあったとて、

example '数値を加算する' do

は、結局英文としては破綻しているので、それなら

it '数値を加算する' do

と書いても大差ないし、あまり気にする意味はないと僕は思います。

そもそもの話ですが、RSpecの作者はたぶん「英文としてちゃんと読めるかどうか」ということしか気にしていなくて、日本語で書いたときにどうなるかなんて、ほとんど考えていないんじゃないでしょうか。。。

参考情報:もしかしてここが震源地?

僕が昔Qiitaに書いたRSpecの入門記事にも、it/example/specifyの使い分けについて次のような説明を書きました。

(まあ it '1 + 1 は 2 になること' よりも specify '1 + 1 は 2 になること'example '1 + 1 は 2 になること' の方が若干自然かもしれませんが・・・)

この記事は多くのRSpec初心者さんに読まれているので、もしかするとこの説明が変に強化されて「itは英語で書き、exampleは日本語で書く」みたいな話になってしまったのでは?という気がしなくもないです😅

おまけ:日本人にも優しい、日本語フレンドリーなRSpecを書いてみよう

先ほど「RSpecの作者はたぶん「英文としてちゃんと読めるかどうか」ということしか気にしていない」と書きましたが、実はdescribeitを日本語に置き換える方法があります。

以下のコード例を見てください。

RSpec.configure do |config|
  config.alias_example_group_to :次の仕様を記述する
  config.alias_example_to :次のような振る舞いを持つこと
end

次の仕様を記述する "四則演算" do
  次のような振る舞いを持つこと "1足す1は2である" do
    expect(1 + 1).to eq 2
  end
end

このコードではexample group(describecontext)のエイリアスとして次の仕様を記述するというメソッドを、example(it/example/specify)のエイリアスとして次のような振る舞いを持つことというメソッドをそれぞれ定義しています。

そのため、RSpecのコードを

次の仕様を記述する "四則演算" do

や、

次のような振る舞いを持つこと "1足す1は2である" do

のように書くことができます。

もちろん、このコードは実際に動かすことも可能です。

$ rspec sample_spec.rb --format documentation

四則演算
  1足す1は2である

Finished in 0.00121 seconds (files took 0.06884 seconds to load)
1 example, 0 failures

spec_helper.rbの中でエイリアスメソッドを定義すれば、こんなふうに「日本語フレンドリー」なRSpecを書くことも可能です・・・って、こんなことをする人はたぶんいないと思いますがw

まとめ

というわけで、この記事ではRSpecにおけるit/example/specifyの使い分けについてあれこれ語ってみました。
使い分けがわからなくて困っていた人の参考になれば幸いです😄

PR:RailsでRSpecを書きたいなら「Everyday Rails - RSpecによるRailsテスト入門」をどうぞ!

it/example/specifyの使い分け以前に、Railsでどうやってテストを書いたらいいかわかりません!」というRSpec初心者さんは、「Everyday Rails - RSpecによるRailsテスト入門」をどうぞ。2022年のアップデートでサンプルアプリケーションがRails 7.0にバージョンアップしています。

Rails 7.0対応以外にもさまざまなアップデートがあります。2022年版の詳しいアップデート内容は以下のブログ記事を参照してください。

43
20
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
43
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?