Table of contents

The GDS Way and its content is intended for internal use by the GDS community.

RSpec coding style


What do we use RSpec for?

We use RSpec to write both unit and integration tests for Ruby code.

Why RSpec?

RSpec is the most popular test framework for Ruby, and is recommended for Rails.

This explains why we use RSpec for our unit tests. For integration tests, there is another popular alternative to RSpec, and that is Cucumber.

Many GOV.UK applications have some or all of their integration tests written in Cucumber. However, we are gradually moving away from Cucumber in favour of using RSpec, for reasons outlined in this article: How we write readable feature tests with RSpec.

Essentially, using RSpec for both BDD and TDD requires less of a context switch than using a separate tool for BDD.

How to configure RSpec

We should try to avoid the pollution of the global namespace that came with earlier versions of RSpec. For example, we should be using RSpec.describe instead of describe.

This can be enforced by setting config.expose_dsl_globally = false in your test setup. Read Global namespace DSL for more information.

Example unit test

This example is taken from finder-frontend:

RSpec.describe ContentItem do
  subject { }
  let(:base_path) { "/search/news-and-communications" }
  let(:finder_content_item) { news_and_communications }
  let(:news_and_communications) {
    JSON.parse("features", "fixtures", "news_and_communications.json")))

  RSpec.describe "as_hash" do
    it "returns a content item as a hash" do
      expect(subject.as_hash).to eql(finder_content_item)

Example integration test

This example is taken from publishing-e2e-tests:

# Some methods and variables have been removed here for brevity, but you get the idea.

RSpec.feature "Publishing a parent and child topic on Collections Publisher" do
  let(:parent_title) { unique_title }
  let(:child_title) { unique_title }

  RSpec.scenario "Publishing a parent and child topic" do


  def signin_to_signon
    signin_with_next_user("Collections Publisher" => ["GDS Editor"])

  def then_i_can_view_both_on_gov_uk
    expect(page).to have_content(child_title)

    first(:link, parent_title).click
    expect(current_url).to end_with(parent_slug)
This page was last reviewed on 9 May 2019. It needs to be reviewed again on 9 November 2019 by the page owner #gds-way .
This page was set to be reviewed before 9 November 2019 by the page owner #gds-way. This might mean the content is out of date.