ChefSpecの始め方

  • 29
    Like
  • 0
    Comment
More than 1 year has passed since last update.

はじめに

Chefのテストはserverspec - Homeとかtest-kitchen/test-kitchenとかCucumber-chefとか色々あります。
ただ、これら3つは実際に仮想マシンを動かしてそれに対してクックブックを実行してテストするものです(たぶん)。

nodeの値変えたら設定ファイルの値がちゃんと変わるかとか、not_ifが期待通り動くかとかレシピのロジックのテストをするなら、ChefSpecが実行が速いし向いてるんじゃないかと思います。

ChefSpecのインストール

Gemfileに以下を追加
ChefSpec 3.0からknife cookbookコマンドでspecの雛形を作る機能が別gemになったので、knife-specを追加する。(詳細

Gemfile
source "https://rubygems.org"

gem "chefspec"
gem "knife-spec"

インストール

$ bundle install

.rspecにデフォルト設定を追加

.rspec
--colour
--format documentation

雛形作成

knife-specを入れると、knife cookbook createでテストコードの雛形が一緒に作られます。(ChefSpec 2.xにあったknife cookbook create_specsはなくなりました。)

$ bundle exec knife cookbook create nginx -o site-cookbooks/
** Creating cookbook nginx
** Creating README for cookbook: nginx
** Creating CHANGELOG for cookbook: nginx
** Creating metadata for cookbook: nginx
** Creating specs for cookbook: nginx

レシピとテストコードを書く

以下にサンプルが山ほどあるので、参考にしてテストコードを書く。
https://github.com/sethvargo/chefspec/tree/master/examples

例えば、nginxのポート番号を可変にするレシピがあって、ちゃんと渡したポート番号がはまるかのテストだったら、こんな感じ。

site-cookbooks/nginx/spec/recipes/default_spec.rb
require_relative '../spec_helper'

describe 'nginx::default' do
  let(:chef_run) do
    ChefSpec::Runner.new do |node|
      node.set["nginx"]["port"] = "8080"
    end.converge(described_recipe)
  end

  it "creates /etc/nginx/sites-available/default" do
    expect(chef_run).to create_template("/etc/nginx/sites-available/default")
  end

  it "changes port to 8080 in /etc/nginx/sites-availabel/default" do
    expect(chef_run).to render_file("/etc/nginx/sites-available/default").with_content(/[\s]+listen[\s]+8080;/)
  end
end

レシピ

site-cookbooks/nginx/recipes/default.rb
# nginxのインストール
package "nginx" do
  action :install
end

# /etc/nginx/sites-available/defaultの配置
template "/etc/nginx/sites-available/default" do
  source "nginx/default.erb"
  mode 00644
end

こんなノードファイルを渡すイメージ。

nodes/nginx.json
{
  "run_list":[
    "nginx"
  ],
  "nginx":{
    "port":"8080"
  }
}

/etc/nginx/sites-available/default はご想像に任せます。

実行

全部実行

$ bundle exec rspec site-cookbooks/nginx/spec/

nginx::default
  creates /etc/nginx/sites-available/default
  changes port to 8080 in /etc/nginx/sites-availabel/default

Finished in 0.02586 seconds
2 examples, 0 failures

default_spec.rbの10行目だけ実行

$ bundle exec rspec site-cookbooks/nginx/spec/recipes/default_spec.rb:10

nginx::default
  creates /etc/nginx/sites-available/default

Finished in 0.00448 seconds
1 example, 0 failures