Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute an rspec test in Rails Console

Say I have a user_spec.rb for my User model, and I want to run that test inside the rails console.

My first thought is to execute the usual shell command:

exec("./spec/user_spec.rb")

But is there a simpler way to run the spec? I'm trying to automate some of the tests (and reinvent the wheel a little, yes), so being able to trigger an rspec test inside of another Ruby class seems ideal.

Edit:

output = `./spec/user_spec.rb`

This will provide the rspec output and $?.success? will then provide a pass fail value. Is this the best solution here? Or is there a way to call an RSpec class itself?

like image 282
Scott Hillson Avatar asked Oct 01 '18 19:10

Scott Hillson


People also ask

How do I run a RSpec test in terminal?

Open your terminal, cd into the project directory, and run rspec spec . The spec is the folder in which rspec will find the tests. You should see output saying something about “uninitialized constant Object::Book”; this just means there's no Book class.

How do I run a specific test in RSpec?

Running tests by their file or directory names is the most familiar way to run tests with RSpec. RSpec can take a file name or directory name and run the file or the contents of the directory. So you can do: rspec spec/jobs to run the tests found in the jobs directory.


1 Answers

As pointed out by Anthony in his comment, you can use RSpec::Core::Runner to basically invoke the command line behavior from code or an interactive console. However, if you use something like Rails, consider that your environment is likely going to be set to development (or even production, if this is where you'll execute the code). So make sure that whatever you do doesn't have any unwanted side-effects.

Another thing to consider is that RSpec globally stores its configuration including all example groups that were registerd with it before. That's why you'll need to reset RSpec between subsequent runs. This can be done via RSpec.reset.

So putting it all together, you'll get:

require 'rspec/core'
RSpec::Core::Runner.run(['spec/path/to_spec_1.rb', 'spec/path/to_spec_2.rb'])
RSpec.reset

The call to RSpec::Core::Runner.run will output to standard out and return the exit code as a result (0 meaning no errors, a non-zero exit code means a test failed).

..

Finished in 0.01791 seconds (files took 17.25 seconds to load)
2 example, 0 failures

=> 0

You can also pass other IO objects to RSpec::Core::Runner.run to specify where it should output to. And you can also pass other command line parameters to the first array of RSpec::Core::Runner.run, e.g. '--format=json' to output the results in JSON format.

So if you for example want to capture the output in JSON format to then further do something with it, you could do the following:

require 'rspec/core'

error_stream = StringIO.new
output_stream = StringIO.new

RSpec::Core::Runner.run(
  [
    'spec/path/to_spec_1.rb',
    'spec/path/to_spec_2.rb',
    '--format=json'
  ],
  error_stream,
  output_stream
)

RSpec.reset

errors =
  if error_stream.string.present?
    JSON.parse(error_stream.string)
  end

results =
  if output_stream.string.present?
    JSON.parse(output_stream.string)
  end

like image 103
Nicolas Avatar answered Oct 12 '22 03:10

Nicolas