Cicada

Cicada

  • Docs
  • Guides
  • API
  • Runners
  • Help

›Guides

Introduction

  • Quickstart
  • Tests
  • State
  • Actions and Asserts
  • Runners
  • Reports

Guides

  • REST API Guide
  • Async App Guide
  • gRPC Server Guide
  • Kubernetes Guide

API

  • Test
  • Action
  • Assert
  • Config
  • Test Engine
  • Verification

Runners

  • REST Runner
  • SQL Runner
  • Kafka Runner
  • S3 Runner
  • gRPC Runner

REST API Guide

In this guide, you'll create tests for an example REST API written with Flask.

Source code

App

Here we have a simple API that connects to a Postgres database and has one endpoint, which creates members given a member name as JSON.

app.py

from flask import Flask, request, jsonify
from sqlalchemy import create_engine


app = Flask(__name__)
engine = create_engine("postgresql://postgres:admin@db:5432/postgres")


@app.route("/members", methods=["POST"])
def members():
    body = request.json

    with engine.connect() as connection:
        row = list(
            connection.execute(
                "INSERT INTO members (name) VALUES (%s) RETURNING *", body["name"]
            )
        )[0]

    return jsonify({"id": row.id, "name": row.name})


if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=8080)

requirements.txt

flask
psycopg2
sqlalchemy

Environment

Next, we'll need to set up our environment using Docker compose. Docker compose will handle creating the Docker image from a Dockerfile and starting the API as well as the Postgres database. We'll also want to create our schema for the database using a migration manager like 'Flyway'

V1__Initial.sql

CREATE TABLE members (
    id SERIAL PRIMARY KEY,
    name TEXT
)

Dockerfile

FROM python:3.8-buster

WORKDIR /app

RUN apt-get update
RUN apt-get install -y libpq-dev python-dev

ADD requirements.txt .
RUN pip install -r requirements.txt

ADD app.py .

ENTRYPOINT ["python", "app.py"]

docker-compose.yml

version: '3'
services:
  db:
    image: postgres:12-alpine
    environment:
      - POSTGRES_PASSWORD=admin
    ports:
      - 5432:5432
  flyway:
    image: flyway/flyway:6-alpine
    command: -url=jdbc:postgresql://db:5432/ -schemas=public -user=postgres -password=admin -connectRetries=60 migrate
    volumes:
      - .:/flyway/sql
    depends_on:
      - db
  api:
    build: .
    ports:
      - 8080:8080
    depends_on:
      - db
      - flyway

Ensure that the API is built and run successfully with docker-compose up or by running make run if using the provided Makefile in the guide

Tests

Next, we'll want to create tests for our app. Create a file called test.cicada.yaml to house the tests in and add a test that creates 100 members through the API endpoint:

test.cicada.yaml

description: Example test
tests:
  - name: add_members
    description: add 100 new members
    runner: rest-runner
    actions:
      - type: POST
        executionsPerCycle: 100
        params:
          url: "http://api:8080/members"
          body:
            name: jeff

Next, add the following to docker-compose.yml to start Cicada and start docker-compose again:

docker-compose.yml

version: '3'
services:
  ...
  cicada:
    image: cicadatesting/cicada-2-engine
    environment:
      - CONTAINER_NETWORK=rest_api_default
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - .:/tests
      - ./reports:/reports
    depends_on:
      - api

The test should now create 100 users.

Let's add a SQL runner to our test. In this example, we are going to change the name of all the members in the database. In test.cicada.yaml:

test.cicada.yaml

tests:
  ...
- name: update_ages
    description: update ages of new members
    runner: sql-runner
    dependencies:
      - add_members
    config:
      connectionString: postgresql://postgres:admin@db:5432/postgres
    actions:
      - type: SQLQuery
        params:
          query: "delete from members where name='jeff2'"
      - type: SQLQuery
        template: >
          params:
            {% set ids = [] %}
            {% for member in state['add_members']['actions']['POST0']['results'] if member is not none %}
            {% do ids.append(member['body']['id']) %}
            {% endfor %}
            query: "update members set name='jeff2' where id in ({{ ids|join(',') }})"

After updating test.cicada.yaml, run docker-compose again. You should be able to verify in the database that the name of all the members is now jeff2.

Finally, we'll want to automate the verification of all the changed members. Add the following to the test file:

test.cicada.yaml

tests:
  ...
- name: update_ages
    ...
    asserts:
      - type: EqualsRows
        params:
          method: SQLQuery
          actionParams:
            query: "select count(*) as cnt from members where name='jeff2'"
          expected:
            rows:
              - cnt: 100

This will perform a SQL query which will check that 100 users exist in the database with name=jeff2

Run the docker-compose one last time. This test should finish and you will be able to see the test results in reports/report.md

Congratulations! You were able to create and test a REST API!

← ReportsAsync App Guide →
  • App
  • Environment
  • Tests
Cicada
Docs
Getting StartedAPI Reference
More
GitHubStar
Copyright © 2021 Cicada