Support for Testing Serverless API Services on AWS¶
Many API services are currently hosted on AWS, and Serverless is one common
Infrastructure-as-Code (IaC) system for organizing the bevy of resources
necessary for a “serverless” service. Custom code for handling API requests in
a Serverless application is integrated through Lambda Functions, which have a
simple call interface in several languages. Where the language chosen is
Python, using the intercom_test package allows development of
the interface test cases in familiar HTTP terms but, through
ServerlessHandlerMapper, allows the Lambda
handler functions to be tested.
Extended Example¶
Example directory tree for using intercom_test
Building on the base example, if we had a serverless.yml
file in the src directory, we could create test code like:
from contextlib import ExitStack
from unittest import TestCase
from intercom_test import InterfaceCaseProvider, HTTPCaseAugmenter, aws_http, utils as icy_utils
@icy_utils.complex_test_context
def around_interface_case(case, setup):
setup(database(case))
setup(stubs(case))
yield
# ... define `database` and `stubs` to return context managers for the
# test case data they are given ...
class InterfaceTests(TestCase):
def test_interface_case(self):
# Construct an AWS Lambda handler function mapper from a Serverless
# configuration (targeting the "aws" provider)
service = aws_http.ServerlessHandlerMapper("src")
# Get the case-testing callable, which accepts an entry (a dict)
# from the test data file(s)
case_tester = service.case_tester(case_env=around_interface_case)
# Construct the case provider
case_provider = InterfaceCaseProvider(
"test/component_interfaces", "service",
case_augmenter=HTTPCaseAugmenter("test/component_test_env/service")
)
# Use case_provider to construct a generator of case runner callables
case_runners = case_provider.case_runners(case_tester)
for i, run_test in enumerate(case_runners):
with self.subTest(i=i):
run_test()
if __name__ == '__main__':
unittest.main()
The callable returned from intercom_test.aws_http.ServerlessHandlerMapper.case_tester()
accepts a dict of test case data. It does not care where this
dict comes from, but an
intercom_test.framework.InterfaceCaseProvider is specifically
designed to provide such a value.
Certain keys of the test case dict are consulted (documented in
intercom_test.aws_http.HttpCasePreparer) when building the event
passed to the handler function, and certain other keys (documented in
intercom_test.aws_http.confirm_expected_response()) are used for
evaluating correctness of the handler function’s result.