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.1.1,flow-ver-1.3.6,,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-5.0.1,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
19 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
          • Kevin Mandeville

            My belief when it comes to writing tests is to not go too far with the DRY principles. At times it makes sense to not repeat something many times like using constants for fields, etc, makes sense. But you can definitely take it way too far in trying to reuse things across tests. When it comes to writing tests I’m a firm believer in following the DAMP (descriptive and meaningful phrases) and not DRY. In writing tests, the most important piece is making sure you are writing thorough but most importantly, easy to ready, tests. If you take DRY principles too far, it becomes harder and harder to look at a single test and understand exactly what it’s testing, what the inputs are and what the outputs are. Think about it from the perspective of coming in to figure out why a test is failing. The more DRY it is, the longer it may take to diagnose where and why the test is failing. I’m completely ok with repeated things across tests if it means my individual tests themselves are easy to understand. Remember, you won’t be deploying your test code.

            April 11, 2017 at 1:37 pm
  • 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
  • Jorge Viana

    When you say “Given a book exists with an isbn of 9781451648546”, you already know this because you had to setup the database somehow prior to running the tests.
    I guess your test should create the book with the desired isbn in the “Given…” step, this way you can freely change the isbn that you want to use in your tests.

    April 18, 2017 at 5:48 am Reply
    • Angie Jones

      Thats one approach to test data management. However, in every application, customers/ testers do not have CREATE ability. This is a perfect example. I’m querying Google’s book API. There is no POST action available for this API.

      Also, in the approach that you mention, there are drawbacks. While it allows greater flexibility, it also increases run time. In a case like this, that might cost an additional second or 2 but those few seconds can add up when you’re dealing with thousands of test. The cost becomes exponential when dynamically creating more complex test data that takes minute(s) to execute programmatically.

      April 18, 2017 at 5:56 am Reply
      • Jorge Viana

        I see what you mean. Thank you for explanation. I always try to learn how to better test my APIs.

        April 18, 2017 at 7:10 am Reply
  • Raveendar Reddy

    @Angie,
    It’s a nice post.. but here I would like to see a framework with REST-Assured which is similar to the below framework..
    https://github.com/intuit/karate
    All I want to write my test cases in feature files. They are competing with REST-Assured.

    July 7, 2017 at 12:46 pm Reply
  • nik

    Business analysts write documentation and then developers implement the code in understandable language for business. i don’t understand why quality assurance engineer write it. I understand, just … ? strange phenomen.

    July 20, 2017 at 12:10 pm Reply
  • nik

    ccucumber not for quality assurance engineer . sorry. but you are also doing another things

    July 20, 2017 at 1:23 pm Reply

Post a Comment