我正在尝试整个BDD
方法,并想测试我正在编写的 Vanilla 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
我已经注释掉了the em-minitest-spec gem的功能,该功能应强制规范在
EventMachine
react 器中运行,如果包含它,我会遇到关于(我想)内联类(甚至是NoMethodError: undefined method 'include' for #<#<Class:0x3a1d480>:0x3b29e00>
)的更为粗略的异常。我正在测试的代码(即该Service中的
connect
方法)基于on this article,看起来像这样:# 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
整个“异常处理”仅是尝试将异常冒泡到我可以捕获/处理的地方,无论有无
begin
和raise
位,都无济于事,运行该命令时仍然会得到相同的结果规范:EventMachine::ConnectionError: unable to resolve server address
,实际上实际上是我所期望的,但是Minitest
不能在整个 react 堆概念中很好地发挥作用,并且基于Exception
未能通过测试。问题仍然存在:如何使用
EventMachine
的规范机制测试与Minitest
相关的代码? Another question也一直在徘徊关于Cucumber
,也未得到解答。还是我应该专注于我的主要功能(例如消息传递并查看消息是否被发送/接收)而忘记边缘情况?任何见识都将真正有帮助!
当然,所有这些都可以归结为我上面编写的代码,也许这不是编写/测试这些方面的方式。可能!
关于我的环境的注释:
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时,请让测试在代码组织方面为您提供一些指导。测试创建新线程并在该线程中运行EM的方法很困难,但是对其中一个进行单元测试并不难。因此,请考虑将主线程代码放入一个单独的函数中,您可以对其进行单独的单元测试。然后,可以在对
connect
方法进行单元测试时将其 stub 。另外,您可以测试当AMQP引发错误时(代码的责任),而不是测试尝试连接到故障服务器(测试AMQP)时发生的情况。在这里,您的单元测试可以 stub AMQP.connect
的响应以引发异常。