Skip to content

Examples

With object annotation

Let's create an example test that uses models, validation, and json generation.

Imagine that we have several endpoints that allow us to manipulate the user

Method Endpoint Body
GET /users None
POST /users {'id': 1, 'username': 'some', 'email': 'other'}
PUT /users/{user_id} {'id': 1, 'username': 'some', 'email': 'other'}

This is what the user object looks like

Field Type Value
id number Any integer
username string Any string
email string Email string

Let's start by creating a model

/models/user.py

from models_manager import Model, Field
from models_manager.utils import random_number, random_string


def get_email() -> str:
    """Generates random email"""
    return random_string() + '@gmail.com'


class User(Model):
    id = Field(default=random_number, json='id', category=int)
    username = Field(default=random_string, json='username', category=str)
    email = Field(default=get_email, json='email', category=str)

/api/users.py

from models.user import User
from requests import get, post, put, Response


def get_users() -> Response:
    return get('/users')


def create_user(user: User) -> Response:
    json = user.manager.to_json
    return post('/users', json=json)


def update_user(user_id: int, user: User) -> Response:
    json = user.manager.to_json
    return put(f'/users/{user_id}', json=json)

tests/conftest.py

import pytest
from models.user import User


@pytest.fixture(scope='function')
def user() -> User:
    user_object = User(**User.manager.to_json)

    user_json = create_user(user_object).json()
    return User(**user_json)

tests/test_user.py

from http import HTTPStatus

import pytest
from api.users import get_users, create_user
from assertions import validate_json
from models.user import User


@pytest.mark.users
class TestUser:
    def test_get_users(self):
        response = get_users()
        json_response = response.json()

        assert response.status_code == HTTPStatus.OK
        validate_json(json_response, User.manager.to_array_schema)

    def test_create_user(self):
        user = User(**User.manager.to_json)

        response = create_user(user)
        json_response = response.json()

        assert response.status_code == HTTPStatus.CREATED
        assert user.id.value == json_response[user.id.json]
        assert user.username.value == json_response[user.username.json]
        assert user.email.value == json_response[user.email.json]
        validate_json(json_response, user.manager.to_schema)

    def test_update_user(self, user: User):  # user object created by fixture
        # creating new user object, with new values, for updating
        update_user = User(**User.manager.to_json)

        # user.id.value - value from fixture
        # updated_user - the user object we use to update
        response = update_user(user.id.value, update_user)
        json_response = response.json()

        assert response.status_code == HTTPStatus.OK
        assert user.id.value == json_response[user.id.json]  # usually we not updating ID
        assert update_user.username.value == json_response[user.username.json]
        assert update_user.email.value == json_response[user.email.json]
        validate_json(json_response, user.manager.to_schema)

This example is just a sample of how the models can be used. In fact, the scope is much wider. Some methods in this example can be overwritten. Let's look at how we can rewrite the user update test

In update_user we can use just object to update user

def update_user(user: User) -> Response:
    json = user.manager.to_json
    return put(f'/users/{user.id.value}', json=json)

Then our tests would look like

class TestUser:
    ...

    def test_update_user(self, user: User):  # user object created by fixture
        # now we overriding id of update_user object
        update_user = User(**User.manager.to_json, id=user.id.value)

        response = update_user(update_user)
        json_response = response.json()

        assert response.status_code == HTTPStatus.OK
        assert update_user.id.value == json_response[user.id.json]
        assert update_user.username.value == json_response[user.username.json]
        assert update_user.email.value == json_response[user.email.json]
        validate_json(json_response, user.manager.to_schema)