简体   繁体   中英

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?

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 , eg '--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

Run bundle exec rspec to run all tests or bundle exec rspec./spec/user_spec.rb to run the specific test

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM