---
# System prepended metadata

title: Pytest Fixtures

---

# Pytest Fixtures

```python=
######### Main library ############
import pytest
from flask.testing import FlaskClient
from dotenv import load_dotenv

# For DB, to allow the model to be test without real db
import sqlalchemy
from sqlalchemy_utils import create_database, database_exists
from flask_migrate import Migrate, upgrade, stamp

# Import all related model and configuration be test
from apps import config

from apps.server import create_app
from apps.model.abc import db
from apps.model.abc import Base

# Load test specicif config
load_dotenv()

# Apply latest migration
migrate = Migrate()
```

>*Mostly, importing the config for real deployment is the best option, since it will make sure test the config against real deployment.*

> Except for some config, (example, Debuging mode, etc)

-----
###  Setup Fixtures (required)
- What usually set here?
    - Setup header (Authentication)
    - Create user / group or any default data
```python=
@pytest.fixture
def jwt_app():
    app = create_app()
    app.config["TESTING"] = True
    app.test_client_class = JWTClient

    # Create tables in database
    with app.app_context():
        engine = sqlalchemy.create_engine(config.DB_URI)
        db.init_app(app)
        migrate.init_app(app, db)
        if not database_exists(engine.url):
            create_database(engine.url)
        # init("/home/apps/migrations")
        upgrade("/home/apps/migrations", "head")
    yield app

    # remove tables in database
    with app.app_context():
        engine = db.get_engine(bind=None)
        Base.metadata.drop_all(engine)
        stamp("/home/apps/migrations", "base")
        db.drop_all()

@pytest.fixture
def jwt_client(jwt_app):
    return jwt_app.test_client()


@pytest.fixture
def jwt_context(jwt_app):
    return jwt_app.app_context()
```


### Writing test case
- Example to access db while test
```python=
def test_get_get_username(jwt_client, jwt_context):  # noqa: F811
    with jwt_context:
        user_data = User("joe@example.fr", "super-secret-password")
        db.session.add(user_data)
        db.session.commit()
        rsp = jwt_client.get(f"/user/{user_data.id}")
        data = rsp.json
        assert rsp.status_code == 200
        assert data["email"] == "joe@example.fr"
```
- Example just access endpoint (Fill in the fixtures)
```python=
# Edit the fixtures
# In the test case
def test_get_get_username(jwt_client, jwt_context):  # noqa: F811
    rsp = jwt_client.get(f"/user/1")
    data = rsp.json
    assert rsp.status_code == 200
    assert data["email"] == "joe@example.fr"
```
- Example using reusable function
```python=
def create_user(jwt_context):
    with jwt_context:
        user_data = User("joe@example.fr", "super-secret-password")
        db.session.add(user_data)
        db.session.commit()
        return user_data.id

def test_get_get_username_form_2(jwt_client, jwt_context):  # noqa: F811
    user = create_user(jwt_context)
    rsp = jwt_client.get(f"/user/{user.id}")
    data = rsp.json
    assert rsp.status_code == 200
    assert data["email"] == "joe@example.fr"
```

- Make sure to test as much as posibilities can happen
    - How if the endpoint receive a script ?
    - How if the payload is not correct
    - How if the data not found on server
    - etc.....


## Mock Test
- Assume we have endpoint which need to hit another service
```python=
class ExampleMock(Resource):
    def get(self):
        response_example = requests.get(
            "https://random-data-api.com/api/v2/users?size=2&response_type=json"
        )
        return jsonify(response_example.json())

```
- In test, we can test with / without mocker
```python=
def test_mock_without_mock(jwt_client: FlaskClient):
    data = {"A": "B"}
    rsp = jwt_client.get(f"/mocks")
    assert rsp.json != data


def test_mock_with_mocker(jwt_client: FlaskClient):
    with requests_mock.Mocker() as mocker:
        data = {"A": "B"}
        mocker.get(
            "https://random-data-api.com/api/v2/users?size=2&response_type=json",
            json=data,
            status_code=200,
        )
        rsp = jwt_client.get(f"/mocks")
        assert rsp.json == data
```

- We can mock function, object, or many things, to encapsulate the test case