Acceptance Test Robot Framework: Test returned JSON by Rest API

API testing is one of common jobs in automation tests, especially when multiple teams work on different parts of a system and use API as the mean of communication between components.

We will examine how Robot Framework can help us to test the API, let’s say REST API that return JSON results.

To access REST API, we need to use a HTTP Library. Standard Libriries from Robot Framework does not include this, so we need to manually into this addon.

pip install --upgrade robotframework-httplibrary

Then, let’s get started to test our API!

Wait, where is our API to test? We don’t have one, but luckily enough, there is free service to build sample APIs that we can use apiary.io, it is a great tool to mock API calls, i.e. you can trap the call requests and return any dummy data you want without writing any real logic. In short, no coding required!

Just register then it gives us a default API sample that we can use in our test immediately:

//http://private-2012e-nguyenthethang.apiary-mock.com/questions?page=1

[  
   {  
      "published_at":"2015-07-10T05:49:29.577344+00:00",
      "choices":[  
         {  
            "url":"/questions/62/choices/265",
            "votes":0,
            "choice":"Android"
         },
         {  
            "url":"/questions/62/choices/264",
            "votes":0,
            "choice":"Bot"
         },
         {  
            "url":"/questions/62/choices/266",
            "votes":0,
            "choice":"God"
         },
         {  
            "url":"/questions/62/choices/263",
            "votes":0,
            "choice":"Human"
         }
      ],
      "url":"/questions/62",
      "question":"Who Are You?"
   },
...
]

Let’s create our test file api.robot. We start by importing the library and make the very first test: make sure our request will return a successful status (status=200)

*** Settings ***
Documentation                 Test our very first REST API
Library                       HttpLibrary.HTTP
*** Variables ***
${API_ENDPOINT}               http://private-2012e-nguyenthethang.apiary-mock.com

*** Test Cases ***
List Question Request Should Return Successful
  GET                                   ${API_ENDPOINT}/questions
  Response Status Code Should Equal     200

Now, run our console to check result:

pybot api.robot
==============================================================================
Api :: Test our very first REST API
==============================================================================
List Question Request Should Return Successful                        | PASS |
------------------------------------------------------------------------------
Api :: Test our very first REST API                                   | PASS |
1 critical test, 1 passed, 0 failed
1 test total, 1 passed, 0 failed
==============================================================================
Output:  /Users/justin/robotframework/APITest/output.xml
Log:     /Users/justin/robotframework/APITest/log.html
Report:  /Users/justin/robotframework/APITest/report.html

Next, we will write some tests to verify the content of the API response. Let’s check if the response contains the correct number of items (1 item in the mock data, we can create more if we want). It takes several steps to do so:

  • Grab the response result
  • Convert it into JSON
  • Examine the JSON object

Here is our test content:

List Question Requset Should Return Correct Number Of Items
  GET                                   ${API_ENDPOINT}/questions
  ${result} =         Get Response Body
  ${json} =           Parse Json                            ${result}
  Length Should Be    ${json}                               10

That’s good. Our tests pass beautifully. But we should refactor it a little bit so that it looks nicer and descriptive enough.

*** Settings ***
Documentation                 Test our very first REST API
Library                       HttpLibrary.HTTP
*** Variables ***
${API_ENDPOINT}               http://private-2012e-nguyenthethang.apiary-mock.com

*** Test Cases ***
List Question Request Should Return Successful
  Get Question list
  Response Status Code Should Equal     200

List Question Requset Should Return Correct Number Of Items
  Get Question list
  ${json} =           Parse Response Body To Json
  Length Should Be    ${json}                               10

*** Keywords ***
Get Question list
  GET                                   ${API_ENDPOINT}/questions

Parse Response Body To Json
  ${result} =         Get Response Body
  ${json} =           Parse Json                            ${result}
  [Return]            ${json}

So we have DRYed it a bit and know that a keyword can return data. Next, let’s try to make a POST request, it is also a very common case.

You can find an API to create question at apiary editor, according to it, we need to send following JSON data to server:

{
  "question": "Favourite programming language?",
  "choices": [
    "Swift",
    "Python",
    "Objective-C",
    "Ruby"
  ]
} 

This API will return the created question detail as response, so we not only test if it is 200, but also double check the result.

*** Settings ***
Documentation                 Test our very first REST API
Library                       HttpLibrary.HTTP

*** Variables ***
${API_ENDPOINT}               http://private-2012e-nguyenthethang.apiary-mock.com
${QUESTION_JSON_DATA}         { "question": "Favourite programming language?", "choices": [ "Swift", "Python", "Objective-C", "Ruby" ] }

*** Test Cases ***
Create Question Should Return Success
  Create Http Context                   private-2012e-nguyenthethang.apiary-mock.com    http
  Set Request Header                    Content-Type          application/json
  Set Request Body                      ${QUESTION_JSON_DATA}
  POST                                  /questions
  Response Status Code Should Equal     200

Code is self-explanatory: we set the necessary headers and body and send it, it would return desired 200 status. We want to compare the returned result with our expected result, particular this response:

{
    "question": "Favourite programming language?",
    "published_at": "2014-11-11T08:40:51.620Z",
    "url": "/questions/2",
    "choices": [
        {
            "choice": "Swift",
            "url": "/questions/2/choices/1",
            "votes": 0
        }, {
            "choice": "Python",
            "url": "/questions/2/choices/2",
            "votes": 0
        }, {
            "choice": "Objective-C",
            "url": "/questions/2/choices/3",
            "votes": 0
        }, {
            "choice": "Ruby",
            "url": "/questions/2/choices/4",
            "votes": 0
        }
    ]
}

But this content is rather long, if we put it in our test file, it would be a little bit messy, therefore we will put it into an external file and read it into our test case. To do that, we import the library OperatingSystem from Standard Libraries.

*** Settings ***
Documentation                 Test our very first REST API
Library                       HttpLibrary.HTTP
Library                       OperatingSystem

*** Test Cases ***
Create Question Should Return Success
  Create Http Context                   private-2012e-nguyenthethang.apiary-mock.com    http
  Set Request Header                    Content-Type          application/json
  Set Request Body                      ${QUESTION_JSON_DATA}
  POST                                  /questions
  Response Status Code Should Equal     200
  ${result} =                           Parse Response Body To Json
  ${expectation} =                      Parse Json From File 
  Should Be Equal                       ${result}                ${expectation}

*** Keywords ***
Parse Json From File
  ${file} =                             Get File    question_detail.json
  ${json} =                             Parse Json    ${file}
  [Return]                              ${json}

Note that Apiary supports multiple mode, in Production mode, your requests can change data on server. So far we should always use Mock Server mode, so that it returns what we config it to be. Otherwise the test case maybe much more complex than the scope of this post. Such as primary key value and timestamp values always change and difficult to test.

You may notice that we parse Json into objects and compare them. It is pretty difficult to compare 2 json objects somehow.

In the end, we have done our important test cases, let’s refactor the code so that it looks tidier.

*** Settings ***
Documentation                 Test our very first REST API
Library                       HttpLibrary.HTTP
Library                       OperatingSystem
Test Setup                    Create API Context

*** Variables ***
${API_ENDPOINT}               http://private-2012e-nguyenthethang.apiary-mock.com
${QUESTION_JSON_DATA}         { "question": "Favourite programming language?", "choices": [ "Swift", "Python", "Objective-C", "Ruby" ] }

*** Test Cases ***
List Question Request Should Return Successful
  Get Question list
  Response Status Code Should Equal     200

List Question Requset Should Return Correct Number Of Items
  Get Question list
  Question List Should Have Correct Length
  

Create Question Should Return Success
  Make Question Creation Request
  Response Status Code Should Equal     201
  Created Question Details Should Be Correct

*** Keywords ***
Create API Context
  Create Http Context                   private-2012e-nguyenthethang.apiary-mock.com    http

Make Question Creation Request
  Set Request Header                    Content-Type          application/json
  Set Request Body                      ${QUESTION_JSON_DATA}
  POST                                  /questions

Question List Should Have Correct Length
  ${json} =                             Parse Response Body To Json
  Length Should Be                      ${json}                               1

Created Question Details Should Be Correct
  ${result} =                           Parse Response Body To Json
  ${expectation} =                      Parse Json From File
  Should Be Equal                       ${result}                ${expectation}

Get Question list
  GET                                   /questions

Parse Json From File
  ${file} =                             Get File    question_detail.json
  ${json} =                             Parse Json    ${file}
  [Return]                              ${json}

Parse Response Body To Json
  ${result} =                           Get Response Body
  Log                                   ${result}
  ${json} =                             Parse Json                            ${result}
  [Return]                              ${json}

By moving the techinical details into keywords we make our test cases more decriptive as natural languages. Just by reading the test cases, people can easily grasp what we are trying to prove. If a long time later we come back and look at the tests, we still understand it clearly and easily.

Summary, this post demonstrates:

  1. Ability of Robot Framework to test Rest API
  2. Ability to read content from file
  3. Encode/decode JSON content
  4. Usage of Apiary as mock server

文章来源:http://nguyenthethang.com/2015/07/14/acceptance-test-robot-framework-test-returned-json-by-rest-api/

posted @ 2016-02-24 18:22  老张测试  阅读(260)  评论(0)    收藏  举报