Reader small image

You're reading from  Building Data Science Applications with FastAPI

Product typeBook
Published inOct 2021
Reading LevelBeginner
PublisherPackt
ISBN-139781801079211
Edition1st Edition
Languages
Concepts
Right arrow
Author (1)
François Voron
François Voron
author image
François Voron

François Voron graduated from the University of Saint-Étienne (France) and the University of Alicante (Spain) with a master's degree in machine learning and data mining. A full stack web developer and a data scientist, François has a proven track record working in the SaaS industry, with a special focus on Python backends and REST APIs. He is also the creator and maintainer of FastAPI Users, the #1 authentication library for FastAPI, and is one of the top experts in the FastAPI community.
Read more about François Voron

Right arrow

Chapter 9: Testing an API Asynchronously with pytest and HTTPX

In software development, a significant part of the developer's work should be dedicated to writing tests. At first, you may be tempted to manually test your application by running it, making a few requests, and arbitrarily deciding that "everything works". However, this approach is flawed and can't guarantee that your program works in every circumstance and that you didn't break things along the way.

That's why several disciplines have emerged regarding software testing: unit tests, integration tests, E2E tests, acceptance tests, and more. These techniques aim to validate the functionality of the software from a micro level, where we test single functions (unit tests), to a macro level, where we test a global feature that delivers value to the user (acceptance tests). In this chapter, we'll focus on the first level: unit testing.

Unit tests are short programs designed to verify that...

Technical requirements

For this chapter, you'll need a Python virtual environment, similar to the one we set up in Chapter 1, Python Development Environment Setup.

For the Testing with a database section, you'll need a running MongoDB server on your local computer. The easiest way to do this is to run it as a Docker container. If you've never used Docker before, we recommend that you read the Get Started tutorial in the official documentation: https://docs.docker.com/get-started/. Once done, you'll be able to run a MongoDB server with this simple command:

$ docker run -d --name fastapi-mongo -p 27017:27017 mongo:4.4

The MongoDB server instance will then be available on your local computer on port 27017.

You can find all the code examples for this chapter in its dedicated GitHub repository: https://github.com/PacktPublishing/Building-Data-Science-Applications-with-FastAPI/tree/main/chapter9.

Introduction to unit testing with pytest

As we mentioned in the introduction, writing unit tests is an essential task in software development to deliver high-quality software. To help us be productive and efficient, lot of libraries exist that provide tools and shortcuts dedicated to testing. In the Python standard library, a module exists for unit testing called unittest. Even though it's quite common in Python code bases, many Python developers tend to prefer pytest, which provides a more lightweight syntax and powerful tools for advanced use cases.

In the following examples, we'll write a unit test for a function called add, both with unittest and pytest, so that you can see how they compare on a basic use case. First, we'll install pytest:

$ pip install pytest

Now, let's see our simple add function, which simply performs an addition:

chapter9_introduction.py

def add(a: int, b: int) -> int:
    return a + b

Setting up testing tools for FastAPI with HTTPX

If you look at the FastAPI documentation regarding testing, you'll see that it recommends that you use TestClient provided by Starlette. In this book, we'll show you a different approach involving an HTTP client, called HTTPX.

Why? The default TestClient is implemented in a way that makes it completely synchronous, meaning you can write tests without worrying about async and await. This might sound nice, but we found that it causes some problems in practice: since your FastAPI app is designed to work asynchronously, you'll likely have lots of services working asynchronously, such as the database drivers we saw in Chapter 6, Databases and Asynchronous ORMs. Thus, in your tests, you'll probably need to perform some actions on those asynchronous services, such as filling a database with dummy data, which will make your tests asynchronous anyway. Melting the two approaches often leads to strange errors that are hard...

Writing tests for REST API endpoints

All the tools we need to test our FastAPI application are now ready. All these tests boil down to performing an HTTP request and checking the response to see if it corresponds to what we expect.

Let's start simple with a test for our hello_world path operation function. You can see it in the following code:

chapter9_app_test.py

@pytest.mark.asyncio
async def test_hello_world(test_client: httpx.AsyncClient):
    response = await test_client.get("/")
    assert response.status_code == status.HTTP_200_OK
    json = response.json()
    assert json == {"hello": "world"}

First of all, notice that the test function is defined as async. As we mentioned previously, to make it work with pytest, we had to install...

Writing tests for WebSocket endpoints

In Chapter 8, Defining WebSockets for Two-Way Interactive Communication in FastAPI, we explained how WebSockets work and how you can implement such endpoints in FastAPI. As you may have guessed, writing unit tests for WebSockets endpoints is quite different from what we've seen so far.

Unfortunately, we won't be able to reuse HTTPX since, at the time of writing, this client can't communicate with WebSockets. For the time being, our best bet is to use the default TestClient provided by Starlette.

To show you this, we'll consider the following WebSocket example:

chapter9_websocket.py

from fastapi import FastAPI, WebSocket
from starlette.websockets import WebSocketDisconnect
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    try:
        while True:
 ...

Summary

Congratulations! You are now ready to build high-quality FastAPI applications that have been well tested. In this chapter, you learned how to use pytest, a powerful and efficient testing framework for Python. Thanks to pytest fixtures, you saw how to create a reusable test client for your FastAPI application that can work asynchronously. Using this client, you learned how to make HTTP requests to assert the behavior of your REST API. Finally, we reviewed how to test WebSocket endpoints, which involves a fairly different way of thinking.

Now that you can build a reliable and efficient FastAPI application, it's time to bring it to the whole world! In the next chapter, we'll review the best practices and patterns for preparing a FastAPI application for the world before studying several deployment methods.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Building Data Science Applications with FastAPI
Published in: Oct 2021Publisher: PacktISBN-13: 9781801079211
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
François Voron

François Voron graduated from the University of Saint-Étienne (France) and the University of Alicante (Spain) with a master's degree in machine learning and data mining. A full stack web developer and a data scientist, François has a proven track record working in the SaaS industry, with a special focus on Python backends and REST APIs. He is also the creator and maintainer of FastAPI Users, the #1 authentication library for FastAPI, and is one of the top experts in the FastAPI community.
Read more about François Voron