Chef Chefspec
ChefSpec is a unit testing framework for testing Chef cookbooks. ChefSpec makes it easy to write examples and get fast feedback on cookbook changes without the need for virtual machines or cloud servers.ChefSpec runs our cookbooks locally with Chef Solo without actually converging a node.
Structure of Cookbooks for ChefSpec
When writing unit tests for our cookbook, the standard is to create a separate spec test for each recipe in the /spec folder.
# tree
.
├── chefignore
├── httpd_deploy
│ ├── Berksfile
│ ├── chefignore
│ ├── metadata.rb
│ ├── README.md
│ ├── recipes #Recipes
│ │ └── default.rb
│ ├── spec
│ │ ├── spec_helper.rb
│ │ └── unit
│ │ └── recipes
│ │ └── default_spec.rb
│ └── test
│ └── smoke
│ └── default
│ └── default_test.rb
└── starter
├── attributes
│ └── default.rb
├── files
│ └── default
│ └── sample.txt
├── metadata.rb
├── recipes
│ └── default.rb
└── templates
└── default
└── sample.erb
Writing ChefSpec Program
# recipe/default.rb
package 'foo'
# spec/unit/recipes/default_spec.rb
require 'chefspec'
describe 'example::default' do
let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '16.04').converge(described_recipe) }
it 'installs foo' do
expect(chef_run).to install_package('foo')
end
end
ChefSpec Program
require 'chefspec'
At the top of the spec file, we require the chefspec gem. This is required so that our custom matchers are loaded. In larger projects, it is common practice to create a file named "spec_helper.rb" and include ChefSpec and perform other setup tasks in that file.
describe 'example::default' do
The describe keyword is part of RSpec and indicates that everything nested beneath is describing the example::default recipe. The convention is to have a separate spec for each recipe in your cookbook.
let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '16.04').converge(described_recipe) }
The let block creates the ChefSpec:SoloRunner with mocked Ohai data for Ubuntu 16.04 from Fauxhai. It then does a fake Chef run with the run_list of example::default. Any subsequent examples can then refer to chef_run to make assertions about the resources that were created during the mock converge.
SoloRunner
The SoloRunner allows us to simulate testing against the different operating systems (platforms) and versions by passing a parameter. It simulates the Chef run-in memory.
described_recipe
The described_recipe macro is a ChefSpec helper method that infers the recipe from the describe block. Alternatively, you could specify the recipe directly.
expect(chef_run).to install_package('foo')
Each of these examples defined expectations that desired packages will be installed.
expect(chef_run).to_not install_package('unzip')
Each of these examples defined expectations that desired packages not will be installed.
Relevant Blogs:
Recent Comments
No comments
Leave a Comment
We will be happy to hear what you think about this post