Chapter 12. RSpec - 2. Commonly used gems and their usage

This chapter explains frequently used gems for RSpec.

  • Capybara For system spec
  • Selenium For testing Javascripts in system spec
  • Webmock For mocking external HTTP Communications
  • VCR For using Webmock easily

Capybara

Github - capybara

It is for a system spec, and seems to be a standard since Rails 5.1.

How to use

  • In request spec, check response after a request such as get, but
  • Insystem spec (Capybara), check page variable after a visit.
    • After visit, use fill_in, click_on, etc. to operate the screen.

Github - capybara#using-capybara-with-rspec

Capybara does not wait for ajax responses, so you need to detect DOM changes using loop etc.

Aliases

The following aliases can also be used in Capybara

  • background instead of before.
  • scenario instead of it.
  • given/given! instead of let/let!.

These are aliases work the same. These seem to be prepared for more natural English grammar, but either is fine. It would be pointless if the different writing styles made it difficult to read, so it might be a good idea to set a policy with the team.

Selenium

Github - selenium

The gem selenium-webdriver enables Javascripts for system spec, and it seems to be standard since Rails 5.1 as well as Capybara.

Since capybara does not include a Javascript driver, so Javascripts will not work without it, so this is necessary if you want to use system specs with Javascripts.

Multi-browser/device support

Also, selenium seems to handle multiple browsers and devices well, allowing for multi-threaded testing.

I have not used such a feature, but if you are working on a multi-platform game project and want to build a robust test, it might be good to remember that you can do such a thing.

Competitors

There are a few competitors, but selenium is the only one with the most information, and the others would only be used only if there was a reason.

  • cuprite A relatively new gem. There is not much information and I did not see any particular advantage in choosing it one for now.
  • poltergeist, capybara-webkit Both are now deprecated.

Webmock

Github - webmock

A gem that replaces the result of external HTTP responses with a dummy.

It is also possible to generate an error message when external HTTP requests are detected. This is a highly recommended feature.

Competitors

There are RR and MiniTest::Mock, but I choose this one because VCR's dependency is webmock, and I am not familiar with the others.

How to use

  • First arg is a target HTTP method or any means all methods.
  • Second arg is a target URL, which can be a regular expression or a string.
  • Use to_return to specify the return value, or use with to specify the body and headers in the case of post.
before
  # Prevents all requests
  stub_request(:any, /www.example.com/)

  # Replace GET with `users_json`.
  stub_request(:get, /www.example.com?param=1/).to_return(users_json)

  # Replace POST with some informations.
  stub_request(:post, /www.example.com/).
    with(body: /world$/, headers: {"Content-Type" => /image\/. +/}).
    to_return(body: "abc")
end

Github - webmock#stubbing

VCR

Github - vcr

It can easily use Webmock and depends on it.

Webmock needs to know the request details (such as URL, HTTP method, parameters, and others) and prepare the return value. On the other hand, VCR can simply be used to enclose in its method block where there is the request.

It is not exclusive to system spec, so it can also be used in request spec.

How to use

When enclosed in a VCR block, the behavior is as follows.

  • The first time, the request is executed and recorded as a yml in spec/vcr
  • The second time, that yml information is used and the request is skipped.

So when using VCR, commit the yml at the same time.

it do
  VCR.use_cassette 'cassette_name' do
    # HTTP request
  end
end

If the implementations have changed, delete the yml and run it again, then the request will run again and the yml will be created.

There are many articles explaining how to use this system, so I will skip the detailed explanation here.