Tests for defined types should be placed in files under spec/defines/
. For
example the tests for apache::vhost
should be in
spec/defines/apache_vhost_spec.rb
.
As when using a defined type, when testing a defined type it must have a title.
This can be specified using let(:title)
.
If the object being tested takes parameters, these can be specified as a hash
of values using let(:params)
.
When passing undef
as a parameter value, it should be passed as the symbol
:undef
.
When passing a reference to a resource (e.g. Package['apache2']
), it should
be passed as a call to the ref
helper (ref(<resource type>, <resource
title>)
)
If have nested RSpec contexts to test the behaviour of different parameter
values, you can partially override the parameters by merging the changed
parameters into super()
in your let(:params)
block.
If the object being tested depends upon the node having a certain name, it
can be specified using let(:node)
.
If the manifest being tested expects to evaluate the environment name, it can
be specified using let(:environment)
.
Node parameters (or top-scope variables) such as would be provided by an ENC
can be specified as a hash of values using let(:node_params)
.
These node parameters will be merged into the default node parameters (if set), with these values taking precedence over the default node parameters in the event of a conflict.
If have nested RSpec contexts to test the behaviour of different node parameter
values, you can partially override the node parameters by merging the changed
parameters into super()
in your let(:node_params)
block.
If the manifest being tested relies on some existing state (another class being
included, variables to be set, etc), this can be specified using
let(:pre_condition)
.
The value may be a string or an array of strings that will be concatenated, and then be evaluated before the manifest being tested.
If the manifest being tested depends on being evaluated before another
manifest, this can be specified using let(:post_condition)
.
The value may be a string or an array of strings that will be concatenated, and then be evaluated after the manifest being tested.
By default, the test environment contains only the hostname
, domain
, and
fqdn
facts (determined by the FQDN of the test node). Additional facts can be
specified as a hash of values using let(:facts)
.
Facts may be expressed as a value (shown in the previous example) or a structure. Fact keys may be expressed as symbols or strings, and will be converted to a lower case string to align with the Facter standard.
These facts will be merged into the default facts (if set), with these values taking precedence over the default fact values in the event of a conflict.
If have nested RSpec contexts to test the behaviour of different fact
values, you can partially override the parent facts by merging the changed
facts into super()
in your let(:facts)
block.
When testing with Puppet >= 4.3, the trusted facts hash will have the standard
trusted facts (certname
, domain
, and hostname
) populated based on the
node name. Those elements can only be set with the let(:node)
, not with this
structure.
By default, the test environment contains no custom trusted facts (usually
obtained from certificate extensions) and found in the extensions
key. If the
manifest being tested depends on the values from specific custom certificate
extensions, they can be specified as a hash using let(:trusted_facts)
.
These trusted facts will be merged into the default trusted facts (if set), with these values taking precedence over the default trusted facts in the event of a conflict.
If have nested RSpec contexts to test the behaviour of different trusted fact
values, you can partially override the parent trusted facts by merging the
changed facts into super()
in your let(:trusted_facts)
block.
This is the most basic test that can be done on a manifest. It will test that the manifest can be compiled into a catalogue, and that the catalogue has no dependency cycles between resources.
This matcher has an optional method that can be chained onto it in order to
have rspec-puppet test that all relationships in the catalogue (as defined with
require
, notify
, subscribe
, before
, or the chaining arrows) resolve to
resources in the catalogue.
When testing for an expected error (e.g. testing the behaviour of input
validation), the and_raise_error
method should be chained onto the compile
matcher.
The presence of a resource in the catalogue can be tested using the generic
contain_<resource type>
matcher.
If the <resource type>
includes ::
(e.g. the apache::vhost
defined type),
you must replace the ::
with __
(two underscores) in the matcher name.
This can also be used to test if a class has been included in the catalogue.
foo::bar
will only be
matched by foo::bar
, not by ::foo::bar
or bar
alone.
The values of a resource’s parameters can be tested by chaining
with_<parameter name>(<value>)
methods onto the contain_<resource type>
matcher.
While you can chain multiple with_<parameter name>
methods together, it may
be cleaner for a large number of parameters to instead to chain the with
method
and pass a hash of expected parameters and values instead.
Testing parameters using with_<parameter name>
or with
will not take into
account any other parameters that might be set on the resource. In order to
test that only the specificied parameters have been set on a resource, the
only_with_<parameter name>
method can be chained onto the
contain_<resource type>
matcher.
Similarly to with_<parameter name>
, there exists a way to specify multiple
parameters at once, by chaining only_with
onto the contain_<resource type>
matcher and passing it a hash of expected parameters and values.
Lastly, there are situations where it is necessary to test that certain
parameters have not been set on a resource. This can be done by chaining
without_<parameter name>
methods onto the contain_<resource type>
matcher.
As with the other parameter methods, there is a way to specify multiple
undefined parameters at once by chaining the without
method to the
contain_<resource type>
matcher and passing it an array of parameter names.
It can be tested that a Sensitive value of resource parameter passed to template is present as expected.
Use the have_unique_values_for_all
matcher to test a specific resource parameter
for uniqueness of values across the entire catalogue:
The relationships between resources can be tested using the following methods,
regardless of how the relationship has been defined. This mean that it doesn’t
matter if it was defined using the relationship metaparameters (require
,
before
, notify
, subscribe
) or the chaining arrows (->
, <-
, ~>
,
<~
).
Package[apache]
instead of Package['apache']
)[Package[apache], Package[htpasswd]]
instead of Package[apache, htpasswd]
)::
(Class[apache::service]
instead of Class[::apache::service]
)An array can be passed if the resource has the same type of relationship to multiple resources.
The relationships can be tested in either direction, so given the following manifest:
It can be tested that Notify[b]
comes before Notify[a]
Or that Notify[a]
requires Notify[b]
The total number of resources in the catalogue can be tested with the
have_resource_count
matcher.
The total number of classes in the catalogue can be tested with the
have_class_count
matcher.
The number of resources of a specific type can be tested using the generic
have_<resource type>_resource_count
matcher.
As with the generic contain_<resource type>
matcher, this matcher can also be
used for defined types that contain ::
in their name by replacing the ::
with __
(two underscores).