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のキュウリのステップを記述しようとするときに従うべき規則はありますか?
私はこの有用な記事に偶然遭遇しました: 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に対する結果の検証はトリッキーなビジネスです。
プラグマティックプログラマーの「きゅうりの本」が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
現在のプロジェクトでRails-api
を使用して作成したAPIをテストし、さらに重要なことを文書化するために、きゅうりを使用しています。使用するいくつかのツールを探して回り、結局 cucumber-api-steps と json_spec を組み合わせて使用しました。それは私にはうまくいきました。
キュウリのステップの書き方に関する規則はありません。ステップの記述方法は、キュウリスイートの使用方法によって異なります。 Angular JSクライアント開発者がAPIクライアントを実装するためのリファレンスとしてキュウリの出力を使用しました。そのため、キュウリのステップには、実際のJSONリクエストとレスポンス、および各シナリオのステータスコードが含まれていました。これは何かが変更されたとき(特にクライアント側のチームが私の職場に物理的にいないとき)に、クライアント側のチームとのコミュニケーションが本当に簡単になりました。
APIを作成または更新するたびに、CIサーバーはビルドの一部としてキュウリを実行し、HTML形式の出力をブラウザーで開くことができる「build_artifacts」の場所に移動します。クライアント側の開発者は、常に最新の参照をそのように取得します。
このすべてを テストされ、文書化され、バージョン管理されたJSON APIの作成に関するブログ投稿 に書きました。何らかの形で役立つことを願っています。
Cucumberの当初の意図の1つは、設計に貢献し、技術的な実装とビジネスニーズを知っている人々との間のギャップを埋め、テストの説明を開発者以外が記述または理解できるようにすることです。そのため、詳細な技術仕様やブローバイブローの単体テストにはあまり適していません。
それで、それがあなたがCucumberを使用している理由でもあるなら、それは私にあなたの最初のテストの説明を指すでしょう。
2番目のバージョンのようなテストの実装に大きな問題はありません。Cucumberはそれをサポートできます。おそらく、解析する必要のあるステートメントの種類はそれほど多くありません。しかし、最終的にはテストフレームワークと少し競合するか、最初にCucumberを使用するという論理的根拠に反する可能性があります。
慣例として、私は実際にコメントするのに十分なREST APIテストを認識していません。
更新:SOを参照して、これへのリンクを見つけました: https://github.com/jayzes/cucumber-api-steps 2番目の形式により似ています。
サーバーサイドのライブラリがいくつかありますRESTRubyでキュウリを使用してテストします。以下にカップルを示します。
私がサーバー側で使用していたライブラリREST cucumberでのテストは 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':を使用してテストを記述する方法です
@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”
should have key “firstName” with value “Katie”
を行う方法はありません。 「値あり」の部分はまだ行われていません。別のリソースは here ですが、古い(2011)です。
最初のシナリオをお勧めします。
私自身の経験から、ソフトウェア配信方法としてBDDを使用することで得られる最大の価値は、ビジネス価値を重視することだと個人的に感じています。
言い換えると、シナリオは、技術的な実装ではなく、ビジネスが望む行動の例である必要があります。これにより、開発がビジネスの目標によって推進され、成果物が期待に一致することが保証されます。
これは、外部開発と呼ばれます。
システム動作の追加のテストで技術要件をカバーするためにshouldを使用できますが、これらを自然言語で書くことに労力を費やすことは、多くの場合、多くの時間と労力を要するため、あまり価値がないと思いますシナリオの。
次のアプローチをお勧めします。
1)BAとPOと協力して、(最初の例のように)非実装固有の言語を使用して、動作の例を開発します。
2)エンジニアはこれらを使用して、最初のテストアプローチから開発を推進し、統合テストとして自動化します。大部分はブラウザの下(REST APIなど)で)、最もコアなシナリオもブラウザを介して(開発している場合)。
3)ユニットテストとBDDの例の両方に合格するまで、エンジニアはユニットテストで機能コードをTDDします。
最初のほうがいいと思います。私はRubyクラスとモジュールに技術を置きます。たとえば、モジュールcart.add(items)のようにwhenステップとthenステップに入れますexpect(cart.item).to include( 'items' => a_string_matching(item))
これにより、Ruby=クラスとモジュールは、別の機能ステップで再利用できます。たとえば、複数のアイテムをカートに追加して合計金額を検証する別のシナリオがあるとします。
ただ、2つ目は技術的な機能のようにできると思います。たとえば、共通/グローバルヘッダーやボディリクエストなどは、すべてのAPIで期待されています。
ここを参照してください: https://github.com/ctco/cukes-rest 。 RESTful APIをテストするためのCucumber DSLを提供します。