Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 基于机器(反应器)的规范测试代码_Ruby_Testing_Amqp_Eventmachine_Minitest - Fatal编程技术网

Ruby 基于机器(反应器)的规范测试代码

Ruby 基于机器(反应器)的规范测试代码,ruby,testing,amqp,eventmachine,minitest,Ruby,Testing,Amqp,Eventmachine,Minitest,我正在尝试整个BDD方法,并想测试我正在编写的基于AMQP的普通Ruby应用程序。在选择了Minitest作为测试框架,以平衡其功能和表达能力,而不是其他恰当命名的植物框架之后,我开始编写本规范: # File ./test/specs/services/my_service_spec.rb # Requirements for test running and configuration require "minitest/autorun" require "./test/specs/spe

我正在尝试整个
BDD
方法,并想测试我正在编写的基于
AMQP
的普通
Ruby
应用程序。在选择了
Minitest
作为测试框架,以平衡其功能和表达能力,而不是其他恰当命名的植物框架之后,我开始编写本规范:

# File ./test/specs/services/my_service_spec.rb

# Requirements for test running and configuration
require "minitest/autorun"
require "./test/specs/spec_helper"

# External requires
# Minitest Specs for EventMachine
require "em/minitest/spec"

# Internal requirements
require "./services/distribution/my_service"

# Spec start
describe "MyService", "A Gateway to an AMQP Server" do

  # Connectivity
  it "cannot connect to an unreachable AMQP Server" do

   # This line breaks execution, commented out
   # include EM::MiniTest::Spec

   # ...
   # (abridged) Alter the configuration by specifying
   # an invalid host such as "l0c@alho$t" or such
   # ...

   # Try to connect and expect to fail with an Exception
   MyApp::MyService.connect.must_raise EventMachine::ConnectionError
  end

end
我已经注释掉了包含的功能,它应该强制规范在
EventMachine
反应器中运行,如果我包含它,我会遇到一个关于(我想)内联类的更粗略的异常:
NoMethodError:undefined方法“include”for#

我正在测试的代码,即该服务中的
connect
方法是基于以下代码的:

# Main namespace
module MyApp

  # Gateway to an AMQP Server
  class MyService

    # External requires
    require "eventmachine"
    require "amqp"

    # Main entry method, connects to the AMQP Server
    def self.connect

      # Add debugging, spawn a thread
      Thread.abort_on_exception = true
      begin
        @em_thread = Thread.new {
          begin
            EM.run do
              @connection  = AMQP.connect(@settings["amqp-server"])
              AMQP.channel = AMQP::Channel.new(@connection)
            end
          rescue
            raise
          end
        }

        # Fire up the thread
        @em_thread.join

        rescue Exception
          raise
        end
      end # method connect
  end
end  # class MyService
整个“异常处理”只是试图将异常冒泡到一个我可以捕获/处理它的地方,但不管是否使用
开始
提升
位,我在运行规范时仍然得到相同的结果:

EventMachine::ConnectionError:无法解析服务器地址
,这实际上是我所期望的,但是
Minitest
不能很好地处理整个反应堆概念,并且由于该
异常
而导致测试失败

接下来的问题是:如何使用
Minitest
的规范机制来测试
EventMachine
相关的代码?关于黄瓜的问题也一直悬而未决,也没有回答

或者我应该专注于我的主要功能(例如,发送消息并查看消息是否被发送/接收),而忽略边缘案例?任何洞察都会有真正的帮助

当然,这可以归结为我上面写的代码,也许这不是编写/测试这些方面的方式。可能是

关于我的环境的说明:
ruby 1.9.3p194(2012-04-20)[i386-mingw32]
(是的,Win32:>),
minitest 3.2.0
eventmachine(1.0.0.rc.4 x86-mingw32)
amqp(0.9.7)

提前谢谢

如果这个回答太迂腐,那么很抱歉,但是我认为如果您区分单元测试和验收测试,那么编写测试和库会容易得多

BDD与TDD 注意不要将BDD与TDD混淆。虽然两者都非常有用,但在验收测试中尝试测试每个边缘情况时可能会导致问题。例如,BDD是关于测试您试图用您的服务完成什么,这与您对消息队列所做的事情比连接到队列本身更相关。在我看来,当您尝试连接到一个不存在的消息队列时发生的事情更符合单元测试的范畴。还值得指出的是,您的服务不应该负责测试消息队列本身,因为这是AMQP的责任

BDD 虽然我不确定您的服务到底应该做什么,但我认为您的BDD测试应该如下所示:

  • 启动服务(如果需要,可以在测试中的单独线程中启动)
  • 在队列中写入内容
  • 等待您的服务响应
  • 检查服务结果
  • 换句话说,BDD(或者验收测试,或者集成测试,不管你怎么想)可以将你的应用程序视为一个黑匣子,用来提供特定的功能(或者行为)。这些测试让你专注于最终目标,但更多的是为了确保一两个黄金用例,而不是应用程序的健壮性。为此,您需要分解为单元测试

    TDD
    在进行TDD时,让测试在代码组织方面为您提供一些指导。测试一个创建新线程并在该线程内运行EM的方法是困难的,但单独对其中任何一个进行单元测试并不困难。因此,考虑将主线程代码放在单独的函数中,可以单独进行单元测试。然后,您可以在单元测试
    connect
    方法时删除该方法。此外,您可以测试AMQP抛出错误时发生的情况(这是您的代码负责处理的),而不是测试尝试连接到坏服务器时发生的情况(测试AMQP)。在这里,您的单元测试可以剔除
    AMQP.connect的响应以抛出异常。

    感谢您的见解,这确实让事情变得更加全面,你看穿了我的问题,并在这个过程中启发了我:)最终证明有效的方法是在规范中用一个
    开始
    --
    解救
    块包装对
    连接
    的调用,其中
    必须引发
    断言。然而,测试非常慢(重试、超时等),我可能会完全放弃它,主要是考虑到Ben在下面的答案中的洞察力。