Skip to main content

Test a FastAPI project

FastAPI is a modern and highly performant web framework that you can use to build APIs in Python 3.7+ using standard Python type hints. In this tutorial, you'll use Harness CI to automatically run tests on your FastAPI project when changes are pushed to a specific branch of your code repository.

Prerequisites

You need the following for this tutorial:

tip

If you don't have a Harness account yet, you can create one for free at app.harness.io.

Prepare the codebase

  1. Fork the fastapi-harness-sample repository into your GitHub account.
  2. In Harness, create a project or select an existing project, and then go to the CI module.
  3. Select Connectors under Project Setup.
  4. Select New Connector, and select GitHub under Code Repositories.
  5. Configure the GitHub connector settings so that the connector can access your fork of the sample repo.

The sample repo has a simple FastAPI project and unit tests. Notable files include:

  • fastapi-todo-tests/requirements.txt: Contains a list of project dependencies.
  • fastapi-todo-tests/app/main.py: The sample FastAPI project builds a "To Do" list. It has three API endpoints, one that creates tasks, one that deletes tasks, and one that gets the task list.
  • fastapi-todo-tests/test_main.py: Defines three test cases.
Optional exercise: Local set up

Optionally, you can build the project and test it locally before running tests in a Harness CI pipeline.

  1. Make sure you have Python/Python3 and Uvicorn installed on your local machine.

  2. Clone the FastAPI sample repo to your local machine.

    The sample repo should have the following structure:

    ├── .harness
    │ ├── Pipeline.yaml
    ├── app
    │ ├── main.py
    │ ├── schemas.py
    │ ├── util.py
    │ ├── __init__.py
    ├── LICENSE
    ├── README.md
    ├── requirements.txt
    └── test_main.py
  3. Create a virtual environment named test-env.

    • Linux or macOS: python3 -m venv test-env
    • Windows: python -m venv test-env
  4. Activate the virtual environment.

    • Linux or macOS: source test-env/bin/activate
    • Windows: .\test-env\Scripts\activate
  5. Install dependencies.

    cd <project root>
    pip install -r requirements.txt
  6. Run tests defined in test_main.py.

    pytest
  7. Start the development server.

    uvicorn app.main:app --reload
  8. Navigate to localhost:8000/docs on your browser to access the local server test environment.

Prepare the pipeline

These steps summarize pipeline creation. For more information, go to CI pipeline creation overview.

  1. In your Harness project, go to the CI module.
  2. Select Pipelines, and then select Create a Pipeline.
  3. Enter a Name and select Start.
  4. Add a Build (CI) stage.

Add the Build stage and infrastructure

  1. Select Add Stage, and select the Build stage.
  2. Enter a Stage Name, such as Test FastAPI.
  3. For Connector, select the GitHub connector you created earlier in Prepare the codebase.
  4. Select Set Up Stage.
  5. In the Build stage, select the Infrastructure tab, and set up your build infrastructure.

Install dependencies

Add a Run step to install dependencies for the FastAPI project.

              - step:
type: Run
name: Install Dependencies
identifier: Install_Dependencies
spec:
shell: Sh
command: |-
sudo apt-get update && sudo apt-get install -y python3-dev && sudo apt-get install default-libmysqlclient-dev
pip install --cache-dir .pip_cache -r requirements.txt
envVariables:
PIP_CACHE_DIR: /root/.cache

Run tests

Add a Run step that runs unit tests and outputs the results in JUnit XML format.

This tutorial runs basic unit tests, but you can run all types of tests (integration tests, mutation tests, and so on) in Harness CI. For more information, go to Run tests in CI pipelines.

              - step:
type: Run
name: Pytest
identifier: Pytest
spec:
shell: Sh
command: |-
pytest test_main.py --junit-xml=output-test.xml
reports:
type: JUnit
spec:
paths:
- output-test.xml

To view test reports in Harness, test results must be in JUnit XML format, and the reports specification must be included.

Add the trigger

You can run this pipeline manually as it is, or you can add a trigger to automatically run these tests whenever the codebase changes. To do this, add a Git event trigger that listens for an event on a specific branch of your FastAPI repo fork.

For this tutorial, you'll create a trigger that listens for pushes to the main branch.

  1. In Harness, in the same pipeline, select Triggers in the Pipeline Studio header, and then select Add New Trigger.
  2. Select GitHub under Webhook.
  3. Enter a Name.
  4. For Connector, select your GitHub connector, and enter the FastAPI repo name if necessary.
  5. For Event, select Push.
  6. Select Continue
  7. On the Conditions tab, configure a Branch Name condition. Set the Operator to Equals, and set the Matches Value to main. The entire condition should read like Branch Name = main.
  8. Select Continue, and select Create Trigger.

GitHub webhooks are usually automatically created in the target repo. If automatic registration fails, you must manually copy the webhook URL and add it to your repo webhooks. For instructions on manual webhook registration, go to Register the webhook in the Git provider.

Run the pipeline

To test the Git event trigger and run the pipeline, go to your FastAPI repo fork, make a change, and commit and push it to main. For this tutorial, you could commit directly to main, but in a real world development situation, you would want to create and merge a PR.

Upon pushing to main (either directly or by merging a PR), the trigger should start your pipeline within a few moments. While the build runs, you can view the logs and monitor build activity on the Build details page.

After the pytest step runs, you can find logs indicating that the output-test.xml file was generated, and you can view the test results on the Tests tab.

Complete YAML examples

Here are complete YAML examples for this tutorial. If you copy these examples, make sure to replace the placeholders with valid values.

Pipeline YAML

These pipelines include a Build (CI) stage with two Run steps. One step installs dependencies defined in requirements.txt and the other runs unit tests.

This example uses Harness Cloud build infrastructure.

pipeline:
name: YOUR_PIPELINE_NAME
identifier: YOUR_PIPELINE_ID
projectIdentifier: YOUR_HARNESS_PROJECT_ID
orgIdentifier: default
tags: {}
properties:
ci:
codebase:
connectorRef: YOUR_GITHUB_CONNECTOR_ID
repoName: fastapi-harness-sample
build: <+input>
stages:
- stage:
name: test
identifier: test
type: CI
spec:
cloneCodebase: true
platform:
os: Linux
arch: Amd64
runtime:
type: Cloud
spec: {}
execution:
steps:
- step:
type: Run
name: Install Dependencies
identifier: Install_Dependencies
spec:
shell: Sh
command: |-
sudo apt-get update && sudo apt-get install -y python3-dev && sudo apt-get install default-libmysqlclient-dev
pip install --cache-dir .pip_cache -r requirements.txt
envVariables:
PIP_CACHE_DIR: /root/.cache
- step:
type: Run
name: Pytest
identifier: Pytest
spec:
shell: Sh
command: |
pytest test_main.py --junit-xml=output-test.xml
reports:
type: JUnit
spec:
paths:
- output-test.xml

Trigger YAML

Trigger YAML is separate from pipeline YAML. However, you can write triggers in a YAML editor just as you can for pipelines. The YAML for this tutorial's trigger is as follows:

trigger:
name: fastapi trigger
identifier: fastapi_trigger
enabled: true
encryptedWebhookSecretIdentifier: ""
description: ""
tags: {}
orgIdentifier: default
stagesToExecute: []
projectIdentifier: YOUR_HARNESS_PROJECT_ID
pipelineIdentifier: YOUR_PIPELINE_ID
source:
type: Webhook
spec:
type: Github
spec:
type: Push
spec:
connectorRef: YOUR_GITHUB_CONNECTOR_ID
autoAbortPreviousExecutions: false
payloadConditions:
- key: targetBranch
operator: Equals
value: main
headerConditions: []
repoName: fastapi-harness-sample
actions: []