Rspec Cheat Sheet



Instantly share code notes and snippets. Go to capybaranodeactions and here it lists how you can attach a file check a checkbox choose a radio button click a button click a link click a link or a button fill in a text box field select a dropdown uncheck a checkbox or unselect a dropdown. RSpec is a mature, feature-packed testing framework, but the documentation can be difficult to navigate. The official documentation is written as a set of Cucumber tests within Relish. It’s very comprehensive, but also quite sparse, and Cucumber tests are kind of unnatural to read. RSpec Quick Reference 1. Rspec Cheat Sheet loads the file tested by the spec describe ClassName do require 'thing'. describe declares what is being tested and defines a context describe Thing do. Optionally, you can specify before do some code to run before each @thing = Thing.new example. RSpec.describe User, type:. Kotlin Collection Functions Cheat Sheet. Elye in Mobile App Development Publication. Flutter + Source Generation. Raef Mousheimish in Flutter Community. RSpec is a mature, feature-packed testing framework, but the documentation can be difficult to navigate. The official documentation is written as a set of Cucumber tests within Relish. It’s very comprehensive, but also quite sparse, and Cucumber tests are kind of unnatural to read.

When it comes to testing your Chef cookbooks, currently there seem to be two tools that build the standard in the Chef community: ChefSpec and Test Kitchen (with Serverspec, which is the third tool). Where Serverspec can be used for an outside-in testing approach for your infrastructure, ChefSpec is more like unit testing or input testing for your Chef cookbooks. In this blogpost I’ll try to provide some best practices and snippets for common use cases.

ChefSpec’s goal is to simulate a convergence run of Chef in-memory and test expected behavior against this in-memory results. Due to only converging the node in-memory, it provides fast feedback thus making an ideal test framework for a commit stage in a Continuous Integration pipeline for your cookbooks.

ChefSpec Setup

Let’s assume you have a cookbook structure like this:

In order to use ChefSpec in your cookbook, make sure to add it to your Gemfile

After you created your Gemfile, run bundle install to install all dependencies.

The spec_helper.rb configures the rspec framework and looks like this:

All you have to do to run ChefSpec is to go to the root of your cookbook and run rspec:

Writing your first Spec

Given the following recipe that you want to write a spec for:

here’s how this spec might look like:

In line 3 we open a describe block for the recipe under test (app_virtualbox::default). Line 7 simulates the Chef run - in memory, as I described before - and “overrides” a few node attributes that we’ll use in our specs later.

Line 14 shows how we can assert that resources have been invoked by our Chef run. The add_apt_package method is a so-called matcher, which is defined for every resource that ships with Chef in the ChefSpec framework (see the extensive example folder on Github for a complete list of default matchers and their usage). Additional matchers can either be defined in your own cookbooks or community cookbooks or can be added to your specs for those cookbooks, which do not define their own matchers as we’ll see later.

Rspec Cheat Sheet

Using the with method in line 114, you can further specify the attributes that you want the resource to be called with.

Running this spec, the output will look like this (given you use the parameters -f d -c when calling rspec):

“Advanced” Use Cases

Mocking Recipe Inclusion

Let’s say you have a recipe that includes two other recipes:

and you want to test whether your recipe includes the expected recipes (and only those), then you can use the following spec to do this:

Mocking Data Bags

If your recipe under test uses a data bag:

you can mock them as well:

Mocking Shell Commands (e.g. for not_if conditions)

Given you use a shell command in a not_if attribute in your resource:

and you want to stub this command to either return true or false in your spec, use this snippet:

Mocking File.exists? and IO.read

Let’s assume, you want to test a recipe like this:

Therefore, you have to figure out, how to mock a call to File.exists? and IO.read in order to mock out the behavior and check whether an exception is raised in the expected circumstances. You can do that with this before block:

Notifications to other resources

Let’s assume we have a service resource for the Apache server like this

and another resource that writes a configuration file, which should effect a restart of the Apache server

then you can use the following Chefspec test to check whether the notification happens:

Testing for raised exceptions during Chef run

Assume you have a recipe code like this:

Then you can check for the exception being raised in your Chef run using

Write Custom Matchers

If you are using a 3rd-party cookbook that does not provide a matcher for a resource defined within this cookbook, you can write your own matcher. Let’s say you have this resource in your recipe (it actually doesn’t provide a matcher!):

then you can write a matcher ssh_known_hosts_entry_matcher.rb file like this:

and include it in your spec_helper.rb like that:

If you have several matchers that you have to implement on your own, you might come up with a folder structure like this:

and you can use the following snippet in your spec_helper.rb to include those matchers:

Using ChefSpec with Berkshelf

In case you are using Berkshelf for cookbook dependency management, simply add the following line to your spec_helper.rb:

ChefSpec will then automatically resolve cookbook dependencies for you.

Test Coverage

The following snippet in your spec_helper.rb file will switch test coverage on:

In your rspec output you will then find something like this:

The .rspec File

You can add a file .rspec in your cookbook’s root directory that holds a default configuration for your rspec test runs:

this will result in a colored output with the decriptions in the describe and it blocks rendered as output on the shell.

Rake Helper Task

A simple Rake task can help you to run all ChefSpec tests in a subdirectory at once. Let’s assume that your coobooks are stored in a subfolder cookbooks:

Further Resources

RSpec hierarchy

example group > nested group > example > expectations

Example group

basic format for describe or context

Example

it 'a string, or a Class goes here' doend

Expectations

Example has four main parts

expect, an argument to expect, the method .to, and an argument to .toexpect(Car.colors).to match_array(c)

basic format for expectexpect(something).to(something)expect(something).not_to(something)

Describe string syntax

describe '.colors' do #for class methods use this syntaxdescribe '#full_name' do #for instance methods use this syntax

Basic Example format

Format with Documentation

add -f d to command for format documenation example: rspec spec/car_spec.rb -f d

Pending Tests

Rspec Cheat Sheet Pdf

Either omit the do end block or use pending inside the block

Skipping

Use xdescribe or xit or skip inside the block

Fundamentals

Cheat

One expectation per example because you will only see first failure

Matchers

Used as arguments to .to()Expectations are the statements, matchers provide the variety and complexity

Types

Equivalence matchers, Truthiness matchers, Numeric-comparison matchers, Collection matchers, Observation matchers, and each one allows us to different kinds of things

Equivalence

expect(x).to eq(1) #most common expect(x).to be 1 #same thing as above

Truthiness Matchers

expect(1 < 2).to be(true)expect('some string').to be_truthy #or be_falsy

Numeric Comparison Matchers

expect(100).to eq(100)expect(100).to be 100

Collection Matchers - Arrays, Hashes, Strings

arr = [1,2,3]expect(arr).to match_array([3,2,1]) #in any orderexpect(arr).to contain_exactly(3,2,1)

hash = {:city => 'Dallas', :state => 'TX'}expect(hash).to include(:city) expect(hash).to include(:city => 'Dallas')

Other Matchers

the Regular Expression matcher, the Object Type Matchers, Respond To Matcher, Attribute Matcher, and Satisfy Matcher.

Predicate Matchers - dynamically defined

arr.nil? or arr.odd? or arr.be_even? etcexpect(value).to be_nil / be_odd / be_even / be_integer etc.

useful for custom methods, with a ? such as

arr.visible?where visible is a function below....visible?(x) do ... end.to be_visible

Observation Matchers

Uses a block instead of an argumentexpect {}.to()

array = []expect { array << 1 }.to change(arr, :empty?).from(true).to(false)

another example

expect do bob.first_name = 'Robert' bob.last_name = 'Smith'end.to change(bob, :full_name).from('Bob Smith').to('Robert Smith')

Observe Output

Not really useful for Ruby on Railsexpect {}.to output.to_stdout

Complex Expectations

Complex Expectations uses and, or.and &.or |

Composing Matcher

Rspec Matchers Cheat Sheet

matchers that accept other matchers