How can I write a unit test for a Chef provider?
So far, our unit testing strategy uses ChefSpec for recipes, and we stuff most of the interesting logic for our providers in libraries to make the logic more testable. However, we still run into issues where our providers are calling other resources (among other simple logic issues). For example:
action :run do
helper = Helper.new
template '/etc/hosts' do
source 'hosts.erb'
variables ({
"host" => @new_resource.host,
"ip_address" => node['ipaddress']
})
only_if { helper.update_hosts }
end
service 'httpd' do
action :restart
end
end
(this is not real code, just a trivial example)
What we'd like to do is test this provider in isolation to check for logic errors. ChefSpec has the capability of stepping into an LWRP, but it looks like that would force us to put the LWRP into a recipe, and many of our cookbooks are basically LWRP libraries with no recipes. We'd also just like to keep a clean separation in our tests, so it's obvious what component failed by looking at the file name.
Additionally, it would be nice if the test would automatically fail if there are any syntax errors in the LWRP definition. For example:
action :run do
template '/etc/hosts/' do
source_whoops 'hosts.erb'
action :whoops
end
end
It would be really nice if the above statement would cause the test to fail due to the attribute name being defined incorrectly, and the action name not existing (just like ChefSpec).
The only solution I've come up with is to basically create a "test cookbook" - a separate cookbook that defines each LWRP 1:1 with a single recipe, so ChefSpec can step into it that way. It seems like a reasonable, but less than ideal solution.
Unit testing ensures that all code meets quality standards before it's deployed. This ensures a reliable engineering environment where quality is paramount. Over the course of the product development life cycle, unit testing saves time and money, and helps developers write better code, more efficiently.
Test Kitchen is Chef's integrated testing framework. It enables writing test recipes, which will run on the VMs once they are instantiated and converged using the cookbook. The test recipes run on that VM and can verify if everything works as expected. ChefSpec is something which only simulates a Chef run.
ChefSpec is a unit testing framework for testing Chef cookbooks. ChefSpec makes it easy to write examples and get fast feedback on cookbook changes without the need for virtual machines or cloud servers. ChefSpec runs your cookbooks locally while skipping making actual changes.
Looks like there is a (very recent) solution to this.
First, this pull request would basically do what I'm asking, although it has been rejected by the ChefSpec maintainer for understandable reasons.
The maintainer suggests to use a mycookbook_test pattern - a separate cookbook keeps all the unit tests. This would allow a simple 1 recipe-per-lwrp approach.
Additionally, this approach keeps the cookbook clear of any unit tests, which is nice for consumers of the cookbook. Consumers may want to run their own unit tests, and there's no need (or desire) to run tests on third party cookbooks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With