GladstoneKeep
GladstoneKeep

Reputation: 3982

How can I make RSpec output to console when run as a command %x[rspec] from Ruby script?

I have a class with an instance method that runs RSpec using the %x[] notation:

class TestRunner
  def run_rspec
    # do stuff
    %x[rspec spec -c -f documentation]
    # do more stuff
  end
end

When I do this:

> tr = TestRunner.new
> tr.run_rspec

The documentation (group and example names) does not appear in the console.

To contrast, when I run rspec straight from the command line I get this:

$ rspec spec -c -f documentation

  a group name
    an example
    another example
    ...

I don't want to do this:

puts %x[rspec spec -c -f documentation

Because then the output all spits out in one huge clump at the very end. I want it to run in "real time," with each example showing up as each test is run.

Is there a way, with the setup I have, to get RSpec to announce what it's doing, as it's doing it (as it does when run normally from the command line)?

Upvotes: 1

Views: 1934

Answers (1)

GladstoneKeep
GladstoneKeep

Reputation: 3982

I've been advised that system() and the other shell methods can be dangerous to use, so I've opted to switch to the even-better approach of using RSpec itself:

RSpec::Core::Runner.run(['spec', '-c', '-f', 'documentation'])

rather than calling it via shell from my Ruby script.


Ruby offers several options for running programs from the command line. I was using %x[], the wrong choice for my use case.

Solution: Use system(), not %x[] -- rspec will write to STDOUT in real-time when I call it with system('rspec spec').


Some background in case it's helpful to anyone who stumbles upon this question:

Consider the differences between Ruby's command-line options:

  • %x[command] accumulates the result of command and returns it, in one chunk.
  • exec('command') will output command as command runs, but will replace whatever process called it -- i.e., if you use exec in your Ruby script, your Ruby script won't finish.
  • system('command') executes command in a subshell, and returns to the calling script.

This is why system was the choice for my script.

Upvotes: 3

Related Questions