Watch: Writing Great Unit Tests with ChefSpec
// Chef Blog
On March 23rd, I presented a live webinar on Writing Great Unit Tests. Watch the recording below to hear me explain how to write unit tests and how they apply to the domain of cookbook development. You'll see me demonstrate how to build cookbooks by using a test-driven approach. At the end of the presentation, you'll know when to apply unit tests, how to use the Chef DK tools effectively, and where you can go to improve your skills even more. At the end of this post, I've included some Q&A from the presentation.
Is there a good way to test resource notify and subscribe in ChefSpec?
Yes. Look at the examples in the ChefSpec documentation for:
None. When you write Chef you are really writing in the Domain Specific Language (DSL) built on top of Ruby. Pry is built for Ruby. What you will not have are perhaps some shortcuts that might find handy to use while debugging Chef code. If you found some then you could always codify them and turn them into a Pry plugin that you could release to the community.
What was the spec parameter to switch to documentation mode?
Here is all the documentation on RSpec's various flags and commands:
ChefSpec provides support for testing custom resources that you can implement.
No. All ChefSpec examples and expectations are in-memory. No actual state of the system changes. This is important to remember. Because it means that are isolated from external dependencies allowing you to execute tests and get fast feedback. That also means that you are isolated from external dependencies which means you really do not know if it work on the platform. That is why both unit testing and integration testing should be used together to verify the recipes you create.
After you've added the breakpoint, how can you "continue" running? Can you step through from there?
To continue debugging you can use the 'exit' command. This will continue through the execution until it reaches the next break point or end of execution. 'exit!' was the command that will halt the execution immediately and return you back to the shell.
Is there a chef command to create the scaffolding/dir structure for the spec/unit/ directory?
The 'chef' tool that is packaged with the Chef Development Kit (Chef DK) allows you to generate recipes. When you generate a recipe it will create the entire directory structure for you to store your unit tests.
I think SoloRunner would be a lot faster here … any reason for choosing ServerRunner vs SoloRunner?
I left the unit tests as they were generated by Chef. I am often working with a Chef Server so I also do not often feel the need to change it over. I have not tested the performance between the two but I imagine that you are probably right. I would love to read a blog post with some results.
When you used rspec command with the file path and ended with the line number (e.g. rspec spec/unit/recipes/install_spec.rb:21) does it run up to line 21 or just line 21?
It only executes the example found on line 21. Line 20 or 22 would have also worked to target that one example.
I've only ever done integration tests (serverspec). If I unit test all resources can I reduce my integration tests? I currently do everything as integration tests because that's all I knew prior to today.
Yes. That is personally what I would choose to do.
I personally use my integration tests to focus on the big things like does the service return the content that matters most to me. That means I often do not express things like: is this package installed; is this service running; etc. I leave those small things to my unit tests.
Is there anyway to create "libraries" of test? Resuse tests? or is that just wrong?
There are ways in which you can define tests and have them be re-usable. There are two ways build right into RSpec called 'Shared Examples' and 'Shared Context'. Take a look at those two topics:
Is there any atom integration for running chef spec from a keyboard shortcut or anything like that? Just to avoid having to switch between the editor and console constantly.
Atom provides a number of different plugins. This is one that I found right away that would do the job you are describing:
Shared via my feedly reader
Sent from my iPad