【问题标题】:How to write Rspec test for running file from command line?如何从命令行为运行文件编写 Rspec 测试?
【发布时间】:2020-08-03 15:47:13
【问题描述】:

我有一个 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

当我运行它时,我得到了测试失败:

预期块将“hello world”输出到标准输出,但什么也不输出

这是我的规范文件相对于我的项目根目录的位置:spec/integration/parse_spec.rb

我尝试将 requirerequire_relative 语句与 parse 可执行文件的路径一起放在该规范文件中,以防万一,但我只是不断得到:

LoadError: 无法加载此类文件

有谁知道我如何在该文件中编写一个可以通过并证明parse 可执行行为有效的测试?

【问题讨论】:

  • 系统命令不返回任何输出。你可能想要``%x()
  • 你需要确保从 shell 调用的东西在 PATH 中。否则,您的规范、lib 文件等之间的行为可能会发生变化。您可以从规范文件中尝试../../bin/parse,但这会使您的代码变得脆弱。
  • @ToddA.Jacobs 谢谢,你能详细说明一下吗?我该怎么做你所说的? “确保您的解析命令在您的路径中”(我还在您的代码中尝试使用../../bin/parse 代替parse,但这不起作用)(我还必须将您的() 更改为{},因为测试失败说它需要块)
  • 您正在与反模式作斗争。您最好使用 let 或 before 块来正确(无论这对您的应用程序意味着什么)使用%x() 获取命令的输出,然后进行比较。
  • 在 PATH 环境变量中包含解析实用程序的限定路径。你可以在 shell 中设置它,或者在你的程序中修改ENV["PATH"]。使用规范中的相对路径会使其无法可靠地作为真实代码的测试,因此除非您真的必须这样做,否则不要这样做。

标签: ruby rspec


【解决方案1】:

不要使用 RSpec 输出匹配器

RSpec 有一个内置的output matcher 可以测试哪里 输出,以及它的内容。但是,它测试的是您的 Ruby 输出的去向,而不是某些外部应用程序使用标准输入还是标准错误。您将不得不对您的代码做出一些不同的假设。

您可以通过比较字符串而不是测试底层外壳或输出流来避免让自己发疯。例如,考虑:

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 之类的实用程序,或者通过在您的spec 或spec_helper 中修改ENV["PATH"]

根据经验,RSpec 并不是真正用于测试命令行应用程序。如果您想这样做,请考虑使用Aruba framework 来练习您的命令行应用程序。最好使用 RSpec 来测试方法的结果或命令的输出,而不是尝试测试基本功能。当然,您的里程可能会有所不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    • 2014-09-02
    • 2015-05-22
    • 2016-02-03
    • 2017-06-08
    • 2015-05-22
    • 2018-10-27
    相关资源
    最近更新 更多