Test kitchen is Chef’s integration testing framework. It enables writing tests, which run after VM is instantiated and converged using the cookbook. The tests run on VM and can verify that everything works as expected.
This is node contract to ChefSpec, which only simulates a Chef run. Test Kitchen boots up a real node and runs Chef on it.
Setting Up
In order to do this, we need to have Vagrant installed on the machine which helps in managing a virtual machine. Then we need to have bookshelf installed and hooked with Vagrant in order to manage cookbook dependencies.
Step 1 − Edit default recipe in the cookbook.
vipin@laptop:~/chef-repo $ subl cookbooks/<Cookbook Name>/recipes/default.rb file "/tmp/greeting.txt" do content node['my_cookbook']['greeting'] end
Step 2 − Edit cookbook attributes.
vipin@laptop:~/chef-repo $ subl cookbooks/<Cookbook Name>/attributes/default.rb default['my_cookbook']['greeting'] = "Ohai, Chefs!"
Step 3 − Edit gem file to install the necessary Ruby gems.
vipin@laptop:~/chef-repo $ subl Gemfile gem 'test-kitchen', '~> 2.0.0.alpha.7' gem 'kitchen-vagrant'
Step 4 − Install the necessary Ruby gem.
vipin@laptop:~/chef-repo $ bundle install ...TRUNCATED OUTPUT... Installing test-kitchen (1.0.0.alpha.7) Installing kitchen-vagrant (0.10.0) ...TRUNCATED OUTPUT...
Step 5 − Create .kitchen.yml file in the cookbook.
vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ subl .kitchen.yml --- driver_plugin: vagrant driver_config: require_chef_omnibus: true platforms: - name: ubuntu-12.04 driver_config: box: opscode-ubuntu-12.04 box_url: https://opscode-vm.s3.amazonaws.com/vagrant/ opscode_ubuntu12.04_provisionerless.box suites: - name: default run_list: - recipe[minitest-handler] - recipe[my_cookbook_test] attributes: { my_cookbook: { greeting: 'Ohai, Minitest!'} }
Step 6 − Create a test directory inside the cookbook.
vipin@laptop:~/chef-repo/cookbooks/<Cookbook Name>$ mkdir test
Step 7 − Create a test cookbook for integration testing.
vipin@laptop:~/chef-repo/cookbooks/<Cookbook Name>/test $ knife cookbook create my_cookbook_test ** Creating cookbook my_cookbook_test ** Creating README for cookbook: my_cookbook_test ** Creating CHANGELOG for cookbook: my_cookbook_test ** Creating metadata for cookbook: my_cookbook_test
Step 8 − Edit test cookbooks default recipe.
vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ subl test/cookbooks/my_cookbook_test/recipes/default.rb include_recipe 'my_cookbook::default'
Step 9 − Create Minitest Spec inside the cookbook.
vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ mkdir -p test/cookbooks/my_cookbook_test/files/default/tests/minitest vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ subl test/cookbooks/my_cookbook_test/files/default/tests/minitest/default_test.rb require 'minitest/spec' describe_recipe 'my_cookbook::default' do describe "greeting file" do it "creates the greeting file" do file("/tmp/greeting.txt").must_exist end it "contains what's stored in the 'greeting' node attribute" do file('/tmp/greeting.txt').must_include 'Ohai, Minitest!' end end
Step 10 − Edit your main cookbook’s Berksfile.
vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ subl Berksfile site :opscode metadata cookbook "apt" cookbook "minitest-handler" cookbook "my_cookbook_test", path: "./test/cookbooks/my_cookbook_test"
Testing the Setup
vipin@laptop:~/chef-repo/cookbooks/my_cookbook $ kitchen test -----> Starting Kitchen (v1.0.0.alpha.7) ...TRUNCATED OUTPUT... -----> Converging <default-ubuntu-1204> -----> Installing Chef Omnibus (true) ...TRUNCATED OUTPUT... Starting Chef Client, version 11.4.4 [2013-06-29T18:33:57+00:00] INFO: *** Chef 11.4.4 *** [2013-06-29T18:33:58+00:00] INFO: Setting the run_list to ["recipe[minitest-handler]", "recipe[my_cookbook_test]"] from JSON ...TRUNCATED OUTPUT... # Running tests: recipe::my_cookbook::default::greeting file#test_0001_creates the greeting file = 0.00 s = . recipe::my_cookbook::default::greeting file#test_0002_contains what's stored in the 'greeting' node attribute = 0.00 s = . Finished tests in 0.011190s, 178.7277 tests/s, 178.7277 assertions/s. 2 tests, 2 assertions, 0 failures, 0 errors, 0 skips ...TRUNCATED OUTPUT... -----> Kitchen is finished. (2m5.69s)