2

我想测试对用户输入的响应。使用Highline查询该输入:

def get_name
  return HighLine.new.ask("What is your name?")
end

我想做与这个问题类似的事情并将其放入我的测试中:

STDOUT.should_receive(:puts).with("What is your name?")
STDIN.should_receive(:read).and_return("Inigo Montoya")
MyClass.new.get_name.should == "Inigo Montoya"

使用 Highline 执行此操作的正确方法是什么?

4

4 回答 4

10

了解如何测试 Highline 的最佳方法是查看作者如何测试他的包。

class TestHighLine < Test::Unit::TestCase
  def setup
    @input    = StringIO.new
    @output   = StringIO.new
    @terminal = HighLine.new(@input, @output)..
  end
..
  def test_agree
    @input << "y\nyes\nYES\nHell no!\nNo\n"
    @input.rewind

    assert_equal(true, @terminal.agree("Yes or no?  "))
    assert_equal(true, @terminal.agree("Yes or no?  "))
    assert_equal(true, @terminal.agree("Yes or no?  "))
    assert_equal(false, @terminal.agree("Yes or no?  "))
....
    @input.truncate(@input.rewind)
    @input << "yellow"
    @input.rewind

    assert_equal(true, @terminal.agree("Yes or no?  ", :getc))
  end


   def test_ask
     name = "James Edward Gray II"
     @input << name << "\n"
     @input.rewind

     assert_equal(name, @terminal.ask("What is your name?  "))
 ....
     assert_raise(EOFError) { @terminal.ask("Any input left?  ") }
   end

等等,如他的代码所示。您可以在highline 源代码中找到此信息,密切关注我在链接中突出显示的设置。

请注意他是如何使用 STDIN IO 管道来代替在键盘上键入键的。

实际上,这表明您不需要使用highline来测试那种东西。他的测试中的设置在这里真的很关键。随着他的使用 StringIO作为一个对象。

于 2013-01-10T08:15:49.700 回答
1

Highline 已经有自己的测试,以确保它输出到 STDOUT 并从 STDIN 读取。没有理由编写这些类型的测试。这与您不会编写 ActiveRecord 测试以确保可以保存属性并从数据库中读取的原因相同。

但是...如果 Highline 有一个框架,它的工作方式与 Capybara 用于 Web 表单的方式相似,那将非常有用...实际上驱动来自 UI 的输入并测试您的命令行实用程序的逻辑。

例如,以下类型的假设测试会很好:

run 'my_utility.rb'
highline.should :show_menu
select :add
highline.should(:ask).with_prompt("name?")
enter "John Doe"
output.should == "created new user"
于 2013-04-07T01:26:02.267 回答
1

我已经发布了 HighLine::Test - 它允许您在一个进程中运行您的测试并在另一个进程中运行您的应用程序(与使用 Selenium 进行基于浏览器的测试的方式相同)。

于 2013-07-07T14:32:51.717 回答
1

我研究了这个 DSL 来尝试解决这个问题:

https://github.com/bonzofenix/cancun

require 'spec_helper'

describe Foo do
  include Cancun::Highline
  before { init_highline_test }

  describe '#hello' do
    it 'says hello correctly' do
    execute do
      Foo.new.salute
    end.and_type 'bonzo'
    expect(output).to include('Hi bonzo')
  end
于 2014-02-03T13:58:11.333 回答