Test de L'API REST cucumber étapes pratiques exemplaires
Essaie d'écrire des concombres fonction des étapes pour le REPOS de l'API de test.
je ne suis pas sûr que l'approche qui est mieux:
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
ou
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"]}"
est-ce qu'il y a une convention à suivre quand les gens essayent d'écrire des pas de concombre pour L'API REST?
8 réponses
je viens de tombé sur cet article utile: http://gregbee.ch/blog/effective-api-testing-with-cucumber
Pour résumer...
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 |
valider un résultat contre JSON est une affaire délicate car si le résultat est un tableau, les éléments peuvent ne pas être dans le même ordre que la façon dont vous validez dans le test.
voici un exemple (assez proche) de ce que le programmeur pragmatique "the Cucumber Book" dit à propos de tester les APIs REST via Cuke,et il semble se rapporter plus étroitement à votre second exemple:
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
j'ai utilisé cucumber pour tester et surtout pour documenter l'API que j'ai créé en utilisant rails-api
dans mon projet en cours. J'ai cherché quelques outils à utiliser et j'ai fini par utiliser une combinaison de concombre-api-étapes et json_spec. Il a bien fonctionné pour moi.
Il n'y a pas de convention sur la façon d'écrire le concombre étapes. La façon dont vous écrivez vos étapes dépend de la façon dont vous souhaitez utiliser votre concombre suite. J'ai utilisé la sortie de concombre comme référence pour nos devs client js angulaires pour implémenter le client API. Donc mes étapes de concombre contenaient les requêtes et les réponses réelles JSON ainsi que le code d'État pour chaque scénario. Il était donc très facile de communiquer avec une équipe du côté du client chaque fois que quelque chose changeait ( surtout lorsque l'équipe du côté du client n'était pas physiquement présente à mon lieu de travail ).
chaque fois que je créais ou mettais à jour une API, le serveur CI exécutait cucumber dans le cadre de la construction et déplaçait le HTML sortie formatée à un emplacement "build_artifacts" qui peut être ouvert dans le navigateur. Les responsables du côté client obtenaient toujours la référence la plus récente de cette façon.
j'ai écrit tout cela dans un blog sur la création d'un testées, documentées et versionné API JSON, j'espère qu'elle vous aide en quelque sorte.
une des intentions originales de Cucumber, qui contribue à sa conception, est de combler le fossé entre la mise en œuvre technique, et les gens qui connaissent les besoins de l'entreprise, de sorte que les descriptions de test pourraient être rédigés et/ou compris par des non-développeurs. En tant que tel, ce n'est pas un idéal détaillée des spécifications techniques, ou coup par coup, les tests unitaires.
donc, cela m'indiquerait votre première description de test, si c'est aussi la raison pour laquelle vous utilisez le concombre.
il n'y a pas problème majeur avec la mise en œuvre de tests comme la deuxième version, Cucumber peut le supporter. Il n'y a probablement pas un grand nombre de types d'énoncés que vous devriez analyser non plus. Mais vous pourriez finir par combattre le cadre de test un peu, ou aller à l'encontre de votre raison d'utiliser le concombre en premier lieu.
pour ce qui est d'une convention, Je ne suis pas au courant de suffisamment de tests de L'API REST dans la pratique pour commenter, et aucun que j'ai vu testé ont utilisé le concombre comme le Framework.
mise à Jour: Navigation autour de SORTE que sur le sujet, j'ai trouvé un lien: https://github.com/jayzes/cucumber-api-steps qui est plus semblable à votre deuxième format.
il y a quelques bibliothèques maintenant pour les tests de REST côté serveur avec cucumber dans Ruby. Voici un couple:
- Concombre-API-Étapes. (Recommandé)
- concombre-API. Un petit tutoriel pour que ici.
la bibliothèque que j'ai utilisée pour les tests de REST côté serveur avec cucumber est Concombre-API-Étapes.
Concombre-API-Étapes
Voici comment j'écrirais votre test en utilisant 'concombre-api-étapes" (Recommandé):
@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']}"
et voici à quoi mes tests ressemblent en utilisant 'concombre-api-étapes":
@success
Scenario: Successfully log in
Given I am logged out
When I send a POST request to “/login” with:
| username | katie@gmail.com |
| password | mypassword |
Then the response status should be “200”
And the JSON response should have "firstName" with the text "Katie"
concombre-API
Voici comment j'écrirais votre test en utilisant 'concombre-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']}"
et voici à quoi mes tests ressemblent en utilisant 'concombre-api':
@success
Scenario: Successfully log in
Given I am logged out
When I send a POST request to “/login” with:
| username | katie@gmail.com |
| password | mypassword |
Then the response status should be “200”
And the response should have key “firstName”
- Remarque à propos de Concombre-API: Il n'y a aucun moyen actuellement de faire
should have key “firstName” with value “Katie”
. La partie "avec valeur" n'a pas encore été faite. - Également "Suivre" s'attend à un fichier JSON
une Autre ressource est ici, mais il est vieux (2011).
je pense que le premier est mieux. Je mettrais la technique dans les classes et les modules ruby. E. g comme le module panier.ajouter(articles) dans la lors de l'étape et l'étape puis mettre attendre(cart.l'élément).à include('articles' => a_string_matching(item))
ainsi, les classes et modules ruby peuvent être réutilisés dans d'autres étapes de fonctionnalités. Par exemple, comme peut-être vous avez un autre scénario qui ajouterait plusieurs articles dans le panier puis valider le montant total.
cependant, le second 1 je pense peut le rendre comme des caractéristiques techniques. Par exemple, une requête d'en-tête ou de corps communs/globaux est attendue dans toute l'api.