Introduction

Test automation at the HTTP layer in case of web applications and services is increasingly becoming popular and rightly so.

At HTTP layer, you get faster and more stable test automation.

Arjuna supports writing tests at this layer by wrapping various related Python modules (primarily requests and requests_oauthlib), all in one framework.

Note This is currently a beta quality feature. The TPI for the classes and functions is fairly finalized, but prone to minor changes and extensions.

The Http Facade Class

Arjuna provides you with Http as the facade class to start with HTTP automation.

Its features include sending various HTTP method requests, creating a session of requests, handling content types and so on.

Supported HTTP Methods

Currently the following HTTP methods/verbs are supported:

Simulating a request with a given HTTP method is achieved by making correspindingly named methods in Http.

Following are some basic examples of these calls:

Http.get("https://another.com/api/res/someid")
# With relative route. Base/Default URL of Session is prefixed.
Http.get("/res/someid")

Http.delete("/res/someid")

# Content sent as URL encoded
Http.post("/res", content={'a' : 1, 'b': 2})
Http.put("/res", content={'a' : 1, 'b': 2})

All types of requests return an HttpResponse object, which can be inquired to validate or extract data.

You can set custom headers and content type for invidual requests. Explore the Http class documentation.

Handling Content Types

By default the content is URL encoded.

Http class provides various content specifiers. You can use any of the following:

Following is a simple example of sending JSON content:

# Content sent as serialized JSON
Http.post("/res", content=Http.content.json({'a' : 1, 'b': 2}))

Creating an HTTP Session

Beyond basic automation, you will need to send requests as a part of the same session so that cookie management is done automatically for you.

Along with this you also get other benefits in the form of common settings across all requests that are sent as a part of this session.

You can create a new session using Http.session method to create an object of HttpSession.

It supports all the HTTP methods that are supported by Http class.

Following is an example of the most basic construct for creating an HttpSession:

svc = Http.session(url="https://svc.com/api")

The url argument sets the base/default URL for this HttpSession. If relative path is used as a route in sender methods like get(), then this URL is prefixed to their provided routes.

You can add request headers, add OAuth bearer token, set default content handler and so on. Explore the HttpSession class documentation.

Setting a Request Label

All session request methods accept a label argument. This is used in reports and logging to give a user-defined representation of an HTTP request.

Following are basic examples of these calls:

svc.get("/api/res/someid", label="Authorization Request")

Setting Arbitrary Query String Parmaters in URL

A common need in HTTP automation is to set the query parameters in the URL.

One can ofcourse do it with Python string formatting. However, Arjuna makes it easier fpr url-encoded params, the most commonly used format.

You can achieve this for all types of session requests. Following is a get example, where arbitrary key-value arguments are passed to become query parameters:

svc.get("https://app.com/somepath", a=1, something="test")

In the above example, the URL will be

https://another.com/somepath?a=1&something=test

Sometimes, the names in query string are not valid Python names and hence can not be passed as keyword arguments. You can use quer_params argument in such situations.

svc.get("https://app.com/somepath", query_params={'nonpy-name':1, 'something':"test"})

If used in combinations, the keyword arugments will override the values in query_params

svc.get("https://app.com/somepath", query_params={'a':1, 'something':"test"}, a=2)

In the above case, the value of a will be 2:

https://another.com/somepath?a=2&something=test

Checking Expected HTTP Status Code(s)

Inquiring

Status code can be easily inquired:

response = svc.get("/obj/someid")
print(response.status_code)

Asserting

You can also assert status codes by inquiring HttpResponse object as follows:

response = svc.get("/obj/someid")
response.assert_status_codes(200, msg="Your context string")
response.assert_status_codes({200, 404}, msg="Your context string")

xcodes Argument

You can set a session request to raise an HttpUnexpectedStatusCode exception if expected status code is not got:

svc.get("/obj/someid", xcodes=200)

xcodes Argument in strict Mode

You can set a session request to raise an AssertionError exception if expected status code is not got:

svc.get("/obj/someid", xcodes=200, strict=True)

The HttpResponse Object

If a session request is successful it returns an HttpResponse object.

It provides you with various properties to assert or extract data.

Basic Data Extraction

You can easily extract the following data using response properties:

#Response headers
response.headers

# Status Code
response.status_code

# Status Message
response.status

# Request Information
# In case of redirects, this is for the last request
response.request
response.url
response.query_params

Redirections

An HttpResponse object maintains all redirect history.

You can get a sequence of all redirect HttpResponse objects using redir_history property.

You can get the last redirect response using last_redir_response property.

Handling Response Content

You can get formatted as well as un-formatted response content using following properties:
  • text: Unformatted content as plain text

  • html: Response as an HtmlNode object.

  • json: Response as a JsonDict or JsonList object.

Check Parsing JSON, XML, HTML Files and Strings section in documentation to know more about how to parse and extract data from these content type.

Support for Open Authentication (OAuth)

Arjuna supports the following OAuth grant types with its custom HTTP session objects:

OAuth Client Grant Session

Http.oauth_client_grant_session

It wraps the BackendApplicationClient object from requests_oauthlib package.

Once created, the session supports all methods in HttpSession object discussed above.

Explore OAuthClientGrantSession for constructor.

OAuth Implicit Grant Session

Http.oauth_implicit_grant_session

It wraps the MobileApplicationClient object from requests_oauthlib package.

Once created, the session supports all methods in HttpSession object discussed above.

Explore OAuthImplicitGrantSession for constructor.

Creating a New Session from an OAuth Session

Many a times, you will want to reuse the OAuthToken to connect to multiple services for testing.

Rather than creating a token each time, you can create it once by creating OAuthClientGrantSession or OAuthImplicitGrantSession.

Now you can use this OAuth session to create a new HttpSession object for any base URL using create_new_session call.

oauth_session.create_new_session(url="https://someapp.com/api")