如何从命令行为 运行 文件编写 Rspec 测试?
How to write Rspec test for running file from command line?
我有一个 Ruby 项目,其中一个名为 parse
的 UNIX 可执行文件位于我项目根目录的 bin
子文件夹中。
目前是这样的:
#!/usr/bin/env ruby
# frozen_string_literal: true
puts 'hello world'
从项目根目录运行这条命令可以在命令行执行文件:bin/parse
它工作正常,但我还想为它编写一个通过的 Rspec 测试。
我有这个规格文件:
RSpec.describe "end-to-end application behaviour" do
subject { system('bin/parse') }
it 'prints the expected messsage to stdout' do
expect { subject }.to output(
'hello world'
).to_stdout
end
end
当我 运行 它时,我得到测试失败:
expected block to output "hello world" to stdout, but output nothing
这是我的规范文件相对于我的项目根目录的位置:spec/integration/parse_spec.rb
我尝试在该规范文件中放置 require
和 require_relative
语句以及 parse
可执行文件的路径,以防万一,但我一直得到:
LoadError: cannot load such file
有谁知道我如何在该文件中编写一个测试来证明 parse
可执行行为有效?
不要使用 RSpec 输出匹配器
RSpec 有一个 built-in output matcher 可以测试 where 输出,以及它的内容。但是,它测试的是 Ruby 输出的去向,而不是某些外部应用程序正在使用标准输入还是标准错误。您将不得不对您的代码做出一些不同的假设。
您可以通过比较 字符串 而不是测试底层 shell 或您的输出流来避免让自己抓狂。例如,考虑:
RSpec.describe "parse utility output" do
it "prints the right string on standard output" do
expect(`echo hello world`).to start_with("hello world")
end
it "shows nothing on standard output when it prints to stderr" do
expect(`echo foo >&2 > /dev/null`).to be_empty
end
end
只需为您的系统用 parse
的正确调用替换 echo 语句,也许通过直接在 shell 中设置 PATH,使用像 direnv 这样的实用程序,或者通过修改ENV["PATH"]
在您的规范中或 spec_helper.
根据经验,RSpec 并不是真正用于测试 command-line 应用程序。如果您想这样做,请考虑使用 Aruba framework 来练习您的 command-line 应用程序。最好使用 RSpec 来测试方法的结果或命令的输出,而不是尝试测试基本功能。当然,您的里程可能会有所不同。
我有一个 Ruby 项目,其中一个名为 parse
的 UNIX 可执行文件位于我项目根目录的 bin
子文件夹中。
目前是这样的:
#!/usr/bin/env ruby
# frozen_string_literal: true
puts 'hello world'
从项目根目录运行这条命令可以在命令行执行文件:bin/parse
它工作正常,但我还想为它编写一个通过的 Rspec 测试。 我有这个规格文件:
RSpec.describe "end-to-end application behaviour" do
subject { system('bin/parse') }
it 'prints the expected messsage to stdout' do
expect { subject }.to output(
'hello world'
).to_stdout
end
end
当我 运行 它时,我得到测试失败:
expected block to output "hello world" to stdout, but output nothing
这是我的规范文件相对于我的项目根目录的位置:spec/integration/parse_spec.rb
我尝试在该规范文件中放置 require
和 require_relative
语句以及 parse
可执行文件的路径,以防万一,但我一直得到:
LoadError: cannot load such file
有谁知道我如何在该文件中编写一个测试来证明 parse
可执行行为有效?
不要使用 RSpec 输出匹配器
RSpec 有一个 built-in output matcher 可以测试 where 输出,以及它的内容。但是,它测试的是 Ruby 输出的去向,而不是某些外部应用程序正在使用标准输入还是标准错误。您将不得不对您的代码做出一些不同的假设。
您可以通过比较 字符串 而不是测试底层 shell 或您的输出流来避免让自己抓狂。例如,考虑:
RSpec.describe "parse utility output" do
it "prints the right string on standard output" do
expect(`echo hello world`).to start_with("hello world")
end
it "shows nothing on standard output when it prints to stderr" do
expect(`echo foo >&2 > /dev/null`).to be_empty
end
end
只需为您的系统用 parse
的正确调用替换 echo 语句,也许通过直接在 shell 中设置 PATH,使用像 direnv 这样的实用程序,或者通过修改ENV["PATH"]
在您的规范中或 spec_helper.
根据经验,RSpec 并不是真正用于测试 command-line 应用程序。如果您想这样做,请考虑使用 Aruba framework 来练习您的 command-line 应用程序。最好使用 RSpec 来测试方法的结果或命令的输出,而不是尝试测试基本功能。当然,您的里程可能会有所不同。