Search code examples
rubyserverspec

how to invoke bundler commands from within a Serverspec/RSpec test


I have a project to create a template ruby project.

I am using serverspec and want to verify the behaviour of the template.

However, using command(`rake -T`) fails. If I execute the command manually, it works as expected.

Debugging, when the test is running in Serverspec, it finds the wrong Gemfile - it is using the Gemfile from my project (.), not the generated directory (target/sample_project).

How can I invoke rake or bundler commands withing a Serverspec/Rspec test?

sample code:

require "spec_helper"
require 'serverspec'
require 'fileutils'

set :backend, :exec
set :login_shell, true

describe "Generated Template" do
  output_dir='target'
  project_dir="#{output_dir}/sample_project"

  # Hooks omitted to create the sample_project 
  # and change working directory to `project_dir`

  describe command('rake -T') do
    its(:stdout) { should include "rake serverspec:localhost" }
    its(:stdout) { should include "rake serverspec:my_app" }
  end
end

Solution

  • Bundler has provision for running external shell commands documented here: http://bundler.io/v1.3/man/bundle-exec.1.html

    Running bundler/rake tasks is possible using rspec using Bundler.with_clean_env, instead of Serverspec.

    require 'bundler'
    require 'rspec'
    RSpec.describe "Generated Template" do
    
      output_dir='target'
      project_dir="#{output_dir}/sample_project"
    
      around(:example) do |example|
        #Change context, so we are in the generated project directory
        orig_dir=Dir.pwd
    
        Dir.chdir(project_dir)
        example.run
        Dir.chdir(orig_dir)
    
      end
    
      around(:example) do |example|
        Bundler.with_clean_env do
          example.run
        end
      end
    
      it "should include localhost" do
        expect(`rake -T 2>&1`).to include "rake serverspec:localhost"
      end
    end