PikoPong
  • Web Dev
  • Hack
  • Database
  • Big Data
  • AWS
  • Linux
No Result
View All Result
PikoPong
  • Web Dev
  • Hack
  • Database
  • Big Data
  • AWS
  • Linux
No Result
View All Result
PikoPong
No Result
View All Result
Home DevOps

Introducing the AWS Chalice test client : idk.dev

August 6, 2020
in DevOps
289 3
Introducing the AWS Chalice test client : idk.dev


The latest release of AWS Chalice, v1.17.0, now includes a test client that enables you to write tests for your Chalice applications using a concise and simplified API. The test client handles all the boilerplate setup and teardown logic that you’d previously have to write yourself when testing your Chalice applications.

This new test client allows you to test REST APIs as well as all the event handlers for AWS Lambda supported by Chalice.

Basic Usage

To show how to use this new test client, let’s start with a hello world REST API. If you haven’t used Chalice before, you can follow our quickstart guide which will walk you through installing, configuring, and creating your first Chalice application.

First, we’ll update our app.py file with two routes.

from chalice import Chalice

app = Chalice(app_name='testclient')


@app.route('/')
def index():
    return {'hello': 'world'}


@app.route('/hello/{name}')
def hello(name):
    return {'hello': name}

To test this API, we’ll create a tests directory and create a tests/__init__.py and a tests/test_app.py file with two tests, one for each route.

$ mkdir tests
$ touch tests/{__init__.py,test_app.py}
$ tree
.
├── app.py
├── requirements.txt
└── tests
    ├── __init__.py
    └── test_app.py

Your tests/test_app.py should look like this.

import app
from chalice.test import Client


def test_index_route():
    with Client(app.app) as client:
        response = client.http.get('/')
        assert response.status_code == 200
        assert response.json_body == {'hello': 'world'}


def test_hello_route():
    with Client(app.app) as client:
        response = client.http.get('/hello/myname')
        assert response.status_code == 200
        assert response.json_body == {'hello': 'myname'}

In our test file above, we first import our test client from chalice.test. Next, in order to use our test client, we instantiate it and use it as a context manager. This ensures that our test environment is properly set up, and that on teardown we cleanup and replace any resources we needed to modify during our test, such as environment variables.

The test client has several attributes that you can use to help you write tests:

  • client.http – Used to test REST APIs.
  • client.lambda_ – Used to test Lambda functions by specifying the payload to pass to the Lambda function.
  • client.events – Used to generate sample events when testing Lambda functions through the client.lambda_ attribute.

To run our tests, we’ll install pytest.

$ pip install pytest
$ py.test tests/test_app.py
============================= test session starts ==============================
platform darwin -- Python 3.7.3, pytest-5.3.1, py-1.5.3, pluggy-0.12.0
rootdir: /tmp/testclient
plugins: hypothesis-4.43.1, cov-2.8.1
collected 2 items

test_app.py ..                                                                [100%]

============================= 2 passed in 0.32s ================================

Testing AWS Lambda functions

To test Lambda functions directly, we’ll use the client.lambda_.invoke() method. First, let’s test a Lambda function that isn’t connected to any events. Add this function to your app.py file.

@app.lambda_function()
def myfunction(event, context):
    return {'event': event}

Our test for this function will look similar to our REST API unit tests, except we’ll use the client.lambda_.invoke() method instead.

def test_my_function():
    with Client(app.app) as client:
        response = client.lambda_.invoke('myfunction',
                                         {'hello': 'world'})
        assert response.payload == {'event': {'hello': 'world'}}

Testing event handlers

In the previous example, we’re creating our own event payload to pass to our Lambda function invocation. We can use the client.events attribute to generate sample events for specific services that Chalice supports. To learn more about Lambda event sources with Chalice, see our event sources documentation.

Suppose we wanted to test an event handler connected to an Amazon SNS topic.

@app.on_sns_message(topic='mytopic')
def myfunction(event):
    return {'message': event.message}

In order to test this function we need to generate an event payload that matches the schema expected by this event handler. We can use the client.events.generate_sns_event() to do this for us:

def test_my_function():
    with Client(app.app) as client:
        event = client.events.generate_sns_event(message='hello world')
        response = client.lambda_.invoke('sns_message_handler', event)
        assert response.payload == {'message': 'hello world'}

Testing with the AWS SDK for Python

Finally, let’s look at an example that involves the AWS SDK for Python. In this example, we have a REST API that takes the request body and forwards it to Amazon S3 using the AWS SDK for Python, boto3.

_S3 = None


def get_s3_client():
    global _S3
    if _S3 is None:
        _S3 = boto3.client('s3')
    return _S3


@app.route('/resources/{name}', methods=['PUT'])
def send_to_s3(name):
    s3 = get_s3_client()
    s3.put_object(
        Bucket='mybucket',
        Key=name,
        Body=app.current_request.raw_body
    )
    return Response(status_code=204, body='')

In our test we want to verify that when we make a PUT request to /resources/myobject the request body is sent as the object body for a corresponding PutObject S3 API call. To test this, we’ll use the Chalice test client as well as Botocore Stubber. The Botocore Stubber allows us to stub out requests to AWS so you don’t actually send requests to AWS. It will validate that your stubbed input parameters and response values match the schema of the service API. To use the stubber, we wrap our S3 client in a Stubber instance and specify the expected API calls. We can use the stubber as a context manager which will automatically activate our stubber as well as cleanup once we’re finished using it. Here’s how this test looks like.

import json

from botocore.stub import Stubber


def test_send_to_s3():
    client = app.get_s3_client()
    stub = Stubber(client)
    stub.add_response(
        'put_object',
        expected_params={
            'Bucket': 'mybucket',
            'Key': 'myobject',
            'Body': b'{"hello": "world"}',
        },
        service_response={},
    )
    with stub:
        with Client(app.app) as client:
            response = client.http.put(
                '/resources/myobject',
                body=json.dumps({'hello': 'world'}).encode('utf-8')
            )
            assert response.status_code == 204
        stub.assert_no_pending_responses()

We can one again run these tests using pytest.

$ py.test tests/test_app.py
============================= test session starts ==============================
platform darwin -- Python 3.7.3, pytest-5.3.1, py-1.5.3, pluggy-0.12.0
rootdir: /tmp/testclient
plugins: hypothesis-4.43.1, cov-2.8.1
collected 5 items

test_app.py .....                                                         [100%]

============================= 5 passed in 0.43s ================================

Next Steps

For more information on using the test client in Chalice, you can check out our testing documentation as well as our API reference. Let us know what you think. You can share feedback with us on our GitHub repository.



Source link

Share219Tweet137Share55Pin49

Related Posts

Following serverless best practices with AWS Chalice and Lambda Powertools : idk.dev
DevOps

Following serverless best practices with AWS Chalice and Lambda Powertools : idk.dev

AWS Chalice lets you quickly create serverless applications in Python. It has a number of built-in features such as...

September 23, 2020
Connection UX improvements in the AWS Toolkit for JetBrains : idk.dev
DevOps

Connection UX improvements in the AWS Toolkit for JetBrains : idk.dev

The AWS Toolkit for JetBrains is a plugin for JetBrains’s IDEs that makes it easier to write applications for...

September 23, 2020
Creating an EC2 instance in the AWS Wavelength Zone : idk.dev
DevOps

Creating an EC2 instance in the AWS Wavelength Zone : idk.dev

Creating an EC2 instance in the AWS Wavelength ZoneThis blog post is contributed by Saravanan Shanmugam, Lead Solution Architect,...

September 22, 2020
EFA-enabled C5n instances to scale Simcenter STAR-CCM+ : idk.dev
DevOps

EFA-enabled C5n instances to scale Simcenter STAR-CCM+ : idk.dev

This post was contributed by Dnyanesh Digraskar, Senior Partner SA, High Performance Computing; Linda Hedges, Principal SA, High Performance...

September 21, 2020
Next Post
A Practical Guide To Product Tours In React Apps — Smashing Magazine

A Practical Guide To Product Tours In React Apps — Smashing Magazine

Almost a Year After Richard Stallman Was ‘Cancelled’, Free Software Foundation has Elected a new President

Almost a Year After Richard Stallman Was 'Cancelled', Free Software Foundation has Elected a new President

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recommended

We need more inclusive web performance metrics

We need more inclusive web performance metrics

July 10, 2020
What Happens When Border Radii Overlap?

What Happens When Border Radii Overlap?

August 17, 2020
Web Unleashed 2020 – FITC

Web Unleashed 2020 – FITC

September 1, 2020
11 Ways to Modify the Looks of KDE

11 Ways to Modify the Looks of KDE

January 17, 2021

Categories

  • AWS
  • Big Data
  • Database
  • DevOps
  • IoT
  • Linux
  • Web Dev
No Result
View All Result
  • Web Dev
  • Hack
  • Database
  • Big Data
  • AWS
  • Linux

Welcome Back!

Login to your account below

Forgotten Password?

Create New Account!

Fill the forms bellow to register

All fields are required. Log In

Retrieve your password

Please enter your username or email address to reset your password.

Log In