Test automation with Ansible
Automation
Did you know that you can automate your REST API tests using Ansible? This tool which is usually associated with app and infrastructure automation can also be used to perform API tests.
In this article, we will take a brief look at Ansible test automation.
Ansible core module
No additional modules are needed to start writing tests – core Ansible module called „uri” will be used. This module ensures communication with api resources and allows to conveniently check the operation of REST API.
In the following sections, we will write sample plays that will be used for api tests.
Play’s structure
Play used for API testing will take the following form:
- name: Template
hosts: localhost
tasks:
- name: Template task
uri:
url: "/some/path"
method: POST
body_format: json
body: "param: value"
validate_certs: false
return_content: yes
register: return_data
The task „Template task” is designed to:
- send POST request (method: POST) to the endpoint „/some/path” (url: “/some/path”),
- send username and password in the request’s body (body: […]) in JSON format (body_format: json),
- save the response from the API to the variable „return_data” (register: return_data).
For testing purposes, it is worth using the „validate_certs” option, which allows the use of self-signed certificates without getting errors.
Caution! By default, Ansible expect a „200 OK” response to conclude that the request was successful. If you need to check a different response code, use the „status_code: expected status code” option.
Example tests – logging into the application, sending GET request and logging out
In this section, we will use Ansible to obtain user’s authorization token, send GET request to the secured endpoint and then send a user logout request. These simple tests will check basic operations performed by the API.
Logging in
To login to the API using a POST request, use the following play:
- name: Login to the system
hosts: localhost
tasks:
- name: Login to the system
uri:
url: "api/auth/login"
method: POST
body_format: json
body: "{\"username\": \"user123\", \"password\": \"1qaz@WSX\"}"
validate_certs: false
return_content: yes
register: token_data
This request uses the aforementioned template, only the request body was changed to take a form suitable for logging in with a username and password.
After executing this request, the authorization token will be saved to the „token_data” variable (register: token_data).
Sending GET request
To send a GET request to the API resource using the previously obtained token to authorize the user, use the following play:
- name: Obtain list of objects
hosts: localhost
tasks:
- name: Obtain objects
uri:
url: "api/some/other/path"
headers:
Authorization: "Bearer {{ token_data.json.token }}"
validate_certs: false
return_content: yes
register: data_objects_all
- name: Print objects
debug:
msg:
- "{{ item.id }}"
loop: "{{ data_objects_all.json }}"
loop_control:
label: "{{ item.id }}"
extended: yes
The code above sends a GET request (it is the default method so you do not have to specify it like you did with POST request) to the API resource, and then prints the received data in the terminal window.
The first task uses the template with an additional code responsible for user authorization (headers: […]). This snippet will add the „Authorization: Bearer ” header to the request. Note that in order to refer to a variable defined earlier in the code, you use „{{ variable_name }}” construct.
In our case, we want to get data from a variable in JSON format from the parameter called „token” so we use „{{ token_data.json.token }}”
The second task is designed to list the received objects. For this purpose, we will use „debug” and „msg” instructions and the „loop” to go over all elements received. The iteration will be performed on the received objects in JSON format (loop: „{{ data_objects_all.json }}”). In order not to print the whole object during each step of the loop, „label” option will be used (label: „{{ item. id }}”).
Logging out
To logout we send a DELETE request to the endpoint using the following play:
- name: Logout
hosts: localhost
tasks:
- name: Delete user session
uri:
url: "api/auth/path"
method: DELETE
status_code: 204
headers:
Authorization: "Bearer {{ token_data.json.token }}"
validate_certs: false
Once again we use the template and change it so that the DELETE method is used (method: delete) and the task expects response code „204 No Content” (status_code: 204). Again, we add the header to inform the server about our identity.
Summary
The above examples show that Ansible can be used to quickly write and perform tests for REST APIs. Thanks to the built-in core „uri” module, API testing can be started immediately after installing Ansible and the code structure itself is clear and transparent.