How to Pass a Variable to Your Specs

There may come a time when you need to pass an environment variable to your specs. For example, on one of my projects we had a services monitor running for every environment. We needed a way to run the same specs, but for different environments. So if the service monitor spec failed, we would know which environment it failed for.

We wanted a way to specify the environment variable when we run the specs like this TEST_ENV=staging rspec services_monitor/service_spec.rb so that it would run the specs, only hitting the urls that exist in staging.

How do we do this? It’s quite simple, really. Let’s say we have a spec that tests whether myservice.com is up:

require 'open-uri'

describe "Services are up" do

  it "ensures myservice is up" do
    url = "http://staging.myservice.com"
    expect(open(url).status.first).to eq "200"
  end
end

As it is, you can run rspec services_monitor/service_spec.rb and it will always test http://staging.myservice.com. Now, I’d like to specify whether it runs for http://staging.myservice.com or http://qa.staging.myservice.com, assuming I have environments called staging and qa. I add the use of an environment variable:

require 'open-uri'

describe "Services are up" do

  it "ensures myservice is up" do
    url = "http://#{ENV["TEST_ENV"]}.myservice.com"
    expect(open(url).status.first).to eq "200"
  end
end

Now you can run TEST_ENV=staging rspec services_monitor/service_spec.rb to check whether http://staging.myservice.com is up, or you can run TEST_ENV=qa rspec services_monitor/service_spec.rb to test whether http://qa.myservice.com is up. Note, however, that this spec will still run if you don’t provide a TEST_ENV, and if you do this, it will test whether “http://.myservice.com” is up even though it’s not a valid url. We want to make sure that these tests are always run with the TEST_ENV variable. Here’s how to do so, with a descriptive message:

require 'open-uri'

describe "Services are up" do
  raise "Please provide TEST_ENV parameter" if ENV["TEST_ENV"].nil?

  it "ensures myservice is up" do
    url = "http://#{ENV["TEST_ENV"]}.myservice.com"
    expect(open(url).status.first).to eq "200"
  end
end

And that’s all, folks. Pretty simple, right?