Top
Rest-Assured with Cucumber: Using BDD for Web Services Automation – Angie Jones
fade
3687
post-template-default,single,single-post,postid-3687,single-format-standard,eltd-core-1.0,flow-ver-1.3.1,,eltd-smooth-page-transitions,ajax,eltd-grid-1300,eltd-blog-installed,page-template-blog-standard,eltd-header-vertical,eltd-sticky-header-on-scroll-up,eltd-default-mobile-header,eltd-sticky-up-mobile-header,eltd-dropdown-default,wpb-js-composer js-comp-ver-4.12,vc_responsive

Rest-Assured with Cucumber: Using BDD for Web Services Automation

Rest-Assured with Cucumber: Using BDD for Web Services Automation

Behavior Driven Development (BDD) has become a popular approach in communicating requirements between stakeholders of agile teams. In fact, it’s so effective that it’s also being adopted in automation strategies by using Cucumber to write test scenarios in Gherkin (a non-technical, human readable language) and coupling them with an automation framework so that the scenarios are executable in the form that they are originally written.

While many teams use Cucumber to describe their UI testing, this open source software can be used for web service scenarios as well.

For example, here’s a simple scenario that tests Google’s Books API to get a book by its ISBN. This is written in a feature file using Cucumber.

Each line of the scenario would tie to backend code that actually executes the line. Of course, you can automate this from scratch, but there’s a really cool Java testing framework that has done all of the heavy lifting: Rest-Assured. This framework can be used as a standalone automation solution without Cucumber, but it also uses the Gherkin-style Given-When-Then structure so it lends itself quite nicely to being coupled with Cucumber.

Here are the step definitions that the scenario hooks into to enable the execution:

As you can see, Cucumber and Rest-Assured are a match made in “web services automation heaven”! Both technologies are open source, so are free to download and use. And they both are pretty easy and straight forward to configure, so you’ll be up and running in no time.

Here’s the source code on GitHub.

Happy testRESTing!

Angie Jones
12 Comments
  • toks

    Nice article.. I have a quick question if you dont mind

    If you need to reuse the step definition ‘verify_status_code’ (e.g. Status code is 200) in another step definition, how would you go about it? Reason why I am asking is because the ‘response’ object is set by the previous step definition (e.g userRetrieveTheBookByIsbn) and if you call the ‘verify_status_code’ step definition without the userRetrieveTheBookByIsbn step definition in another step definition class, I believe a null pointer exception will be returned.

    Cucumber tends to support re use of step definition. In other words, if you want to verify the response status code for a service call in another step definition class and you type ‘the status code is’ within your feature file, I believe the already defined step (i.e. in BookStepDefinitions class) would be suggested. If you then re-use this step without using the previous step that actually sets the response object, exception will be returned.

    How would you go about doing this?

    August 31, 2016 at 12:59 pm Reply
    • Angie Jones

      Hi Toks,

      Yes, if you’re going to have multiple step definition files, you’ll need to use dependency injection (DI). There’s several options: PicoContainer, Spring, OpenEJB, etc. If you’re not already using DI, then I recommend PicoContainer. Otherwise, use the one that’s already in use, because you should only have one.

      First thing you’ll need to do is add the dependency to your pom file:

      Next, create a new class that holds the common data. For example:

      Then, in each of your step definition files that you want to use this common data, you can add a constructor that takes StepData as an argument. This is where the injection occurs. For example:

      Then you can use stepData to access all of the common fields needed across your step definition classes. For example, I can split the BookStepDefinitions class into two classes:

      Then in another file:

      This will allow you to share the state of the fields in StepData with all of your step definition files. More on DI for Cucumber is here:
      https://cucumber.io/docs/reference/java-di

      August 31, 2016 at 8:21 pm Reply
      • toks

        Thanks for your swift reply and your work out here is greatly appreciated. I understand the concept of dependency injection that you’ve explained and I do use it as well. However, if for any reason you have the same step in 2 different feature files e.g. Feature A and Feature B.

        The particular step is defined in the step definition for Feature A and its also available for re-use within Feature B. e.g.

        Feature A
        Scenario: Retrieve book with ISBN
        Given ….
        When …
        Then the status code is 200

        Feature B
        Scenario: Add book to a catalogue
        Given ….
        When …
        Then the status code is 200

        My question is more like, if you have ‘verify_status_code’ in both BookStepDefinitions and SecondStepDefinitions (but ‘verify_status_code’ is implemented in BookStepDefinitions), Would you re-use the step defined in Feature A in Feature B or would you create another step (doing the same thing) with a different name in Feature B (DRY) ?

        Also, I noticed that you moved ‘verify_status_code’ from BookStepDefinitions to SecondStepDefinitions, any reason for this?

        September 1, 2016 at 1:01 pm Reply
        • Angie Jones

          I would definitely reuse the step definition. But I wouldn’t leave it in BookStepDefinitions anymore because now it’s common. I would add a new file CommonStepDefinitions and move the verify_status_code to there so that it’s clear that this particular step is one that is applicable to more than one area. Any other steps that you come across that are common can be moved here as well.

          No reason why I moved this method in my example other than to illustrate the global scope of the steps. 🙂

          September 2, 2016 at 7:52 am Reply
  • Renzo

    Hey Angie, thank you for the amazing explanation, it has helped me a lot in setting up my own framework. I did have a question though, and hopefully you can help me.

    I have created a StepData class for all my common data to be shared among the stepdefs. However, I’m also using the @Before annotation of Cucumber for setting up my test which can currently be found in all my Stepdefinitions. As they are all the same, I was wondering whether it is ok to move the method to the StepData class?

    January 13, 2017 at 10:05 am Reply
    • Angie Jones

      Renzo, so glad it’s been helpful 🙂 Yes, move the @Before to the common file. You don’t want to have it repeated in multiple files. As a rule of thumb, whenever you find yourself repeating yourself (duplicating code), it’s a sign to refactor and move the code to a central place where it can be shared across.

      January 13, 2017 at 11:31 am Reply
  • Vacha

    Hey Angie,

    Thanks for the wonderful post. Might not be exactly related to Rest assured, but can you give me some starting points on micro-services testing automation framework. I am getting few theoretical concepts but not anything concrete as in how to organize it with BDD-Cucumber like we just did here.

    January 20, 2017 at 10:02 pm Reply
  • callel
    January 27, 2017 at 12:37 pm Reply
  • st

    That was an excellent post and really helpful! I was wondering if you had a chance to implement Serenity with Cucumber-Rest Assured combination. The pico-container DI does not seem to work with Serenity and I am struggling to have the injection done.

    February 9, 2017 at 9:15 pm Reply
  • Minoti Singh

    Thanks a lot.
    Very informative article.
    can you explain me how do we run this project in Eclipse or using cmd prompt for Maven

    March 16, 2017 at 5:30 am Reply
  • Nils

    I am very much thankful to you as this post has helped me a lot in automating web services.
    I have a question on composite/nested service request.
    I am able to get the response for non composite/ non nested service request by using
    response = when().get(“ENDPOINT”);
    But how do I validate composite/nested service request?

    My requirement is I have endpoint say “http://localhost:8080/{company}/{employID}”, now when I hit this main-endpoint it internally makes another Get request to sub-endpoint say “http://localhost:8080/{company}” and get the response_1, depending on this response_1 status/content it will make Get call to the main-endpoint and get response_2.

    Now I want to capture intermediate response_1 and perform some json validation and based on this proceed to main endpoint. Any suggestion is of more help and much appreciated. Thanks.

    March 22, 2017 at 8:54 am Reply

Post a Comment