title: Writing tests and using the fixture framework ## Writing tests and using the fixture framework ## This section describes how to write tests for the provider drivers and how to use our fixture framework and system for mocking the responses. Examples in this section refer to the compute API but things described in this section are also applicable to other APIs. * [Creating Fixtures](#creating-fixtures) * [Mocking responses and using MockHttp class](#mocking-responses-and-using-mockhttp-class) * [MockHttp class example](#mock-http-class-example)

Creating Fixtures

In our test cases fixtures store different responses returned by the provider APIs. They are stored and named in the following format: `test//fixtures//`. Fixtures are usually generated by "manually" performing (usually using a tool like curl) different actions with the provider API and saving responses in the files. *Note: You are advised against using the examples from the provider API docs because empirical evidence has shown that in a lot of cases they are wrong or out of date.*

Mocking responses and using MockHttp class

Each provider test file usually contains a class which inherits from the base `MockHttp` class. This class is responsible for loading fixtures and returning a mocked response for each API call. Which method is called is primary determined by the requested path. All the forward slashes, periods and dashes in the requested path are replaced by an underscore (`_`). Some examples: **Requested path**: `/servers/list.all` **use_params**: `MockHttp.use_params = None` **Name of the method on the Mock class**: `_servers_list_all` **Requested path**: `/servers/reboot-all` **use_params**: `MockHttp.use_params = None` **Name of the method on the Mock class**: `_servers_reboot_all` Some providers use the same path for all the requests and the actual action is determined by some parameter in a query string. To overcome this problem, set the `use_param` MockHttp class attribute to the name of the query string parameter which specifies the action. Good example of a provider API which does this is the Amazon EC2 API (`test/compute/test_ec2.py`). Example: **Requested path**: `/?Action=RebootInstances&InstanceId=12345` **use_params**: `MockHttp.use_params = 'Action'` **Name of the method on the Mock class**: `_RebootInstances` Usually we also want to test different scenarios for a single API call. Good example of this is testing a success and different failure scenarios when creating a node. Because we are testing a single API call, this means that the request path will in most cases be the same. This makes loading a different response fixture for each API call without inspecting the request parameters or doing something similar very cumbersome. This problem can be overcome by setting the `type` attribute on the `MockHttp` class before issuing a request. The specified `type` will be automatically appended to the end of the constructed method name. Example: **Requested path**: `/servers/reboot-all` **use_params**: `MockHttp.use_params = None` **type**: `MockHttp.type = 'FAILURE'` **Name of the method on the Mock class**: `_servers_reboot_all_FAILURE`

MockHttp class example

Bellow is an example of a MockHttp class from the Amazon EC2 tests with a single method. Return value of a mock method is a tuple - **(status_code, response_body, response_headers, response_status_string)**. * **response_code** (intger) - response status code (httplib.OK, httplib.NOT_FOUND, ...) * **response_body** (string) - actual mocked response body which is usually read from a fixture * **response_headers** (dictionary) - response headers * **response_status_string** (string) - string representation of the response status code (httplib.responses[httplib.OK], httplib.responses[httplib.CONTINUE], ...) ::python class EC2MockHttp(MockHttp): fixtures = ComputeFileFixtures('ec2') def _DescribeInstances(self, method, url, body, headers): body = self.fixtures.load('describe_instances.xml') return (httplib.OK, body, {'Content-Type': 'application/xml'}, httplib.responses[httplib.OK])