Test Kitchen is a central tool in the Chef ecosystem as it enables thorough testing of infrastructure code and plays very well with a lot of other tools we already use and know. It takes the strong testing culture from the development world and applies it to an infrastructure-as-code environment. Test Kitchen helps start an isolated system environment, apply Chef cookbooks to it, and then execute tests. Supported test frameworks include RSpec, ServerSpec, or Bats (and more), with a large choice of supported environments such as AWS, Vagrant, Digital Ocean, Docker, and OpenStack. Test Kitchen integrates very well with Berkshelf, so cookbook dependencies aren't an issue while testing complex infrastructures. The best part is, it's already included in the Chef DK, so we just have to use it.
In this section, we'll structure everything needed to properly test our Chef cookbooks code using Vagrant with CentOS 7.2
To step through this recipe, you will need the following:
Test Kitchen is configured by a single .kitchen.yml
file at the root of the cookbook. It contains a lot of information:
Irrespective of whether we already have a .kitchen.yml
file or not, let's open it and fill in the following details:
mysite::default
recipe, and a path to the Data BagsThis is how our .kitchen.yml
file looks for the mysite
cookbook:
--- driver: name: vagrant provisioner: name: chef_zero platforms: - name: centos-7.2 suites: - name: default data_bags_path: "../../data_bags" run_list: - recipe[mysite::default] attributes:
To simply launch Test Kitchen with the specified configuration, execute the following command:
$ kitchen test -----> Testing <default-centos-72> -----> Creating <default-centos-72>... [...] Finished creating <default-centos-72> (1m1.51s). -----> Converging <default-centos-72>... [...] -----> Installing Chef Omnibus (install only if missing) [...] resolving cookbooks for run list: ["mysite::default"] Synchronizing Cookbooks: - apache (0.5.0) - php (0.2.0) - selinux (0.9.0) - yum-mysql-community (1.0.0) - mysite (0.3.1) - mysql (8.0.4) - yum (4.0.0) [...] Chef Client finished, 41/56 resources updated in 02 minutes 47 seconds Finished converging <default-centos-72> (3m18.96s). -----> Setting up <default-centos-72>... Finished setting up <default-centos-72> (0m0.00s). -----> Verifying <default-centos-72>... Preparing files for transfer Transferring files to <default-centos-72> Finished verifying <default-centos-72> (0m0.00s). -----> Destroying <default-centos-72>... ==> default: Stopping the VMware VM... ==> default: Deleting the VM... Vagrant instance <default-centos-72> destroyed. Finished destroying <default-centos-72> (0m28.38s). Finished testing <default-centos-72> (4m48.86s). -----> Kitchen is finished. (4m50.01s)
What happened here is the following:
.kitchen.yml
filerun_list
contentWhen we execute the simple kitchen test
command, we are in fact running through five steps:
kitchen create
: This creates the virtual testing environment (in our case, through Vagrant and an hypervisor), but does not provision it.kitchen converge
: This provisions the instance with the suite information from the .kitchen.yml
we created. As we're using Test Kitchen with Chef, it starts by installing Chef and then resolves cookbook dependencies for us. Then it applies run_list
with the requested Chef mode (chef-zero in our case).kitchen setup
: This installs any additional plugin we might need.kitchen verify
: This first installs everything needed to run the tests—in our case, this will be ServerSpec.kitchen destroy
: If all tests pass, this step destroys the testing environment.We highly recommend that you use each command sequentially for debugging purposes.
For reference, as this will all be discussed in the next section, all tests are located in the test/integration/<suite_name>/<plugin_name>
folder. In other words, the test/integration/default/serverspec/virtualhost_spec.rb
file will match the Chef cookbook recipe named virtualhost
, executed from the default
Kitchen test suite, and tested with the serverspec
plugin.
The counterpart for Puppet is Beaker. The development of Beaker is very active, and the current version (6.x) needs at least Ruby 2.2.5. In order to use the Embedded Ruby provided by Puppet Collections, let's stay on the 5.x branch:
$ sudo puppet resource package beaker-rspec provider=puppet_gem ensure=5.6.0
We also need another gem containing helpers: beaker-puppet_install_helper
. This gem is mainly used to install Puppet in boxes during tests:
$ sudo puppet resource package beaker-puppet_install_helper provider=puppet_gem
We first need to define a list of supported platforms for running test acceptances. Each platform must be defined in a YAML file in spec/acceptance/nodesets
. Since our code only works on Ubuntu, let's define a single platform in spec/acceptance/nodesets/default.yml
:
HOSTS: ubuntu-1604-x64: roles: - agent - default platform: ubuntu-16.04-amd64 hypervisor: vagrant box: bento/ubuntu-16.04 CONFIG: type: foss
As you can see, we will use Vagrant as hypervisor, with an Ubuntu Xenial box.
Now we can run Beaker:
$ rake beaker /opt/puppetlabs/puppet/bin/ruby -I/opt/puppetlabs/puppet/lib/ruby/gems/2.1.0/gems/rspec-support-3.6.0.beta1/lib:/opt/puppetlabs/puppet/lib/ruby/gems/2.1.0/gems/rspec-core-3.6.0.beta1/lib /opt/puppetlabs/puppet/lib/ruby/gems/2.1.0/gems/rspec-core-3.6.0.beta1/exe/rspec --pattern spec/acceptance --color No examples found. Finished in 0.00081 seconds (files took 0.14125 seconds to load) 0 examples, 0 failures
No acceptance test has been defined yet, but we will see how to write one in the next pages.
3.145.12.3