LoginSignup
3
4

More than 5 years have passed since last update.

Serverspecをrspecコマンドで実行する

Last updated at Posted at 2015-04-23

通常Serverspecは$ rake specで実行する
一方、rspecコマンドで実行するとエラーになる

次の方法でrspecコマンドで実行できるようにできる
(もし、すでに一般的な対応方法があったら教えてほしい)

通常はrspecコマンドでエラーになる

$ rake specで実行した後の出力のFailed examples:にrspecコマンドが表示される
その通りにrspecコマンドで実行すると以下のようなエラーになる

$ rspec ./spec/www.example.com/some_spec.rb:33
  1) Port "80" should be listening
     Failure/Error: it { should be_listening }
     TypeError:
       no implicit conversion of nil into String

または

/Users/user/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/net-ssh-2.9.2/lib/net/ssh/transport/session.rb:70:in `initialize': no implicit conversion of nil into String (TypeError)

rspecコマンドで実行できるようにする設定

シングルホストの場合

後述する複数ホストの場合のように、RSpec.configureでhostを設定しようと最初試したが、そもそもシングルホストの場合はフォルダからhostを取得する必要がない

なので、dotenvを使う方法が良い

Gemfile
gem 'dotenv'
spec/spec_helper.rb
require 'dotenv'
Dotenv.load
.env
TARGET_HOST=www.example.com

実行結果

$ rspec

...
Failed examples:

rspec ./spec/www.example.com/sample_spec.rb:5 # Service "httpd" should be enabled

複数ホストの場合

想定している構成はspec以下にホスト名でディレクトリを切って複数管理しているケース(例. spec/www.example.com/some_spec.rb

spec_helper.rb
RSpec.configure do |c|
  c.add_setting :host_taken_from_path

  c.before do |example|
    if c.host.nil?
      c.host = example.metadata[:file_path].gsub('./spec/', '').split('/').first
      c.ssh_options = Net::SSH::Config.for(c.host)
      c.host_taken_from_path = true
    end
  end

  c.after do
    if c.host_taken_from_path
      c.host = c.ssh_options = nil
      c.host_taken_from_path = false
    end
  end
end

rspec実行

$ rspec ./spec/www.example.com/some_spec.rb:33

Port "80"
  should be listening

Finished in 4.77 seconds (files took 1.46 seconds to load)
1 example, 0 failures

制約

RSpec.configureでhostを設定する場合、次のようなosの条件などが使えない(hostが空の時点でsshが走ってエラーになる)

describe service('httpd'), :if => os[:family] == 'redhat' do

留意点

RSpec.configureでhostを設定する場合、留意点としては失敗時にOn host 'www.example.com'のログが出力されない
ソース serverspec.rb

host_taken_from_pathafterのブロックを書かなければ出力されるようになるが、ssh_optionsをクリアしないことによって、以下のようにssh_options内の:send_envがおかしなことになる

{:auth_methods=>["none", "publickey", "password", "keyboard-interactive"], :host_name=>"XXX.XXX.XXX.XXX", :user=>"hoge", :keys=>["/Users/hoge/.ssh/id_rsa"], :send_env=>[/^LANG$/, /^LC_.*$/, "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG"]}

環境

  • rbenv + Ruby 2.1.4
  • serverspec (2.14.1), specinfra (2.30.0)
  • セットアップはUN*X, SSH
  • ホストの設定 ~/.ssh/config
  • set :request_pty, true
  • 適当なsudoの設定

その他

そもそものFailed examplesの部分の出力を変更することもできるかも

Failed examples:

rspec ./spec/www.example.com/some_spec.rb:33 # Port "80" should be listening

rake spec SPEC=spec/www.example.com/some_spec.rb:33
3
4
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
3
4