Chef - ChefSpec



Test Driven Development (TDD) is a way to write unit test before writing any actual recipe code. The test should be real and should validate what a recipe does. It should actually fail as there was no recipe developed. Once the recipe is developed, the test should pass.

ChefSpec is built on the popular RSpec framework and offers a tailored syntax for testing Chef recipe.

Creating ChefSpec

Step 1 − Create a gem file containing the chefSpec gem.

vipin@laptop:~/chef-repo $ subl Gemfile 
source 'https://rubygems.org' 
gem 'chefspec' 

Step 2 − Install the gem.

vipin@laptop:~/chef-repo $ bundler install 
Fetching gem metadata from https://rubygems.org/ 
...TRUNCATED OUTPUT... 
Installing chefspec (1.3.1) 
Using bundler (1.3.5) 
Your bundle is complete! 

Step 3 − Create a spec directory.

vipin@laptop:~/chef-repo $ mkdir cookbooks/<Cookbook Name>/spec 

Step 4 − Create a Spec

vipin@laptop:~/chef-repo $ subl  
cookbooks/my_cookbook/spec/default_spec.rb  
require 'chefspec'  
describe 'my_cookbook::default' do  
   let(:chef_run) {  
      ChefSpec::ChefRunner.new(  
         platform:'ubuntu', version:'12.04'  
      ).converge(described_recipe)  
   }  

   it 'creates a greetings file, containing the platform  
   name' do  
      expect(chef_run).to  
      create_file_with_content('/tmp/greeting.txt','Hello! ubuntu!')  
   end  
end 

Step 5 − Validate ChefSpec.

vipin@laptop:~/chef-repo $ rspec cookbooks/<Cookbook Name>/spec/default_spec.rb 
F 
Failures: 
1) <CookBook Name> ::default creates a greetings file, containing the platform name 
Failure/Error: expect(chef_run.converge(described_recipe)).to 
create_file_with_content('/tmp/greeting.txt','Hello! ubuntu!') 
File content: 
does not match expected: 
Hello! ubuntu! 
# ./cookbooks/my_cookbook/spec/default_spec.rb:11:in `block 
(2 levels) in <top (required)>' 
Finished in 0.11152 seconds 
1 example, 1 failure  

Failed examples: 
rspec ./cookbooks/my_cookbook/spec/default_spec.rb:10 # my_ 
cookbook::default creates a greetings file, containing the 
platform name 

Step 6 − Edit Cookbooks default recipe.

vipin@laptop:~/chef-repo $ subl cookbooks/<Cookbook Name>/recipes/default.rb 
template '/tmp/greeting.txt' do 
   variables greeting: 'Hello!' 
end 

Step 7 − Create a template file.

vipin@laptop:~/chef-repo $ subl cookbooks/< Cookbook Name>/recipes/default.rb 
<%= @greeting %> <%= node['platform'] %>! 

Step 8 − Run the rspec again.

vipin@laptop:~/chef-repo $ rspec cookbooks/<Cookbook Name>/spec/default_spec.rb 
. 
Finished in 0.10142 seconds 
1 example, 0 failures 

How It Works

In order to make it work, we need to first set up the base infrastructure for using RSpec with Chef. Then we need to ChefSpec Ruby gem and the cookbook needs a directory called spec where all the tests will be saved.

Advertisements