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?

18
demandé sur Paulo Fidalgo 2013-05-24 22:32:53

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.

12
répondu bitlather 2014-08-13 03:02:26

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
7
répondu Whitney Imura 2013-06-05 19:20:47

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.

6
répondu Emil 2013-08-02 09:09:23

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.

5
répondu Neil Slater 2013-05-30 23:57:54

il y a quelques bibliothèques maintenant pour les tests de REST côté serveur avec cucumber dans Ruby. Voici un couple:

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).

1
répondu Katie S 2016-09-01 16:54:13

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.

0
répondu Steve Chew 2016-01-11 03:19:21