6

私はアプローチ全体を試していますが、私が書いているバニラアプリケーションBDDのベースの側面をテストしたいと思います。他の適切な名前の野菜フレームワークとは対照的に、機能と表現力のバランスのテストフレームワークとして選択した後、私はこの仕様を書き始めました。AMQPRubyMinitest

# 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

スペックをreactor内で実行するように強制するem-minitest-specgemの機能を含めることについてコメントしました。これを含めるEventMachineと、インラインクラスなどに関してさらに大雑把な例外が発生しますNoMethodError: undefined method 'include' for #<#<Class:0x3a1d480>:0x3b29e00>

私がテストしているコード、つまり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

「例外処理」全体は、例外をキャッチ/処理できる場所にバブルアウトする試みにすぎません。これは、仕様の実行時に同じ結果が得られるビットの有無beginにかかわらず、どちらも役に立ちませんでした。raise

EventMachine::ConnectionError: unable to resolve server address、これは実際には私が期待することですが、Minitestリアクターの概念全体ではうまく機能せず、これに基づいてテストに失敗しますException

その場合、疑問が残ります。の仕様メカニズムEventMachineを使用して、関連するコードをどのようにテストするのでしょうか。もう1つの質問も、未回答の問題について浮かんでいます。MinitestCucumber

または、主な機能(メッセージング、メッセージが送受信されるかどうかの確認など)に焦点を当て、エッジケースを忘れる必要がありますか?どんな洞察も本当に役に立ちます!

もちろん、それはすべて私が上で書いたコードに帰着することができます、多分それはこれらの側面を書く/テストする方法ではないかもしれません。になり得る!

私の環境に関するメモ:(はい、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)

前もって感謝します!

4

1 に答える 1

5

この応答があまりにも衒学的である場合は申し訳ありませんが、単体テストと受け入れテストを区別すると、テストとライブラリを作成するのがはるかに簡単になると思います。

BDD対TDD

BDDとTDDを混同しないように注意してください。どちらも非常に便利ですが、受け入れテストですべてのエッジケースをテストしようとすると問題が発生する可能性があります。たとえば、BDDは、サービスで達成しようとしていることをテストすることを目的としています。これは、キュー自体に接続することよりも、メッセージキューで実行していることと関係があります。私の意見では、存在しないメッセージキューに接続しようとすると、単体テストの領域にさらに適合します。また、AMQPの責任であるため、サービスがメッセージキュー自体のテストを担当するべきではないことも指摘しておく価値があります。

BDD

あなたのサービスが正確に何をするのかはわかりませんが、BDDテストは次のようになると思います。

  1. サービスを開始します(必要に応じて、テストの別のスレッドでこれを実行できます)
  2. キューに何かを書く
  3. サービスが応答するのを待ちます
  4. サービスの結果を確認してください

言い換えると、BDD(または受け入れテスト、または統合テスト、ただしそれらについて考えたい場合)は、アプリを特定の機能(または動作)を提供することになっているブラックボックスとして扱うことができます。テストでは、最終目標に集中できますが、アプリの堅牢性ではなく、1つまたは2つのゴールデンユースケースを確認することを目的としています。そのためには、単体テストに分解する必要があります。

TDD

TDDを実行しているときは、コード編成の観点からテストをある程度ガイドしてください。新しいスレッドを作成し、そのスレッド内でEMを実行するメソッドをテストすることは困難ですが、これらのいずれかを個別に単体テストすることはそれほど難しくありません。したがって、メインスレッドコードを個別に単体テストできる別の関数に配置することを検討してください。次に、メソッドを単体テストするときに、そのメソッドをスタブアウトできますconnect。また、(AMQPをテストする)不良サーバーに接続しようとしたときに何が起こるかをテストする代わりに、AMQPがエラー(処理するコードの責任)をスローしたときに何が起こるかをテストできます。AMQP.connectここで、ユニットテストは例外をスローするための応答をスタブすることができます。

于 2012-07-07T15:39:41.137 に答える