sqlalchemy drop_all not removing data when pytest runs all project tests

26 Views Asked by At

If I run the tests in the module below with the command pytest mytest.py, they all pass. If I run all tests in my project's test directory with pytest, the last test (test_get_actors_returns_all) fails because it finds 3 actors in the database (the two added in this test with post calls, and 1 from a previous test, test_create_actor_with_all_fields). The fixture used by each test should be creating all the tables and when the test ends it should drop all of them. I've verified this happens with print statements. I've verified that the actor Table object is in the list returned by Base.metadata.tables.values() at the time of drop_all(). Can you tell me what I must change so that I can run all the tests in my project and have the desired effect of a fresh database at the start of each test?

# mytest.py
import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine, delete
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool

from api.config.database import get_db
from api.main import app
from api.models.base import Base

SQLALCHEMY_DATABASE_URL = "sqlite://"

engine = create_engine(
    SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}, poolclass=StaticPool
)

TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)


def override_get_db():
    try:
        db = TestingSessionLocal()
        yield db
    finally:
        db.close()


app.dependency_overrides[get_db] = override_get_db

client = TestClient(app)


@pytest.fixture(scope="function")
def db_engine():
    Base.metadata.create_all(engine)
    yield engine
    Base.metadata.drop_all(engine)



def test_get_actors_returns_empty(db_engine):
    response = client.get("api/actors")
    assert response.status_code == 200
    data = response.json()
    assert [] == data


def test_create_actor_with_all_fields(db_engine):
    actor = {
        "identity_id": 933,
        "is_human": True,
        "display_name": "Eddie Kubernetti",
        "phone_number": "555-555-6666",
        "email": [email protected],
        "order_identifier_pattern": "EFK",
        "is_active": True,
    }
    response = client.post("api/actors", json=actor)
    assert response.status_code == 201
    data = response.json()
    assert "id" in data
    for k, v in actor.items():
        assert response.json()[k] == v


def test_create_actor_with_missing_field_fails(db_engine):
    actor = {
        "identity_id": 933,
        "is_human": True,
        "phone_number": "555-555-5555",
        "email": [email protected],
        "order_identifier_pattern": "EFK",
        "is_active": True,
    }
    response = client.post("api/actors", json=actor)
    assert response.status_code == 422


# @pytest.mark.skip(
#     "Test works if running just this file; fails if running pytest on project - drop_all is not happening so we have actors from previous tests"
# )
def test_get_actors_returns_all(db_engine):
    print("Last test")
    actor = {
        "identity_id": 933,
        "is_human": True,
        "display_name": "Eddie Kubernetti",
        "email": [email protected],
        "order_identifier_pattern": "EFK",
        "is_active": True,
    }
    _ = client.post("api/actors", json=actor)
    actor["identity_id"] = 1004
    _ = client.post("api/actors", json=actor)

    # act
    response = client.get("api/actors")

    assert response.status_code == 200

    data = response.json()

    assert len(data) == 2
0

There are 0 best solutions below