web-dev-qa-db-ja.com

REST APIテストキュウリのステップのベストプラクティス

REST APIテストのキュウリ機能ステップを記述しようとしています。

私はどちらのアプローチが優れているのかわかりません:

Given I log in with username and password
When I add one "tv" into my cart
And I check my cart
Then I should see the item "tv" is in my cart

または

Given the client authenticate with username and password
When the client send POST to "/cart/add" with body "{item: body}"    
Then the response code should be "200"
And the response body should expect "{success: true}"
When the client send GET to "/cart"    
Then the response code should be "200"
And the response body should expect "{"items": ["tv"]}"

REST APIのキュウリのステップを記述しようとするときに従うべき規則はありますか?

21
ccy

私はこの有用な記事に偶然遭遇しました: http://gregbee.ch/blog/effective-api-testing-with-cucumber

要約する...

Scenario: List fruit
  Given the system knows about the following fruit:
    | name       | color  |
    | banana     | yellow |
    | strawberry | red    |
  When the client requests a list of fruit
  Then the response is a list containing 2 fruits
  And one fruit has the following attributes:
    | attribute | type   | value  |
    | name      | String | banana |
    | color     | String | yellow |
  And one fruit has the following attributes:
    | attribute | type   | value      |
    | name      | String | strawberry |
    | color     | String | red        |

結果が配列の場合、要素はテストでの検証方法と同じ順序ではない可能性があるため、JSONに対する結果の検証はトリッキーなビジネスです。

13
bitlather

プラグマティックプログラマーの「きゅうりの本」がCukeを介してREST APIsをテストすることについて述べていることを(十分に近い)例を示します。2番目の例とより密接に関連しているようです。

Feature: Addresses
  In order to complete the information on the place
  I need an address

Scenario: Addresses
  Given the system knows about the following addresses:
   [INSERT TABLE HERE or GRAB FROM DATABASE]
  When client requests GET /addresses
  Then the response should be JSON:
  """
    [
     {"venue": "foo", "address": "bar"},
     { more stuff }
    ]
  """
STEP DEFINITION:

Given(/^the system knows about the following addresses:$/) do |addresses| 
# table is a Cucumber::Ast::Table
  File.open('addresses.json', 'w') do |io|
    io.write(addresses.hashes.to_json)
  end
end    

When(/^client requests GET (.*)$/) do |path|
   @last_response = HTTParty.get('local Host url goes here' + path)
end

Then /^the response should be JSON:$/ do |json|
   JSON.parse(@last_response.body).should == JSON.parse(json)
end
ENV File:

require File.join(File.dirname(__FILE__), '..', '..', 'address_app')
require 'rack/test'
require 'json'
require 'sinatra'
require 'cucumber'
require 'httparty'
require 'childprocess'
require 'timeout'

server = ChildProcess.build("rackup", "--port", "9000")
server.start
Timeout.timeout(3) do
  loop do
    begin
      HTTParty.get('local Host here')
      break
    rescue Errno::ECONNREFUSED => try_again
      sleep 0.1
    end
  end
end

at_exit do
  server.stop
end
7
Whitney Imura

現在のプロジェクトでRails-apiを使用して作成したAPIをテストし、さらに重要なことを文書化するために、きゅうりを使用しています。使用するいくつかのツールを探して回り、結局 cucumber-api-stepsjson_spec を組み合わせて使用​​しました。それは私にはうまくいきました。

キュウリのステップの書き方に関する規則はありません。ステップの記述方法は、キュウリスイートの使用方法によって異なります。 Angular JSクライアント開発者がAPIクライアントを実装するためのリファレンスとしてキュウリの出力を使用しました。そのため、キュウリのステップには、実際のJSONリクエストとレスポンス、および各シナリオのステータスコードが含まれていました。これは何かが変更されたとき(特にクライアント側のチームが私の職場に物理的にいないとき)に、クライアント側のチームとのコミュニケーションが本当に簡単になりました。

APIを作成または更新するたびに、CIサーバーはビルドの一部としてキュウリを実行し、HTML形式の出力をブラウザーで開くことができる「build_artifacts」の場所に移動します。クライアント側の開発者は、常に最新の参照をそのように取得します。

このすべてを テストされ、文書化され、バージョン管理されたJSON APIの作成に関するブログ投稿 に書きました。何らかの形で役立つことを願っています。

6
Emil

Cucumberの当初の意図の1つは、設計に貢献し、技術的な実装とビジネスニーズを知っている人々との間のギャップを埋め、テストの説明を開発者以外が記述または理解できるようにすることです。そのため、詳細な技術仕様やブローバイブローの単体テストにはあまり適していません。

それで、それがあなたがCucumberを使用している理由でもあるなら、それは私にあなたの最初のテストの説明を指すでしょう。

2番目のバージョンのようなテストの実装に大きな問題はありません。Cucumberはそれをサポートできます。おそらく、解析する必要のあるステートメントの種類はそれほど多くありません。しかし、最終的にはテストフレームワークと少し競合するか、最初にCucumberを使用するという論理的根拠に反する可能性があります。

慣例として、私は実際にコメントするのに十分なREST APIテストを認識していません。

更新:SOを参照して、これへのリンクを見つけました: https://github.com/jayzes/cucumber-api-steps 2番目の形式により似ています。

5
Neil Slater

サーバーサイドのライブラリがいくつかありますRESTRubyでキュウリを使用してテストします。以下にカップルを示します。

私がサーバー側で使用していたライブラリREST cucumberでのテストは Cucumber-API-Steps です。

Cucumber-API-Steps

これは、 'cucumber-api-steps'を使用してテストを記述する方法です(推奨):

@success
Scenario: Successfully add to cart
  Given I am logged in
  When I send a POST request to “/cart/add” with the following:
       | item | body |
  Then the response status should be “200”
  And the JSON response should have "success" with the text "true"
  When I send a GET request to “/cart”
  Then the response status should be “200”
  And the JSON response should be "{'items': ['tv']}"

そして、これが私のテストが 'cucumber-api-steps'を使用してどのように見えるかです。

@success
Scenario: Successfully log in
  Given I am logged out
  When I send a POST request to “/login” with:
       | username | [email protected] |
       | password | mypassword |
  Then the response status should be “200”
  And the JSON response should have "firstName" with the text "Katie"

Cucumber-API

これが 'cucumber-api'を使用してテストを記述する方法です

@success
Scenario: Successfully add to cart
  Given I am logged in
  When I send a POST request to “/cart/add”
       And I set JSON request body to '{item: body}'
  Then the response status should be “200”
  And the response should have key “success” with value “true”
  When I send a GET request to “/cart”
  Then the response status should be “200”
  And the response should follow "{'items': ['tv']}"

これが私のテストが 'cucumber-api'を使用してどのように見えるかです

@success
Scenario: Successfully log in
  Given I am logged out
  When I send a POST request to “/login” with:
       | username | [email protected] |
       | password | mypassword |
  Then the response status should be “200”
  And the response should have key “firstName”
  • Cucumber-APIに関する注意:現在should have key “firstName” with value “Katie”を行う方法はありません。 「値あり」の部分はまだ行われていません。
  • また、「フォロー」にはJSONファイルが必要です

別のリソースは here ですが、古い(2011)です。

2
Katie

最初のシナリオをお勧めします。

私自身の経験から、ソフトウェア配信方法としてBDDを使用することで得られる最大の価値は、ビジネス価値を重視することだと個人的に感じています。

言い換えると、シナリオは、技術的な実装ではなく、ビジネスが望む行動の例である必要があります。これにより、開発がビジネスの目標によって推進され、成果物が期待に一致することが保証されます。

これは、外部開発と呼ばれます。

システム動作の追加のテストで技術要件をカバーするためにshouldを使用できますが、これらを自然言語で書くことに労力を費やすことは、多くの場合、多くの時間と労力を要するため、あまり価値がないと思いますシナリオの。

次のアプローチをお勧めします。

1)BAとPOと協力して、(最初の例のように)非実装固有の言語を使用して、動作の例を開発します。

2)エンジニアはこれらを使用して、最初のテストアプローチから開発を推進し、統合テストとして自動化します。大部分はブラウザの下(REST APIなど)で)、最もコアなシナリオもブラウザを介して(開発している場合)。

3)ユニットテストとBDDの例の両方に合格するまで、エンジニアはユニットテストで機能コードをTDDします。

1
ADP

最初のほうがいいと思います。私はRubyクラスとモジュールに技術を置きます。たとえば、モジュールcart.add(items)のようにwhenステップとthenステップに入れますexpect(cart.item).to include( 'items' => a_string_matching(item))

これにより、Ruby=クラスとモジュールは、別の機能ステップで再利用できます。たとえば、複数のアイテムをカートに追加して合計金額を検証する別のシナリオがあるとします。

ただ、2つ目は技術的な機能のようにできると思います。たとえば、共通/グローバルヘッダーやボディリクエストなどは、すべてのAPIで期待されています。

0
Steve Chew

ここを参照してください: https://github.com/ctco/cukes-rest 。 RESTful APIをテストするためのCucumber DSLを提供します。

0
Bernd