Giter Site home page Giter Site logo

cucumber-api-steps's Introduction

cucumber-api-steps

Build Status Gem Version

A set of Cucumber step definitions utilizing Rack-Test that ease basic testing of REST-style APIs using either XML or JSON formats.

Adapted from a blog post by Anthony Eden with a few additions based on my own needs. I found myself copying these step definitions around to multiple projects, and decided that it would be worthwhile to gem them up to keep things nice and DRY.

Dependencies

Requires Cucumber (obviously). Also makes use of JSONPath for setting criteria against JSON responses. See the gemspec for more info.

Installation

Add the following line to your Gemfile, preferably in the test or cucumber group:

gem 'cucumber-api-steps', :require => false

Then add the following line to your env.rb to make the step definitions available in your features:

require 'cucumber/api_steps'

Usage

Still a work in progress. For now, read the api_steps.rb file or check out the stashboard-rails project - its Cucumber features make extensive use of the steps in this gem.

Examples

Feature: API

  Scenario: List tweets in JSON
    When I send and accept JSON
    And I send a GET request to "/api/tweets"
    Then the response status should be "200"
    And the JSON response should be:
      """
      [{"tweet":"Hello World!"},{"tweet":"New Rails has been released"}]
      """
    And the JSON response should have "$..tweet" with the text "Hello World!"
    And the JSON response should have "$..tweet" with a length of 2

  Scenario: List tweets in XML
    When I send and accept XML
    And I send a GET request to "/api/tweets"
    Then the XML response should have "tweet" with the text "Hello World!"

  Scenario: Post tweet using POST-params
    When I send a POST request to "/api/tweets" with the following:
      | tweet | Hello World! |
      | lat   | 42.848282    |
      | lng   | 74.634933    |
    Then the response status should be "201"

  Scenario: Post tweet using json in POST body
    When I send a POST request to "/api/tweets" with the following:
      """
      {"tweet":"Hello World!","lat":"42.848282", "lng":"74.634933"}
      """
    Then the response status should be "201"

  Scenario: Basic authentication
    When I authenticate as the user "joe" with the password "password123"
    And I send a GET request to "/api/tweets"
    Then the response status should be "200"

  Scenario: Digest authentication
    When I digest-authenticate as the user "joe" with the password "password123"
    And I send a GET request to "/api/tweets"
    Then the response status should be "200"

Contributors

  • Jay Zeschin
  • Justin Smestad
  • Kevin Pfefferle
  • Kalys Osmonov
  • Mingding Han
  • Gabe Varela
  • Steven Heidel
  • Adam Elhardt
  • Gonzalo Bulnes Guilpain

Copyright

Copyright (c) 2011 Jay Zeschin. Distributed under the MIT License.

cucumber-api-steps's People

Contributors

daleki avatar edenvicary avatar glaszig avatar gonzalo-bulnes avatar gvarela avatar hanmd82 avatar jayzes avatar jsmestad avatar kalys avatar kpfefferle avatar legolin avatar ms-ati avatar rrooding avatar splisson avatar spone avatar tgautier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cucumber-api-steps's Issues

Add token and JWT authentication

As of now, if I'm not mistaking, the gem is only supporting authentication using Basic auth.

What about token based authentication (In the path or HTTP Authorization header) and Json Web Token (JWT http://jwt.io) ?

Support non Rack-Test calls

This library is exactly what we want to use to externally test our API's, but we can't use Rack-Test. Is there any interest in me creating a pull-request that would offer a remote implementation? I guess I would lean towards using rest-client, but if you guys want something else that's fine too.

Let me know if you'd like to open a dialog on this.

Cucumber-ruby 3.0 compatibility issues

After upgrading to cucumber-ruby 3.0, I've started seeing this error:

uninitialized constant Cucumber::Ast (NameError) # cucumber-api-steps-0.13/lib/cucumber/api_steps.rb:39

After copying lib/cucumber/api_steps.rb directly into my features/support directory and removing require cucumber/api_steps, the issue was resolved - which makes sense, since cucumber-api-steps makes no direct reference to Cucumber::Ast.

So there has to be some dependency that is still using it that isn't jsonpath or nokogiri (since those are required at the top of api_steps.rb, which works on its own).

last_response

When sending 2 requests in one scenario like:

When I send and accept JSON
And I send a POST request to "/nl/parks/1/categories/1/reservations.json?api_key=123_abc" with the following:
  """
  {
    "reservation": {
      "start_date": "2011-10-10",
      "end_date": "2011-10-17",
      "number_of_people": 4,
      "email": "[email protected]",
      "phone": "0612345678",
      "initials": "J.",
      "last_name": "Doe",
      "address": "Street",
      "number": "1",
      "postalcode": "1234AB",
      "city": "Enschede",
      "country": "Nederland",
      "extras": {
        "1": 1
      }
    }
  }
  """
Then the JSON response should have "$..email" with the text "[email protected]"
 And the JSON response should have "$..arrival_date" with the text "2011-10-10"
 And the JSON response should have "$..checkout_date" with the text "2011-10-17"
 And the JSON response should have "$..number_of_people" with the text "4"
 And the JSON response should have "$..confirmed" with the text "false"

When I send a PUT request to the last reservation api confirm url
Then the JSON response should have "$..confirmed" with the text "true"

The last JSON response should... refers to the first response
I identified this by calling:

Show me the page

And outputting the send parameters for the action.
I also double checked the fact that it calls 2 separate actions.

Bottom line:

api_steps.rb#78:

 json    = JSON.parse(last_response.body)

Returns the wrong body

undefined method `last_response'

undefined method `last_response' for #<Capybara::RackTest::Driver:0x000001037f3c18> (NoMethodError)

#cucumber-api-steps-0.4/lib/cucumber/api_steps.rb:39

I found one recent reference to this error at http://pastie.org/pastes/2061958

Any idea what would cause this? Using page.driver.response seems to fix this.

Getting undefined method `length' for #<Cucumber::Ast::Table:0x00000105b3d9a8> (NoMethodError)

Scenario: post a simple email # features/post_message.feature:7
When I send a POST request to "/api/v1/messages" with the following: # features/step_definitions/api_steps.rb:27
| to | from | subject | plain |
| [email protected] | [email protected] | che palle | la vita e' bella per chi se sgharbella |
undefined method length' for #<Cucumber::Ast::Table:0x00000105b3d9a8> (NoMethodError) ./features/step_definitions/api_steps.rb:28:in/^I send a POST request to "([^"]*)" with the following:$/'
features/post_message.feature:8:in `When I send a POST request to "/api/v1/messages" with the following:'

the only way to make it work is to change the step to:
When /^I send a POST request to "([^"]*)" with the following:$/ do |path, body|
page.driver.post path, body.hashes.first
end

What am I missing here?

Thanks,
-Matteo

Error while extending step definitions in Rails project

If I copy the step definition that makes the request from the gem and paste it in the features/step_definitions/custom_steps.rb (with some parameter modifications) and use this custom step in a scenario, the JSON response step throws the following error :

No response yet. Request a page first. (Rack::Test::Error)

I can see that the controller action is receiving the request and a Rack::MockSession is created. Any clue why the error occurs ?

I know it's hard to understand the problem with such a vague description. Please let me know what other information will be helpful to point out the problem here. Thanks !

getting private method `present?' called for #<Cucumber::Ast::Table:0x000000038cac28> (NoMethodError)

Scenario: Adding new poi in json format # ../add_new_poi/add_new_poi.feature:5
When I send a POST request to "my/api/url" with the following: # cucumber-api-steps-0.10/lib/cucumber/api_steps.rb:24
| name | tester |
| lat | 42.3444 |
| lng | 23.9940 |
private method present?' called for #<Cucumber::Ast::Table:0x000000038cac28> (NoMethodError) ../add_new_poi/add_new_poi.feature:7:inWhen I send a POST request to "my/api/url" with the following:'

What i missed here?

No longer compatible wtih json_spec

The two gems are often used together, but I found that as of:
9692bb1#diff-4a6e5a18c593cf41a8e1174bfd5afd41

I could no longer use both gems since the 'should have' step creates ambiguous match with json_spec from collective_idea. For now, I'm rolled back to 0.10 of api-steps, but would love to figure out how to use both gems without generating ambiguous match errors.

host required

Hi,

In a Rails app using Capybara, in order to use the "I send a XXX request to…" step definitions, I needed to specify the host otherwise it would always 404. Therefore I now provide page.driver.send with a fully-fledged path in the step definition. I did that the brutal way by adding the following piece of code in the step definition, before the final if/else:

current_host = Capybara.app_host || Capybara.default_host
path = current_host + path

Capybara's internals (see Capybara::RackTest::Browser#process) feature a more subtle way of handling the issue.

Still, I am not sure how it should be fixed in cucumber-api-steps. Food for thoughts!

Ignore default fields in JSON response

How to ignore fields?
For example,

{  
  "data"  =>  {  
    "id"    =>"1",
    "type"    =>"user",
    "attributes"    =>    {  
      "name"      => "Test",
      "token"      =>"ZnJhY3RhbDEyMw2"
    }
  }
}

I want to ignore the token field.

Usage with Rack

Hey, here's a quick fix for using the API steps with Rack. Before, all steps would fail because the JSON::Pure::Parser was initialized with a Rack::MockResponse which it couldn't handle:

# Monkey patch Rack::MockResponse to work with the cucumber API steps:
class Rack::MockResponse
  def to_str
    body
  end
end

I included this in my features/support/env.rb and though this might be worth sharing – maybe you can update the README or include the patch in the gem.

With kind regards,
Paul

DEPRECATION: Using `should`

DEPRECATION: Using should from rspec-expectations' old :should syntax without explicitly enabling the syntax is deprecated. Use the new :expect syntax or explicitly enable :should with config.expect_with(:rspec) { |c| c.syntax = :should } instead. Called from /home/yuan/.rvm/gems/ruby-2.0.0-p598/gems/cucumber-api-steps-0.13/lib/cucumber/api_steps.rb:151:in `block in <top (required)>'.

How i fix it. please help me.

Given I send and accept JSON          # cucumber-api-steps-0.13/lib/cucumber/api_steps.rb:21
      undefined local variable or method `app' for #<Object:0x007ffc32d779f0> (NameError)

XML response should have - text comparison with number input

Using from api_step.rb the step:
the XML response should have "field" with the text "1234"

The string "1234" enters the body of the step as the argument named 'text'.
In the body the 'text' has class 'Fixnum' in stead of 'String.

The comparison between the element found and the text argument fails because the classes dont match.

Simple fix is to transform text explicitly to class String with the method 'to_s'

undefined method 'header'

Hi everyone,
i am quite new to cucumber and testing REST API´s. But i have the following problem.

I installed the latest version of cucumber-api-steps (v0.13) and when i run a feature file i get the error mentioned above in the GIVEN step.

"undefined method 'header'

My feature file looks l ike this:

Feature: API

Scenario: list all products
Given I send and accept JSON
When I send a GET request to "any URL"
Then the response should be "200"

I followed the installation steps in the Readme file,
I am using ruby 2.2.0.

Version Bump ?

Hi,

I tried your gem but the version deployed to rubygems is outdated compared to your master. Have you plan a next release ?

Thanks for your work that helps me a lot,
Kevin

required ruby version

I noticed that you fixed required ruby version issue but it seems that you didn't pushed the changes to RubyGem host, did you ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.