Package: boto3-fixtures
boto3-fixturesboto3-fixturesprovides test fixtures for your local AWS cloud stack.Testing software which touches cloud infrastructure doesn't have to be difficult!boto3-fixturesprovides a dead-simple framework for setup+teardown of mocked AWS infrastructure. Use in combination with projects like moto or localstack.SupportsKinesisSQSSNSS3LambdaDynamoDBPlease submit a PR or issue if you'd like to see support for a specific AWS service!Getting StartedThis library provides a context decorator,boto3_fixtures.Service, which will setup and teardown AWS services.importboto3_fixtureswithboto3_fixtures.Service("sqs",queues=["my-queue"])assvc:# Queues existforqueueinsvc.state["queues"]:print(f"{queue.name}-{queue.arn}-{queue.url}")# Queues destroyedCombine this with a local testing stack of your choice (moto, localstack).importboto3_fixtures,motowithmoto.mock_sqs():withboto3_fixtures.Service("sqs",queues=["first-queue","second-queue"])assvc:# ...Generating Pytest FixturesTo make your life even easier, we've boiled all of the above down into pytest fixture generators.importboto3_fixturesasb3faws=b3f.contrib.pytest.moto_fixture(services=["dynamodb","kinesis","sqs","s3","lambda"],scope="class",)sqs=b3f.contrib.pytest.service_fixture("sqs",scope="class",queues=fixtures.SQS)kinesis=b3f.contrib.pytest.service_fixture("kinesis",scope="class",streams=fixtures.KINESIS)dynamodb=b3f.contrib.pytest.service_fixture("dynamodb",scope="class",tables=fixtures.DYNAMODB)s3=b3f.contrib.pytest.service_fixture("s3",scope="class",buckets=fixtures.S3)lam=b3f.contrib.pytest.service_fixture("lambda",scope="class",lambdas=fixtures.LAMBDA)sns=b3f.contrib.pytest.service_fixture("sns",scope="class",topics=fixtures.TOPICS)# Example Usagedeftest_my_code(sqs):boto3.client("sqs").list_queues()Theaws()fixtureTo ensure your mocked cloud is a dependency of your service fixtures, boto3-fixtures expects you to create a fixture namedaws. If you don't take advantage of this, your local cloud stack may be torn down before your service, leading to boto3 exceptions when tearing down the services.# Example: localstack via pytest-localstackimportpytest_localstackaws=pytest_localstack.patch_fixture(services=["sqs"],scope="class",)# Example: moto via boto3-fixturesimportboto3_fixturesasb3faws=b3f.contrib.pytest.moto_fixture(services=["sqs"],scope="class",)Configuring ServicesConfiguration of a service may be either a list ofnamesList[str]or a list ofconfigsList[dict]containing boto3 parameters.ServiceList of NamesList of Configss3yesyessqsyesyeskinesisyesyesdynamodbyeslambdayessnsyesyesFor example, your configuration might look like this:S3=["first-bucket","second-bucket"]SQS=["first-queue","second-queue"]KINESIS=["first-stream","second-stream"]DYNAMODB=[{"AttributeDefinitions":[{"AttributeName":"uri","AttributeType":"S"},{"AttributeName":"timestamp","AttributeType":"S"},],"TableName":"test-dbd-table","KeySchema":[{"AttributeName":"uri","KeyType":"HASH"},{"AttributeName":"timestamp","KeyType":"RANGE"},],}]LAMBDA=[{"zip_path":"dist/build.zip","FunctionName":"my_lambda","Runtime":"python3.6","Environment":{"foo":True},}]SNS=["my-topic-with-default-attrs",{"Name":"my-topic-with-additional-params","Tags":[{"Key":"key1","Value":"val1"}],"Attributes":{"DisplayName":"YourSystemIsOnFireTopic",},}]These configurations don't have to be static. You could use a pytest fixture to build or compile a list of resources that you want mocked.Using bothmotoandlocalstackYou can point theawsfixture at moto or localstack to explicitly to require a specific stack to exist for the duration of your service fixture. For example, if you use both stacks:# conftest.pystack_config={"services":["dynamodb","kinesis","sqs","s3","lambda"],"scope":"class","autouse":False,"region_name":"us-east-1",}localstack=pytest_localstack.patch_fixture(**stack_config)moto=b3f.contrib.pytest.moto_fixture(**stack_config)@pytest.fixture(scope="class")defaws(moto):pass# component/conftest.py@pytest.fixture(scope="class")defaws(localstack):passKnown IssuesUsing both pytest-localstack and moto in the same project may break if the pytest-localstack tests run first. It's suspected this is due to an issue with cleanup with the pytest-localstack session, but is this is still under investigation.