Running rspec-puppet tests with granularity

When working on your puppet code, you’re going to want to run rspec against your tests on a regular basis. There are a few quirks to this process that we should cover quickly.

“Normal” Usage

Let’s start with a simple test of everything. You can do this with bundle exec rake spec (or the test target, which includes spec plus some other targets). That would look something like this (note: be is an alias for bundle exec):

$ be rake spec
Cloning into 'spec/fixtures/modules/stdlib'...
remote: Counting objects: 449, done.
remote: Compressing objects: 100% (302/302), done.
remote: Total 449 (delta 143), reused 378 (delta 131), pack-reused 0
Receiving objects: 100% (449/449), 198.99 KiB | 0 bytes/s, done.
Resolving deltas: 100% (143/143), done.
/usr/bin/ruby -I/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/lib:/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-support-3.1.2/lib /home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration,types\}/\*\*/\*_spec.rb --color
/home/rnelson0/modules/local_user/spec/spec_helper.rb:12:in `block in <top (required)>': [DEPRECATION] ::[] is deprecated. Use ::new instead.

local_user
  using minimum params
    should contain User[rnelson0] with comment => "rnelson0", shell => "/bin/bash", home => "/home/rnelson0", groups => ["group1", "group2"] and password_max_age => 90
    should not contain Group[rnelson0]
    should contain Exec[set rnelson0's password]
  managing all groups
    should contain User[rnelson0] with comment => "Rob Nelson" and groups => ["group1", "group2"]
    should contain Group[rnelson0]
    should contain Group[group1]
    should contain Group[group2]
  managing gid only
    should contain User[rnelson0] with comment => "Rob Nelson" and groups => ["group1", "group2"]
    should contain Group[rnelson0]
    should not contain Group[group1]
    should not contain Group[group2]
  set manage_groups to false
    should contain User[rnelson0] with comment => "rnelson0", groups => ["group1", "group2"] and password_max_age => 90
    should not contain Group[rnelson0]
    should not contain Group[group1]
    should not contain Group[group2]
  manage_groups with invalid input
    should raise Puppet::Error
  using full params
    should contain User[rnelson0] with comment => "Rob Nelson", shell => "/bin/zsh", home => "/nfshome/rnelson0", groups => ["group1", "group2"], password_max_age => 120 and uid => 101
    should contain Local_user::Ssh_authorized_keys[ssh-rsa AAAA...zwE1 rsa-key-20141029]
    should not contain Group[rnelson0]
  with a valid date for last_change
    should contain User[rnelson0]
    should not contain Group[rnelson0]
  with an invalid date for last_change
    should raise Puppet::Error

local_user::ssh_authorized_keys
  default
    should contain Ssh_authorized_key[rnelson0_ssh-rsa_rsa-key-20141029] with user => "rnelson0", type => "ssh-rsa", key => "AAAA...zwE1" and name => "rsa-key-20141029"

local_user::windows
  with defaults
    should contain User[rnelson0] with comment => "rnelson0", groups => ["Remote Desktop Users"] and password => "Microsoft1"
  with allow_rdp => false, admin => false, no groups
    should contain User[rnelson0] with comment => "rnelson0", groups => [] and password => "Microsoft1"
  with allow_rdp => true, admin => true, no groups
    should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators", "Remote Desktop Users"] and password => "Microsoft1"
  with allow_rdp => false, admin > true, no groups
    should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators"] and password => "Microsoft1"
  with allow_rdp => false, admin => true, rnelson0 group
    should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators"] and password => "Microsoft1"
  with allow_rdp => true, admin => true, rnelson0 group
    should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators", "Remote Desktop Users"] and password => "Microsoft1"
  with allow_rdp => false, admin => true, rnelson0 group
    should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0"] and password => "Microsoft1"
  fail on non-windows systems
    should fail to compile and raise an error matching /Windows support only!/

Finished in 1.69 seconds (files took 1.03 seconds to load)
31 examples, 0 failures
Coverage report generated for RSpec to /home/rnelson0/modules/local_user/coverage. 0.0 / 0.0 LOC (100.0%) covered.

COVERAGE: 100.00% -- 0.0/0.0 lines in 0 files


Total resources:   7
Touched resources: 7
Resource coverage: 100.00%

Awesome, everything passed.

How It Works

Take a look at the top of the output and you’ll see a git clone happening. If you run rake against the same target, you’ll see that happen every time. Take a look at the rake targets to see why:

$ be rake -T | grep spec
rake check:git_ignore                        # Fails if directories contain the files specified in .gitignore
rake module:dependency[module_name,version]  # Set specific module dependency version
rake spec                                    # Run spec tests in a clean fixtures directory
rake spec_clean                              # Clean up the fixtures directory
rake spec_prep                               # Create the fixtures directory
rake spec_standalone                         # Run spec tests on an existing fixtures directory
rake test                                    # Run syntax, lint, and spec tests

The spec target says it runs in a clean fixtures directory. It achieves this by running the next three targets in series: spec_clean to wipe out the fixtures directory, It has been pointed out to me that this description is misleading. The target assumes that the fixtures directory is clean. It runs the targets spec_prep to create the fixtures (where git repos are cloned and forge modules are downloaded per .fixtures.yml). If any fixtures exist, the spec_prep target will skip those fixtures. Next, it runs the target spec_standalone, which actually runs the tests. If spec_standalone is successful (exit code 0), it then runs spec_clean again. This means that when your tests fail, the fixtures are left alone. We can do test out these steps ourselves pretty easily:

$ be rake spec_clean
$ be rake spec_prep
Cloning into 'spec/fixtures/modules/stdlib'...
remote: Counting objects: 449, done.
remote: Compressing objects: 100% (302/302), done.
remote: Total 449 (delta 143), reused 378 (delta 131), pack-reused 0
Receiving objects: 100% (449/449), 198.99 KiB | 0 bytes/s, done.
Resolving deltas: 100% (143/143), done.
$ be rake spec_standalone
/usr/bin/ruby -I/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/lib:/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-support-3.1.2/lib /home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration,types\}/\*\*/\*_spec.rb --color
/home/rnelson0/modules/local_user/spec/spec_helper.rb:12:in `block in <top (required)>': [DEPRECATION] ::[] is deprecated. Use ::new instead.

local_user
  using minimum params
<snip>

Finished in 1.49 seconds (files took 1.04 seconds to load)
31 examples, 0 failures
Coverage report generated for RSpec to /home/rnelson0/modules/local_user/coverage. 0.0 / 0.0 LOC (100.0%) covered.

COVERAGE: 100.00% -- 0.0/0.0 lines in 0 files


Total resources:   7
Touched resources: 7
Resource coverage: 100.00%
$ echo $?
0
$ ls spec/fixtures/modules/
local_user  stdlib

Because we ran the steps individually, even though spec_standalone succeeded, the files are left behind unless we manually call spec_clean. If your module has a lot of dependencies, or you are working with your controlrepo’s profiles module, you may find that the spec_prep step takes a long time. If you are doing repeated tests, you may want to run bundle exec rake spec_prep once and then bundle exec rake spec_standalone as many times as you want. If you change a fixture or the fixture has been modified upstream, then run bundle exec rake spec_clean followed by spec_prep so that you have the latest version of the correct fixtures.

Individual Tests

You may also desire to run rspec against an individual test file, or a group of files smaller than the entire set. You can do this by skipping rake targets and using rspec <filename|glob>. You will still need to run rake spec_prep first, however, so that the fixtures are present. For example:

$ be rake spec_prep
Cloning into 'spec/fixtures/modules/stdlib'...
remote: Counting objects: 449, done.
remote: Compressing objects: 100% (302/302), done.
remote: Total 449 (delta 143), reused 378 (delta 131), pack-reused 0
Receiving objects: 100% (449/449), 198.99 KiB | 0 bytes/s, done.
Resolving deltas: 100% (143/143), done.
$ be rspec spec/defines/windows_spec.rb

local_user::windows
 with defaults
 should contain User[rnelson0] with comment => "rnelson0", groups => ["Remote Desktop Users"] and password => "Microsoft1"
 with allow_rdp => false, admin => false, no groups
 should contain User[rnelson0] with comment => "rnelson0", groups => [] and password => "Microsoft1"
 with allow_rdp => true, admin => true, no groups
 should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators", "Remote Desktop Users"] and password => "Microsoft1"
 with allow_rdp => false, admin > true, no groups
 should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators"] and password => "Microsoft1"
 with allow_rdp => false, admin => true, rnelson0 group
 should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators"] and password => "Microsoft1"
 with allow_rdp => true, admin => true, rnelson0 group
 should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators", "Remote Desktop Users"] and password => "Microsoft1"
 with allow_rdp => false, admin => true, rnelson0 group
 should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0"] and password => "Microsoft1"
 fail on non-windows systems
 should fail to compile and raise an error matching /Windows support only!/

Finished in 0.8302 seconds (files took 1.02 seconds to load)
 8 examples, 0 failures
 Coverage report generated for RSpec to /home/rnelson0/modules/local_user/coverage. 0.0 / 0.0 LOC (100.0%) covered.

COVERAGE: 100.00% -- 0.0/0.0 lines in 0 files

Cleanup

As mentioned above, the fixtures file or the fixtures themselves change over time. When you’re using a CI pipeline that starts with a fresh environment, you won’t have to worry about cleaning anything up, but if you’re running tests on a local node in your home directory, it’s possible for the fixtures to get stale. You may also change between two branches where the fixtures are different. Be sure to clean up after such work, or when you haven’t used the local repo in a while, so that you get new fixtures, with bundle exec rake spec_clean. You can also remove individual modules from the fixtures directory, if you do not want to disturb other modules, by simply removing the module directory:

$ rm -fR spec/fixtures/modules/stdlib/
$ be rake spec_prep
Cloning into 'spec/fixtures/modules/stdlib'...
remote: Counting objects: 449, done.
remote: Compressing objects: 100% (302/302), done.
remote: Total 449 (delta 143), reused 378 (delta 131), pack-reused 0
Receiving objects: 100% (449/449), 198.99 KiB | 0 bytes/s, done.
Resolving deltas: 100% (143/143), done.

Troubleshooting

During this process, you’ll inevitably forget to spec_prep before you spec_standalone. That will look like this:

$ be rake spec_clean
$ be rake spec_standalone
/usr/bin/ruby -I/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/lib:/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-support-3.1.2/lib /home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration,types\}/\*\*/\*_spec.rb --color

local_user
  using minimum params
    should contain User[rnelson0] with comment => "rnelson0", shell => "/bin/bash", home => "/home/rnelson0", groups => ["group1", "group2"] and password_max_age => 90 (FAILED - 1)
    should not contain Group[rnelson0] (FAILED - 2)
    should contain Exec[set rnelson0's password] (FAILED - 3)
  managing all groups
    should contain User[rnelson0] with comment => "Rob Nelson" and groups => ["group1", "group2"] (FAILED - 4)
    should contain Group[rnelson0] (FAILED - 5)
    should contain Group[group1] (FAILED - 6)
    should contain Group[group2] (FAILED - 7)
  managing gid only
    should contain User[rnelson0] with comment => "Rob Nelson" and groups => ["group1", "group2"] (FAILED - 8)
    should contain Group[rnelson0] (FAILED - 9)
    should not contain Group[group1] (FAILED - 10)
    should not contain Group[group2] (FAILED - 11)
  set manage_groups to false
    should contain User[rnelson0] with comment => "rnelson0", groups => ["group1", "group2"] and password_max_age => 90 (FAILED - 12)
    should not contain Group[rnelson0] (FAILED - 13)
    should not contain Group[group1] (FAILED - 14)
    should not contain Group[group2] (FAILED - 15)
  manage_groups with invalid input
    should raise Puppet::Error
  using full params
    should contain User[rnelson0] with comment => "Rob Nelson", shell => "/bin/zsh", home => "/nfshome/rnelson0", groups => ["group1", "group2"], password_max_age => 120 and uid => 101 (FAILED - 16)
    should contain Local_user::Ssh_authorized_keys[ssh-rsa AAAA...zwE1 rsa-key-20141029] (FAILED - 17)
    should not contain Group[rnelson0] (FAILED - 18)
  with a valid date for last_change
    should contain User[rnelson0] (FAILED - 19)
    should not contain Group[rnelson0] (FAILED - 20)
  with an invalid date for last_change
    should raise Puppet::Error

local_user::ssh_authorized_keys
  default
    should contain Ssh_authorized_key[rnelson0_ssh-rsa_rsa-key-20141029] with user => "rnelson0", type => "ssh-rsa", key => "AAAA...zwE1" and name => "rsa-key-20141029" (FAILED - 21)

local_user::windows
  with defaults
    should contain User[rnelson0] with comment => "rnelson0", groups => ["Remote Desktop Users"] and password => "Microsoft1" (FAILED - 22)
  with allow_rdp => false, admin => false, no groups
    should contain User[rnelson0] with comment => "rnelson0", groups => [] and password => "Microsoft1" (FAILED - 23)
  with allow_rdp => true, admin => true, no groups
    should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators", "Remote Desktop Users"] and password => "Microsoft1" (FAILED - 24)
  with allow_rdp => false, admin > true, no groups
    should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators"] and password => "Microsoft1" (FAILED - 25)
  with allow_rdp => false, admin => true, rnelson0 group
    should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators"] and password => "Microsoft1" (FAILED - 26)
  with allow_rdp => true, admin => true, rnelson0 group
    should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators", "Remote Desktop Users"] and password => "Microsoft1" (FAILED - 27)
  with allow_rdp => false, admin => true, rnelson0 group
    should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0"] and password => "Microsoft1" (FAILED - 28)
  fail on non-windows systems
    should fail to compile and raise an error matching /Windows support only!/ (FAILED - 29)

Failures:

  1) local_user using minimum params should contain User[rnelson0] with comment => "rnelson0", shell => "/bin/bash", home => "/home/rnelson0", groups => ["group1", "group2"] and password_max_age => 90
     Failure/Error: it { is_expected.to create_user('rnelson0').with({
     Puppet::PreformattedError:
       Evaluation Error: Error while evaluating a Resource Statement, Invalid resource type local_user at line 1:1 on node build03.nelson.va
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/resource.rb:266:in `initialize'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/resource.rb:123:in `initialize'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/runtime3_support.rb:329:in `new'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/runtime3_support.rb:329:in `block in create_resources'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/runtime3_support.rb:328:in `map'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/runtime3_support.rb:328:in `create_resources'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:763:in `block in eval_ResourceExpression'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:760:in `map'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:760:in `eval_ResourceExpression'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:46:in `block in visit_this'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:42:in `each'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:42:in `visit_this'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:69:in `visit_this_1'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:73:in `evaluate'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:644:in `eval_Program'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:46:in `block in visit_this'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:42:in `each'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:42:in `visit_this'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:69:in `visit_this_1'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:73:in `evaluate'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/parser/evaluating_parser.rb:57:in `evaluate'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/ast/pops_bridge.rb:111:in `evaluate'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/ast.rb:31:in `safeevaluate'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/resource/type.rb:185:in `evaluate_code'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/resource.rb:84:in `block in evaluate'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler/around_profiler.rb:58:in `profile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler.rb:51:in `profile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/resource.rb:76:in `evaluate'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/compiler.rb:638:in `evaluate_main'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/compiler.rb:180:in `block (2 levels) in compile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler/around_profiler.rb:58:in `profile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler.rb:51:in `profile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/compiler.rb:180:in `block in compile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/context.rb:65:in `override'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet.rb:240:in `override'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/compiler.rb:168:in `compile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/compiler.rb:36:in `compile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/indirector/catalog/compiler.rb:93:in `block (2 levels) in compile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler/around_profiler.rb:58:in `profile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler.rb:51:in `profile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/indirector/catalog/compiler.rb:91:in `block in compile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util.rb:129:in `block in benchmark'
     # /usr/share/ruby/benchmark.rb:296:in `realtime'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util.rb:128:in `benchmark'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/indirector/catalog/compiler.rb:90:in `compile'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/indirector/catalog/compiler.rb:50:in `find'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/indirector/indirection.rb:194:in `find'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:218:in `block in build_catalog_without_cache'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/context.rb:65:in `override'
     # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet.rb:240:in `override'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:216:in `build_catalog_without_cache'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:231:in `block in build_catalog'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/cache.rb:17:in `call'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/cache.rb:17:in `get'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:230:in `build_catalog'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:28:in `load_catalogue'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/example/define_example_group.rb:7:in `catalogue'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:8:in `block in subject'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/matchers/create_generic.rb:82:in `call'
     # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/matchers/create_generic.rb:82:in `matches?'
     # ./spec/defines/init_spec.rb:19:in `block (3 levels) in <top (required)>'

   <Repeat for every other test>

Finished in 0.69899 seconds (files took 1.03 seconds to load)
31 examples, 29 failures

Failed examples:

rspec ./spec/defines/init_spec.rb:19 # local_user using minimum params should contain User[rnelson0] with comment => ...
<Repeat for every other test>
COVERAGE: 100.00% -- 0.0/0.0 lines in 0 files


Total resources:   0
Touched resources: 0
Resource coverage:   NaN%
Untouched resources:


/usr/bin/ruby -I/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/lib:/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-support-3.1.2/lib /home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration,types\}/\*\*/\*_spec.rb --color failed

All the errors will be the same, and the error will vary based on the first resource referenced in a test file. If the first resource was include mymodule, the error would look something like:

error during compilation: Could not parse for environment rp_env: No file(s) found for import of '/home/rnelson0/modules/mymodule/spec/fixtures/manifests/site.pp' at line 3 on node build.nelson.va

Both merely indicate that you need to run bundle exec spec_prep and you’ll be fine.

2 thoughts on “Running rspec-puppet tests with granularity

  1. “The spec target says it runs in a clean fixtures directory. It achieves this by running the next three targets in series: spec_clean to wipe out the fixtures directory…”

    I’m not sure that this is accurate. Does spec really run spec_clean first? If I have failing tests and rerun spec, fixtures aren’t re-downloaded, (which they would have to be if spec_clean got run by spec as its first task).

    https://github.com/puppetlabs/puppetlabs_spec_helper/blob/master/lib/puppetlabs_spec_helper/rake_tasks.rb#L276

  2. I’ve been a fan of adding to my `spec_helper.rb`

    “`
    RSpec.configure do |config|
    config.filter_run focus: true
    config.run_all_when_everything_filtered = true
    end
    “`

    which allows me to add `:focus => true` to any context/define. `bundle exec rake spec` then just tests the blocks that are “focused”.

    “`
    context “ipa http ssl cert”, :focus => true do
    let(:params) { { :http_cert_provider => ‘ipa’ } }
    it do
    is_expected.to contain_apache__vhost(‘site-https’).with(
    :ssl => true,

    )
    end
    end
    “`

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s