DEV Community

Monica
Monica

Posted on

TIL about testing commands

This is a walk-with-me-while-I-do-things series, I'm going to tell you what I learned while I'm learning

If this was our program

# my_tool.rb

# Removes and returns the first item from the command-line arguments
command = ARGV.shift

puts command

you can test this code using RSpec with

# specs/my_tool_spec.rb

RSpec.describe "my_tool" do
  it "says hello" do
    expect { system "ruby my_tool.rb hello" }.
      to output("hello\n").
      to_stdout_from_any_process
  end
end

Here we have three fundamental pieces:

  1. the method Kernel#system that invokes a command as if we were on the command line itself. The argument passed as a string will be the command being executed;

  2. the RSpec matcher output that checks against the expectation and passes if the expectation block on which it is invoked outputs to_stdout or to_stderr the string passed as an argument;

  3. the to_stdout_from_any_process that we have to use instead of to_sdtdout because the system call is actually spawning a subprocess, and RSpec wouldn't be able to access $stdout otherwise.

If we weren't testing a command line invocation, we could have written

expect { print "Same process" }.
  to output("Same process").
  to_stdout

More sources are here. To use RSpec for capturing the output and where you can go to the official doc.

Top comments (0)