はじめに
この記事ではRSpec時にvagrantを使用したテストを書く方法を紹介します。テスト実行時にvagrantのイメージを自動で起動し、テストの効率化も図ります。プロジェクトのディレクトリ構造は以下のとおりです。
/
│── .rspec
└── spec
├── spec_helper.rb
├── vagrant
│ │── Vagrantfile
│ └── provisioning.sh
└── vagrant_spec.rb
テスト用の Vagrantfile
やプロビジョニングスクリプトを spec
内に配置することで、ディレクトリ構造もすっきりします。
下準備
rspec --init
して、.rspec
と spec/spec_helper.rb
を作ります
rspec --init
Vagrantfileを配置
今回はArchLinux上でApacheをつかってIt works!を表示する環境とそのテストを作ります。
spec/vagrant/Vagrantfile
に使用するイメージ名、VMの80番ポートをlocalhostの10080に転送設定、プロビジョニングスクリプトを指定します。
# spec/vagrant/Vagrantfile
Vagrant.configure(2) do |config|
config.vm.box = 'ubuntu/trusty64'
config.vm.network :forwarded_port, guest: 80, host: 10080, auto_correct: true
config.vm.provision :shell, :path => 'provisioning.sh'
end
プロビジョニングスクリプトは spec/vagrant/provisioning.sh
に配置します。今回は単純に、apacheをインストールして有効化するシェルスクリプトです。
#!/bin/sh
# spec/vagrant/provisioning.sh
apt-get install apache2 -y
service apache2 start
その他vagrantが使うファイルも spec/vagrant
に置くと、ディレクトリが散らからなくてよいです。
RSpecの設定
RSpecの before(:suite)
と after(:suite)
を設定することで、全てのテストスイートの前後で実行する処理を記述できます。ここに vagrantの起動・破棄する処理を書きます。
# spec/spec_helper.rb
RSpec.configure do |config|
config.before(:suite) do
puts "Starting up virtual machine..."
`VAGRANT_CWD=#{File.expand_path('../vagrant', __FILE__)} vagrant up`
end
config.after(:suite) do
puts "\nDestroying virtual machine..."
`VAGRANT_CWD=#{File.expand_path('../vagrant', __FILE__)} vagrant destroy -f`
end
end
ここでポイントなのがvagrant実行時に環境変数 VAGRANT_CWD
に Vagrantfile
のあるディレクトリを設定します。これによりカレントディレクトリに Vagrantfile
を置かなくとも、vagrantの操作ができます。以下のコマンドで指定した場所の Vagrantfile
の状態が確認できます。
VAGRANT_CWD=spec/vagrant vagrant status
HTTPの確認をするspecを書く
vagrantでHTTPサーバを作ったので、きちんと200が帰ってくるかの簡単なテストを書きます。
# spec/vagrant_spec.rb
require 'net/http'
RSpec.describe 'vagrant' do
describe 'apache' do
it 'responds contents with 200' do
response = Net::HTTP.start('localhost', 10080) { |http| http.get('/') }
expect(response.code_type).to eq(Net::HTTPOK)
end
end
end
そしてRSpecを回してテストがパスすればOKです。
rspec
おわりに
自分はKerberosの認証サーバが必要なテストでvagrantを使用しましたが、mockを作るよりもvmで立てちゃったほうが手っ取り早いし確実です。また今回は紹介しませんでしたが、vagrant-vbox-snapshotを使ってスナップショットを撮ると、各テストケースごとにキレイな状態のVMを効率よく準備出来そうです。