Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

RSpecやMochaのテストにタグをつけてテスト対象をフィルタする

f:id:tbpg:20161108235724p:plain

t_wadaさんに技術相談をしました という記事で言及されていた
テストのタグ付について気になったので、具体的な実装レベルのところについてまとめます。

cureapp-dev.hatenablog.com

各テストフレームワークのタグ利用方法

RSpec

RSpec では describe, context, it などにタグを付加し、
rspec コマンドの --tag オプションや
RSpec::Core::Configuration#filter_run_including(*args)
などを利用することによってタグによるフィルタを実現できます。

タグは キー・値 のHash形式で指定します。
論理型の場合は、キー名を記述するだけで key: true
キー名を書かないことで key: false と同様の意味になります。

サンプル

RSpec.describe 'group with tagged specs' do
  it 'focus true', focus: true do
    expect(true).to be true
  end
  it 'focus false', focus: false do
    expect(true).to be true
  end
  it 'speed fast', :focus, speed: 'fast' do
    expect(true).to be true
  end
  it 'speed slow', speed: 'slow' do
    expect(true).to be true
  end
end

実行結果

  • フィルタなし
$ rspec -fd

group with tagged specs
  focus true
  focus false
  speed fast
  speed slow

Finished in 0.00138 seconds (files took 0.09934 seconds to load)
4 examples, 0 failures
  • focus true のみ実行
$ rspec --tag @focus -fd
Run options: include {:focus=>true}

group with tagged specs
  focus true
  speed fast

Finished in 0.0012 seconds (files took 0.09298 seconds to load)
2 examples, 0 failures
  • focus を否定すると除外になります

~ で否定です

$ rspec --tag ~@focus -fd
Run options: include {:focus=>true}

group with tagged specs
  focus false
  speed slow

Finished in 0.00113 seconds (files took 0.09338 seconds to load)
2 examples, 0 failures

※ spec_helper でフィルタすることもできます。この場合は rspec 実行時の --tag オプションは不要です

RSpec.configure do |config|
  config.filter_run_including :focus => true
end
$ rspec -fd
Run options: exclude {:focus=>false}

group with tagged specs
  focus true
  speed fast

Finished in 0.00128 seconds (files took 0.09333 seconds to load)
2 examples, 0 failures

※除外することもできます

RSpec.configure do |config|
  config.filter_run_excluding :focus => false
end
$ rspec -fd
Run options: exclude {:focus=>false}

group with tagged specs
  focus true
  speed fast

Finished in 0.00128 seconds (files took 0.09333 seconds to load)
2 examples, 0 failures
  • speed fast のみを実行
$ rspec -fd --tag @speed:fast
Run options: include {:speed=>"fast"}

group with tagged specs
  speed fast

Finished in 0.0011 seconds (files took 0.09975 seconds to load)
1 example, 0 failures
  • speed fast 以外を実行
$ rspec -fd --tag ~@speed:fast
Run options: exclude {:speed=>"fast"}

group with tagged specs
  focus true
  focus false
  speed slow

Finished in 0.00131 seconds (files took 0.09338 seconds to load)
3 examples, 0 failures

Mocha

Mocha では describe, context, it などに、
任意の文字列を埋め込み、 --grep オプションでフィルタすることで
タグの機能を実現することができます。

RSpecのような形式でのフィルタについては、 2016/11/08 現在は下記Issueにて検討中のようです。

Test metadata - Issue928 - mochajs/mocha - GitHub

サンプル

  • sample.js
describe("sample", function() {
  context("focus context @focus", function() {
    it("focus1", function() {});
    it("focus2", function() {});
  });
  context("not focus context", function() {
    it("focus3 @focus", function() {});
    it("not focus", function() {});
  });
});

grep option でタグを指定します

{
  "name": "mocha_sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test_focus": "mocha --grep @focus",
    "test_not_focus": "mocha --grep @focus --invert"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "mocha": "^3.1.2"
  }
}

実行結果

  • フィルタなし

  • focus のみ実行

$ npm run test_focus
  sample
    focus context @focus
      ✓ focus1
      ✓ focus2
    not focus context
      ✓ focus3 @focus


  3 passing (7ms)
  • focus を除外実行
$ npm run test_not_focus
  sample
    not focus context
      ✓ not focus


  1 passing (6ms)

関連記事