2017-06-29 12 views
1

背景キュウリルビー - モジュール内のステップ

私は複数のプロジェクトで使用するための異なるステップの様々なキュウリのライブラリーの両方を書いて3にそれらを分割することにより、ステップの定義の複雑さを軽減しようとしていますiOS、Android、Webのための異なるモジュール、具体的にはすべて3を含むプロジェクトです。

ステップライブラリの1つに、手順を使用する前にプロジェクトに明示的に含めるセキュリティベースの手順が含まれています。新しいプロジェクトに起動時

if $profile[:app_type] == 'android' 
    World(ProjectSteps::Android) 
else 
    if $profile[:app_type] == 'ios' 
     World(ProjectSteps::IOS) 
    else 
     World(ProjectSteps::Web) 
    end 
end 

これらのヘルパーメソッドを置き換えるためにされていませんが、私たちの時間を節約するために:

プロジェクト分割ライブラリを明示的に設定で指定された内容に応じて含まれることになりますウェブ、ネイティブiOSアプリ、まったく同じ機能を持つように構築されたネイティブAndroidアプリをテストしているかどうかによって、異なるステップ定義を必要とするほど異なるプロジェクト固有のステップ定義を異なる方法で記述することも可能になります

モジュール内のステップを定義した後の問題

、フィーチャーファイルはまだこのようにモジュールは、「世界」には含まれていない場合でも、喜んでこれを実行することができます。World(CommonSteps::Security)であり、これは何を普通だろうモジュールの内部に隠れているヘルパーメソッドについてキュウリに知らせるために使用します。

When 'I provide my personal details' do 
    select :title, 'Mr' 
    fill :first_name, 'John' 
    fill :last_name, 'Doe' 

    unless $profile[:app_type] == 'web' 
     click :progress 
    end 

    if $profile[:app_type] == 'android' 
     fill :postcode, 'TE37ER' 
     select :address, '1 Test Street' 
     click :progress 
     fill :occupation, 'Tester' 
     fill :company, 'Test Company' 
     click :progress 
    else 
     fill :occupation, 'Tester' 
     fill :company, 'Test Company' 
     unless $profile[:app_type] == 'web' 
      click :progress 
     end 
     fill :postcode, 'TE37ER' 
     select :address, '1 Test Street' 
     click :progress 
    end 
end 

このステップ定義は一度に3つのアプリケーションをテストしようとしているが、それは、まったく同じシナリオとまったく同じ機能をまったく同じ機能をテストしています。これが3つのステップ定義に分割されていれば、将来的にはデバッグするのが簡単になりますが、同じ機能ファイルをそれぞれに使用できるようになります(これは疑問の余地はありません。ウェブとネイティブのモバイル版で全く同じ機能を共有しています)。私の意見では、このタイプのステップ定義はあまりにも多くを達成しようとしています。

それは簡単ですので、これは、より多くのことにもかかわらず、保守が容易になります:

module ProjectSteps::IOS 
    When 'I provide my personal details' do 
     select :title, $user[:title] 
     fill :first_name, $user[:first_name] 
     fill :last_name, $user[:last_name] 
     click :progress 
     fill :occupation, $user[:occupation] 
     fill :company, $user[:company] 
     click :progress 
     fill :postcode, $user[:postcode] 
     select :address, $user[:line1] 
     click :progress 
    end 
end 
module ProjectSteps::Android 
    When 'I provide my personal details' do 
     select :title, $user[:title] 
     fill :first_name, $user[:first_name] 
     fill :last_name, $user[:last_name] 
     click :progress 
     fill :postcode, $user[:postcode] 
     select :address, $user[:line1] 
     click :progress 
     fill :occupation, $user[:occupation] 
     fill :company, $user[:company] 
     click :progress 
    end 
end 
module ProjectSteps::Web 
    When 'I provide my personal details' do 
     select :title, $user[:title] 
     fill :first_name, $user[:first_name] 
     fill :last_name, $user[:last_name] 
     fill :occupation, $user[:occupation] 
     fill :company, $user[:company] 
     fill :postcode, $user[:postcode] 
     select :address, $user[:line1] 
     click :progress 
    end 
end 
When 'some thing that is the same across platforms' do 
    # Some stuff 
end 

クマ心の中で、これは私が達成しようとしているものの簡易版で、表示されません。私が解決しようとしているいくつかの問題の完全な複雑さ。このケースでは、分割よりむしろif/unlessバージョンを使用する可能性が最も高いですが、大幅に複雑なケースが3つあり、3つのセクションに分割すると恩恵を受けます。

私たちが開発中に見つけたバグについては、これらが回帰しないことを確認するためにサイレントチェックを追加することもできます。また、web、androidとiosのアプリケーションのバグが異なるため、 if/unlessステートメント

私は何を試しましたか?- 私はあなたが

を尋ねる聞くまあ、私はどちらか本当に近い、または遠く本当にです。

Given,およびThenは別のモジュール内では正常に動作しないため、別名であると思われる方法を検索しなければなりませんでした。ここで

は、結果のコードです:

require_relative 'xss.rb' 
require 'cucumber' 

module CommonSteps 
    module Security 
    Cucumber::RbSupport::RbDsl.register_rb_step_definition(
     'I attempt to write a step definition that has to be included to work', 
     Proc.new { 
      # Some stuff here 
     }) 
    end 
end 

絶対に細かいステップ定義を登録します。しかし、それは問題の一部です。モジュールが私が取り組んでいるプロジェクトの世界に含まれている場合にのみ、このステップ定義を登録したいと思います。

機能を維持することは、まったく同じにファイルをしながら、それはまた、私たちがする必要がある場合、我々はiOSとAndroidのステップのためのWeb段階を切り替えることができますことを意味します。 (はい私はif文が事あるけど、あまりにも多く、ステップDEFSは本当に速い複雑ます。)

編集

私は「ウェブの手順を」好きではないされて達成しようとしていること私たちは過去に見ました。一般的な手順はコードを示しておらず、私たちが協力しているビジネスと開発チームと合意した言語でしかありません。私たちが取り組んでいるプロジェクトの多くはクロスプラットフォームなので、どのタイプのステップ定義を使用しているかを切り替えるものを実現しようとしています。 - Chromeを使用している場合は、iOSを使用している場合はこのステップ定義のWebバージョンを使用し、このステップ定義のiOSバージョンを使用するだけでなく、テキスト、シナリオを完全にビジネスベースに保ちながら、ページオブジェクトモデルにリンクすることができます。

Given I am on the "Personal Details" page # (generic) 
When I provide my personal details # (non-generic, but Web, iOS and Android versions exist) 
But leave the "First Name" field blank # (generic) 
And I attempt to continue to the next page # (generic) 
Then I should see a validation error for the "First Name" text box stating: "Please provide your first name" # (generic) 
例えば

、および検証は、ビジネスが機能している知りたい何か、そしてビジネスで合意されている要件のit'aの一部である場合、通信するために、より多くのビジネス理解しやすい方法がありますその情報? - これは、なぜユーザーが情報を入力して検証が表示されないようにしたいのですが、情報を提供しない場合は、それが必要なシナリオ

私たちは、「個人詳細は、」URLのマップで:personal_detailsキーを見つけるようにページオブジェクトモデルを使用します。キーは、:first_nameキーを含むPages.personal_detailsメソッドにリンクする次のステップに渡すことができます。私たちのプロジェクトはすべてこの設定を使用しており、コアヘルパーメソッドライブラリに付属するドキュメントの一部です。私は示唆しています、しかし、間違って使用する場合は、そのまま使用することができた方法で使用されたとき、私は達成しようとしている何

は必ずしも悪い習慣ではありません。

答えて

-1

このようなことがキュウリ自体が行われているとき、キュウリの歴史の中でかなりの数回ありましたが、いくつかの時間前に削除されたウェブのステップを、持っていました。これらは現在、宝石https://github.com/cucumber/cucumber-rails-training-wheelsにあります。あなたのライブラリーのヒントを得るかもしれません。私は強くステップ定義のライブラリを書いていない推薦する、と述べた

。代わりに、ステップ定義で使用できるメソッドのライブラリを作成します。粗い例がこれを説明するのに役立つかもしれません。

は、アプリケーションにログインするための、本当に複雑な方法を考えてみましょう。あなたは

def login(as:, args={})

のようなメソッドを記述し、人々は、このメソッドを使用してみましょうことができ、このような

When I login (hugely complex regex to deal with things like ... # loads of code to deal with you params and regex's and make things work with lots of different scenarios

かのようなもので、ロギングのすべての種類を扱って本当にcommplicatedステップ定義を書くことができます彼らは物事を書くときなど

When 'I login' do 
    login as: @i 
end 

When 'I login as Fred' do 
    login as: create_or_find_user(firstname: 'Fred') 
end 

または

When 'I login as Fred with Jill's password' do 
    login as: @fred, password: @jill.password 
end 

ヘルパーメソッドは、あなたの個々の状況に適したシンプルなステップの定義を書くためのユーティリティを提供しています。共有ステップ定義は、非常に複雑でコンテキスト固有のものを使用できないものを使用することを制限します。

シナリオはコンテキスト固有のもので、個々のワールドのコンテキストに固有の柔軟なシンプルな言語を可能にする必要があります。彼らは、何かが行われていること、何が行われているのか、何かが行われているかについては何も持っていないことについて、すべてでなければなりません。定義によって、それらは共有しないので、定義によってはステップ定義にもなりません。

あなたは、コードの領域にある呼び出しを行うことによって、ステップの定義を残してきた、とコードが

キュウリは、ステップの定義は、(本当に悪い考えです共有教訓を学んだ共有で本当に効果になったらhttp://aslakhellesoy.com/post/11055981222/the-training-wheels-came-off参照)。過去の間違いを繰り返すことには注意してください。

+1

手順のライブラリは、URLのナビゲート、セキュリティテスト、APIテストなどのためのもので、非常に汎用的で、社内向けのものです。しかし、それらは、機能ファイルにコードを表示することなくジェネリックにできるものだけです。私はもっ​​と似ているステップを書いていることを理解しています: "#bar"で "#foo"を書き込むと、特に悪い練習です。 –

+0

リンクされた記事を読んで、私の答えを読み直すことを検討してください。シナリオにはURLが含まれていてはなりません。何かをやっているのですが、WHYではありません。 APIのシナリオでは、APIをどのように呼び出すのかについて、APIを呼び出す理由について説明するべきではありません。実際には一般的なシナリオはありません!シナリオ全体のポイントは、世界に特有のもの、つまりキュウリ:世界は世界と呼ばれ、なぜ物事がグローバルであるのかを書くことです。シナリオ内の各事柄は世界固有のものでなければならず、世界にあいまいさがなければなりません。 – diabolist

+0

おそらく別の質問で一般的だと思ういくつかのステップの具体例を考えてみると、詳細を見ることができます – diabolist

関連する問題