REST Testing Tool (py3resttest)

This is a clone of pyresttest to support py3 and optimized lot of functionality.

Table of Contents

What Is It?


Python 3.5+ Support

Apache License, Version 2.0

Changelog shows the past and present, milestones show the future roadmap.


Works on Linux or Mac with Python 3.5+

First we need to install package python-pycurl:

It is easy to install the latest release by pip: (sudo) pip install resttest3

If pip isn’t installed, we’ll want to install it first: If that is not installed, we’ll need to install it first:

Releases occur every month, if you want to use unreleased features, it’s easy to install from source:

See the Change Log for feature status.

git clone
cd py3resttest
sudo python install

The master branch tracks the latest; it is unit tested, but less stable than the releases (the ‘stable’ branch tracks tested releases).

Troubleshooting Installation

Almost all installation issues are due to problems with PyCurl and PyCurl’s native libcurl bindings. It is easy to check if PyCurl is installed correctly:

python -c 'import pycurl'

If this returns correctly, pycurl is installed, if you see an ImportError or similar, it isn’t. You may also verify the pyyaml installation as well, since that can fail to install by pip in rare circumstances.

Error installing by pip

__main__.ConfigurationError: Could not run curl-config: [Errno 2] No such file or directory

This is caused by libcurl not being installed or recognized: first install pycurl using native packages as above. Alternately, try installing just the libcurl libraries:

Sample Test

This will check that APIs accept operations, and will smoketest an application

- config:
    - testset: "Basic tests"
- test: 
    - name: "Basic get"
    - url: "/api/person/"
- test: 
    - name: "Get single person"
    - url: "/api/person/1/"
- test: 
    - name: "Delete a single person, verify that works"
    - url: "/api/person/1/"
    - method: 'DELETE'
- test: # create entity by PUT
    - name: "Create/update person"
    - url: "/api/person/1/"
    - method: "PUT"
    - body: '{"first_name": "Gaius","id": 1,"last_name": "Baltar","login": "gbaltar"}'
    - headers: {'Content-Type': 'application/json'}
    - validators:  # This is how we do more complex testing!
        - compare: {header: content-type, comparator: contains, expected:'json'}
        - compare: {jsonpath_mini: 'login', expected: 'gbaltar'}  # JSON extraction
        - compare: {raw_body:"", comparator:contains, expected: 'Baltar' }  # Tests on raw response
- test: # create entity by POST
    - name: "Create person"
    - url: "/api/person/"
    - method: "POST"
    - body: '{"first_name": "William","last_name": "Adama","login": "theadmiral"}'
    - headers: {Content-Type: application/json}


How Do I Use It?

Running A Simple Test

Run a basic test of the github API:

resttest3 examples/github_api_smoketest.yaml

Using JSON Validation

A simple set of tests that show how json validation can be used to check contents of a response. Test includes both successful and unsuccessful validation using github API.

resttest3 examples/github_api_test.yaml

(For help: pyresttest –help )

Interactive Mode

Same as the other test but running in interactive mode.

resttest3 examples/github_api_test.yaml --interactive true --print-bodies true

Verbose Output

resttest3 examples/github_api_test.yaml --log debug

Other Goodies

Basic Test Set Syntax

As you can see, tests are defined in YAML format.

There are 5 top level test syntax elements:

Import example

# Will load the test sets from miniapp-test.yaml and run them
# Note that this will run AFTER the current test set is executed
# Also note that imported tests get a new Context: any variables defined will be lost between test sets
- import: examples/miniapp-test.yaml

Imports are intended to let you create top-level test suites that run many independent, isolated test scenarios (test sets). They may also be used to create sample data or perform cleanup as long as you don’t rely on variables to store this information. For example, if one testset creates a user for a set of scenarios, tests that rely on that user’s ID need to start by querying the API to get the ID.

Url Test With Timeout

A simple URL test is equivalent to a basic GET test with that URL. Also shows how to use the timeout option in testset config to descrease the default timeout from 10 seconds to 1.

- config:
    - testset: "Basic tests"
    - timeout: 1
- url: "/api/person/"  # This is a simple test
- test: 
    - url: "/api/person/"  # This does the same thing

Custom HTTP Options (special curl settings)

For advanced cases (example: SSL client certs), sometimes you will want to use custom Curl settings that don’t have a corresponding option in PyRestTest.

This is easy to do: for each test, you can specify custom Curl arguments with ‘curl_option_optionname.’ For this, ‘optionname’ is case-insensitive and the optionname is a Curl Easy Option with ‘CURLOPT_’ removed.

For example, to follow redirects up to 5 times (CURLOPT_FOLLOWLOCATION and CURLOPT_MAXREDIRS):

- test: 
    - url: "/api/person/1"
    - curl_option_followlocation: True
    - curl_option_maxredirs: 5  

Note that while option names are validated, no validation is done on their values.

Syntax Limitations

RPM-based installation

Pure RPM-based install?

It’s easy to build and install from RPM:

Building the RPM:

python3 bdist_rpm  # Build RPM
find -iname '*.rpm'   # Gets the RPM name

Installing from RPM

sudo yum localinstall my_rpm_name
sudo yum install PyYAML python3-pycurl  

Building an RPM for RHEL 6/CentOS 6

You’ll need to install rpm-build, and then it should work.

sudo yum install rpm-build

Project Policies

Feedback and Contributions

We welcome any feedback you have, including pull requests, reported issues, etc!

For new contributors there are a whole set of issues labelled with help wanted which are excellent starting points to offer a contribution!

For instructions on how to set up a dev environment for PyRestTest, see

For pull requests to get easily merged, please:

Bear in mind that this is largely a one-man, outside-of-working-hours effort at the moment, so response times will vary. That said: every feature request gets heard, and even if it takes a while, all the reasonable features will get incorporated. If you fork the main repo, check back periodically… you may discover that the next release includes something to meet your needs and then some!


Why not pure-python tests?

Why YAML and not XML/JSON?

Does it do load tests?

Why do you use PyCurl and not requests?