RSpec Shared Examples and Shared Context

Ben Dunjay
3 min readNov 9, 2021

--

Slowly developing your knowledge in software engineering should be a methodical process. Learning to refactor and DRY out your code is one of those processes where the more knowledge you have the easier it becomes.

Shared examples and shared context will allow you to keep your specs DRY, even when the code base is growing. We use shared examples / context when we find multiple spec files with the specs testing the same behaviour. The idea is you have one spec file, that can be referenced in any other spec file and acts like copying and pasting the tests from the shared example / context file into the current spec you are working on. You should try to make sure the shared example/context name gives a general description of what it is testing and you must make sure the file is loaded prior to the rest of the specs, if it is loaded after the other spec files then all spec files referencing the shared example/context file will fail. Check out Relish for ways to achieve this.

So, when do we use shared example/context? Well, firstly there are two different types of shared example methods:

  • Include_examples
  • It_behaves_like / it_should_behave_like

Include examples is the most basic and generic form of a shared example. It does exactly what we talked about above. It extracts the same behaviour from multiple spec files and contains it in one spec file to be referenced by all these files instead. This gives us three benefits:

  • No code repetition
  • Less engineering time spent on testing similar behaviour
  • But most importantly, it allows us to test for consistency across our code base.

The last bullet point is probably the most important. Imagine we have referenced the shared example in 10 different class specs. These class specs all have a method testing for the same behaviour. We then write an 11th class which has a method that creates the same output. This means in our specs, we can simply reference the shared examples file and voila. We are testing the same behaviour as all the other classes.

However, if you are passing parameters to your shared example then you may want to consider using it_behaves_like / it_should_behave_like. These deal with nested examples and display the tests more clearly when running the specs. RSpec will throw a warning when using parameters and include_examples, by simply switching the name it should work. This is well documented in Relish. Using the same shared_example in the same spec context with different parameters will create a let declaration clash, where one will overwrite the other. So when the tests are output you will not be testing both parameters correctly.

Shared context is just another level of usability. With shared context you can create instance variables, let blocks and methods in the shared context file which can then be called and manipulated wherever the shared context file is referenced.

Coming from a coding BootCamp this was one of the first things I noticed when starting my new job. The ability to DRY out code is a key skill and will reflect well in any interview. Less code, with same readability and behaviour is a win all round.

The links below have good examples. I would suggest trying something relatively simple first.

https://medium.com/@allegranzia/rspec-ruby-testing-shared-examples-and-shared-context-1d5991336d53

--

--