6

以下场景几乎总结了我的问题:

Scenario: problems with subprocesses
  Given the date is 01/01/2012 10:31
  When I run `ruby -e "puts Time.now"`
  Then the output should contain "10:31"

它归结为When I run ruby -e "puts Time.now"启动一个子进程,从而使我的所有Timecop.freeze存根无效,因为它们只在主进程上工作。我需要以某种方式将当前上下文“注入”到正在运行的命令中,但我似乎无法提出任何建议。我在这里尝试一些不可能的事情吗?


步骤:

require 'timecop'
Given /^the date is (\d+)\/(\d+)\/(\d+) (\d+):(\d+)$/ do |month, day, year, hour, minute|
  Timecop.freeze(Time.local(year.to_i, month.to_i, day.to_i, hour.to_i , minute.to_i, 0))
end
4

2 回答 2

1

我在这里看到 2 个选项。

  1. 在被测系统中创建一个钩子,您可以使用它来注入所需的上下文,在此示例中,您可以将“当前时间”参数添加到您正在测试的命令行应用程序中。或者在应用程序配置文件或数据库中指定固定时间,有很多选项。这假定您拥有正在测试的应用程序并且可以进行此类更改。这只需很小的更改,例如,如果指定了“当前时间”参数,则使用 Timecop 冻结当时的时间。

  2. 找到某种方法将被测系统带入 Cucumber 进程。在您的示例中ruby -e "puts Time.now",您可以instance_eval "puts Time.now". 更实际的是,您可以require使用应用程序,如果命令行运行程序只是一些实际执行工作的类的薄包装器,那么您可以直接调用它们。或者,您可以填充任何预期的 ARGV 参数,模拟puts方法和require文件,这应该可以让您近距离体验在进程外运行它,但您将能够有效地使用 Timecop。

于 2012-03-06T22:11:33.173 回答
0

Aruba 还支持一种称为进程执行的功能,它允许您在一个进程中运行所有内容。但是,它几乎完全限制您使用 Aruba 测试 Ruby CLI,因为它的工作方式是通过调用 Ruby 方法覆盖命令的默认行为。

这对我来说是这样的——我正在使用 Aruba 来测试 Thor 应用程序:

require 'aruba/cucumber'
require 'aruba/in_process'
require 'thor'
require 'thor/runner'

load 'Thorfile'

class ThorFriendlyMain
  def initialize(argv, stdin, stdout, stderr, kernel)
    @argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
  end

  def execute!
    $stdin = @stdin
    $stdout = @stdout
    $stderr = @stderr
    Thor::Runner.start(@argv)
    $stdin = STDIN
    $stdout = STDOUT
    $stderr = STDERR
  end   
end     

Aruba.config.command_launcher = :in_process
Aruba.config.main_class = ThorFriendlyMain
于 2018-04-23T20:14:57.917 回答