Puppet rspec testing: understanding describe and context

December 6, 2019 

In the Puppet module rspec testing with PDK blog post I covered the procedure of creating and running puppet-rspec tests with PDK. This blog post will go more in-depth to that topic, in particular describe and context which you see in all puppet-rspec tests.

When looking at the puppet-rspec test syntax the first time it looks very "rubyesque". Somebody used to staring at Python code, for example, could call the syntax "odd" or "1337". Fortunately reading the Ruby rspec documentation helps understand what is going on under the hood and thus making the spec files look less magical. In my case rspec documentation helped understand how contexts work. In the previous blog post a context was created for every supported operating system listed in metadata, and rspec tests were run for each of them by using facts from facterdb.

describe 'sshd' do
  on_supported_os.each do |os, os_facts|
    context "on #{os}" do
    --- snip ---

As shown above, multiple contexts allow you to easily test compiling the same Puppet code (e.g. a class) on multiple platforms with a simple loop.

Another, less mechanical and more targeted use-case it to manual define a set of base parameters which you override as needed in nested contexts. This latter approach is visualized well in this example from rspec-puppet class testing documentation:

describe 'My::Class' do
  let(:params) do
      'some_common_param' => 'value',
      'ensure'            => 'present',

  context 'with ensure => absent' do
    let(:params) do
      super().merge({ 'ensure' => 'absent' })
    it { should compile }

What happens there is that the default value, "ensure => present", gets overridden in the nested context with "ensure => absent". The defaults can be facts, parameters, node name, environment, among other things. Please refer to the excellent rspec-puppet documentation for further details.

More on Puppet testing:

Samuli Seppänen
Samuli Seppänen
Author archive