Skip to main content

RESTful API Testing Suite

Project description

Testing framework for RESTful APIs such as the OpenStack/Rackspace APIs

Travis-CI Status

Overview

Stack-In-A-Box is a RESTful API Testing Framework for unit testing applications against the other services

Installing

Installation is simple:

pip install stackinabox

Goals

  • Enable Python modules to be unit tested against externals services in particular in an environment entirely controlled by the unittest. - Example: The OpenStack/Rackspace APIs

  • The service should be started/stopped and configured from the setup/teardown methods of the unittest

  • Support both Postive and Negative testing

  • Testing should be easy to do:

    • you should not necessarily need to know the ins and outs of each service

    • you should be able to register what you need (f.e keystone, swift) and have it just work

  • should be useable on systems like Travis (https://travis-ci.org/)

  • should be light on requirements

    • we do not want to bloat your testing to fit our needs

    • if we have many requirements they could interfere with your requirements

  • The code being unit-tested should not be able to tell the difference of whether it is working with Stack-In-A-Box or the real thing

    • there should be nothing special about setting up the test

    • if you don’t turn on Stack-In-A-Box then the code should be able to call the real thing

Why not use framework X?

A couple of frameworks and tools were considered, but they did not quite meet the goals above.

For instance, mimic (https://github.com/rackerlabs/mimic) is a great tool for testing multiple things. However, you have to start/stop it separately from your tests, and each test is configured through a series of HTTP calls to Mimic itself.

On the other hand, pretenders (https://github.com/pretenders) has a nice framework too, but it does not provide a way to emulate an integrated application that requires a series of dependent calls that modify each other.

What’s Provided?

Here’s what is currently provided:

  • An easy to build Service object and end-point registration that is plug-in-play with StackInABox

  • A plug-in-play utility set for several testing frameworks so you the developer can choose which fits your needs best

  • An example HelloWorld Service to show the basics

  • The start of support StackInABox services for testing against OpenStack/Rackspace APIs

It’s a work in progress. Here’s the list of current targets in-order:

  • Keystone v2

  • Keystone v3

  • Swift

Thus far Keystone v2 provides end-points for:

  • Listing tenants

  • Listing users

It also has support in the backend for:

  • tenant (add/remove/enable/disable)

  • users (add/remove/enable/disable, apikey, password)

  • tokens (add/remove, revoke, validate, admin tokens)

  • roles (add, assign)

Working with Frameworks

Stack-In-A-Box does not itself provide a socket interception framework. Out-of-the-box it supports the following frameworks:

You can use any of them, and you must pull them in via your own test requirements.

Both of these are extremely easy to use as shown in the following examples:

HTTPretty

httypretty works well with class-based tests.

import unittest

import httpretty
import requests

import stackinabox.util_httpretty
from stackinabox.stack import StackInABox
from stackinabox.services.hello import HelloService


@httpretty.activate
class TestHttpretty(unittest.TestCase):

    def setUp(self):
        super(TestHttpretty, self).setUp()
        StackInABox.register_service(HelloService())

    def tearDown(self):
        super(TestHttpretty, self).tearDown()
        StackInABox.reset_services()

    def test_basic(self):
        stackinabox.util_httpretty.httpretty_registration('localhost')

        res = requests.get('http://localhost/')
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.text, 'Hello')
        assert False

Responses

responses works well with function-based tests; however, it does require you use the Python requests library.

import unittest

import responses
import requests

import stackinabox.responses
from stackinabox.stack import StackInABox
from stackinabox.services.hello import HelloService


@responses.activate
def test_basic_responses():
    StackInABox.reset_services()
    StackInABox.register_service(HelloService())
    stackinabox.util_responses.responses_registration('localhost')

    res = requests.get('http://localhost/hello/')
    assert res.status_code == 200
    assert res.text == 'Hello'

Requests Mock

requests-mock works well with class-based tests, however, it does require that you use the Python requests API. If you use requests-mock directly than you also have to configure requests.session.Session objects and setup your code to use them. However, Stack-In-A-Box makes that unnecessary by providing thread-based session objects that are automatically registered and patching requests to return them automatically. Thus you can either use a Session object directly or just use the nice calls that requests provides and your tests will still just work.

import unittest

import requests

import stackinabox.util_requests_mock
from stackinabox.stack import StackInABox
from stackinabox.services.hello import HelloService

class TestRequestsMock(unittest.TestCase):

        def setUp(self):
                super(TestRequestsMock, self).setUp()
                StackInABox.register_service(HelloService())
                self.session = requests.Session()

        def tearDown(self):
                super(TestRequestsMock, self).tearDown()
                StackInABox.reset_services()
                self.session.close()

        def test_basic_requests_mock(self):
            # Register with existing session object
                stackinabox.util_requests_mock.requests_mock_session_registration(
                        'localhost', self.session)

                res = self.session.get('http://localhost/hello/')
                self.assertEqual(res.status_code, 200)
                self.assertEqual(res.text, 'Hello')

        def test_context_requests_mock(self):
                with stackinabox.util_requests_mock.activate():
        # Register without the session object
                        stackinabox.util_requests_mock.requests_mock_registration(
                                'localhost')

                        res = requests.get('http://localhost/hello/')
                        self.assertEqual(res.status_code, 200)
                        self.assertEqual(res.text, 'Hello')

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stackinabox-0.5.0.tar.gz (14.2 kB view details)

Uploaded Source

File details

Details for the file stackinabox-0.5.0.tar.gz.

File metadata

  • Download URL: stackinabox-0.5.0.tar.gz
  • Upload date:
  • Size: 14.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for stackinabox-0.5.0.tar.gz
Algorithm Hash digest
SHA256 c763841487ec2f8af190cde591b078af998cf24d10ccc39811f8a47a7d50f6c1
MD5 84100eca03bebb721cf11729287d25c4
BLAKE2b-256 c568de64ecf7bfabb8127ed388237c6a239ec5d0305aa71c1aa15b6e4a3f8814

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page