If you have been following the rspec-puppet tutorial, it is likely that you setup your module testing using rspec-puppet-init
. While this works for single modules, you will require a different setup when testing multiple modules in a larger project.
In case you haven’t been using rvm and bundler, you should. rvm
manages multiple versions of ruby and this will go a long way for your project when you would like to test compatibility. bundler
is a dependency management software that makes environment consistent between development, testing and production. These will take more pain out of your setup. We will be using them in this demo. So go ahead and get your download started.
We will name our project rspec-puppet-demo
. We will create subdirectories and our target structure should look like the following:
$ tree rspec-puppet-demo rspec-puppet-demo/ ├── Gemfile ├── Rakefile ├── manifests │ └── site.pp ├── modules │ ├── foo │ │ ├── manifests │ │ │ └── init.pp │ │ └── spec │ │ └── classes │ │ └── foo_spec.rb │ └── bar | ├── manifests | | └── init.pp | └── spec │ └── classes │ └── bar_spec.rb └── spec ├── fixtures │ ├── manifests │ │ └── site.pp │ └── modules │ ├── foo │ | └── manifests -> ../../../../modules/foo/manifests │ └── bar │ └── manifests -> ../../../../modules/bar/manifests └── spec_helper.rb
Notice that modules foo
and bar
contain their own spec
directory. For brevity, only the classes
directory is shown here. Complex modules will require more tests, thus may need defines
, hosts
, and functions
.
Now, we would like to be able to run all module tests from project root, so we create the fixtures
directory in rspec-puppet-demo/spec
. There are two important things to note from rspec-puppet
docs, first, Puppet expects to be able to read a site.pp
file when running tests and that Puppet’s manifest autoloader requires fixtures
directory point to the module contents.
For the first to be true, we create an empty site.pp
file.
$ mkdir -p spec/fixtures/manifests $ touch spec/fixtures/manifests/site.pp
Next we create our symlinks. We start with the module foo
. The same commands will work on our module bar
.
$ mkdir -p spec/fixtures/modules/foo $ cd spec/fixtures/modules/foo $ ln -s ../../../../modules/foo/manifests
If you have a complex module you may need to create more symlinks. Typically, the following folders can be present under your modules directory: files
, lib
, modules
and templates
.
At this point, we need to configure our spec_helper.rb
file to locate our fixtures
directory. Our file will look like:
require 'rspec-puppet' fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures')) RSpec.configure do |c| c.module_path = File.join(fixture_path, 'modules') c.manifest_dir = File.join(fixture_path, 'manifests') end
Next, we configure our Rakefile
. Our objective is to be able to run our spec tests via rake
, and we tell rake
where our tests are located. Looking back at our directory structure, our tests are located at modules/*/spec/*/*_spec.rb
. Our Rakefile
would look like the following:
require 'rake' require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) do |t| t.pattern = 'modules/*/spec/*/*_spec.rb' end task :default => :spec
Finally, we configure bundler
and write our Gemfile
. The packages we need to run our tests will be specified here. It should look like:
source 'https://rubygems.org' gem 'puppet', :require => false gem 'rake', :require => false gem 'rspec-puppet', :require => false
Now, all there is to do is to run bundle install
which will download dependencies for us. And we are able to run tests with bundle exec rake
.