I have the following piece of code:
conftest.py
fake_users = {
"darth": User(
id=1,
first_name="Darth",
last_name="Vader",
email="[email protected]",
password=User.hash_password("Anakin"),
active=True,
superuser=True,
),
"luke": User(
id=2,
first_name="Luke",
last_name="Skywalker",
email="[email protected]",
password=User.hash_password("Father"),
active=True,
superuser=True,
),
}
@pytest.fixture(scope="function")
def app_with_db():
from app.main import app
from app.api.db import SQLBaseModel, get_session
engine = create_engine(
settings.sql_alchemy_database_url,
connect_args={"check_same_thread": False},
)
def override_get_session():
with Session(engine, autoflush=True) as session:
with session.begin():
yield session
app.dependency_overrides[get_session] = override_get_session
SQLBaseModel.metadata.create_all(bind=engine)
with Session(engine) as session:
for user in fake_users.values():
session.add(user)
session.commit()
yield app
app.dependency_overrides = {}
SQLBaseModel.metadata.drop_all(bind=engine)
then i have my tests.py
def test_create_user_success(app_with_db):
user_data = {
"email": "[email protected]",
"password": "password",
"first_name": "first",
"last_name": "last",
}
headers = {"Content-Type": "application/json"}
client = TestClient(app_with_db)
create_user_response = client.post("/users/", json=user_data, headers=headers)
print(create_user_response.json())
assert create_user_response.status_code == 201
assert create_user_response.json() is None
def test_create_user_already_exists(app_with_db):
darth_user = fake_users["darth"]
user_data = {
"email": darth_user.email,
"password": "password",
}
headers = {"Content-Type": "application/json"}
client = TestClient(app_with_db)
create_user_response = client.post("/users/", json=user_data, headers=headers)
print(create_user_response.json())
assert create_user_response.status_code == 418
assert create_user_response.json()["detail"] == "Unhandled Error"
And I have a problem that if I execute the tests exactly as it is, my second test fails because it correctly creates the user via POST endpoint when it should fail because in the fixture they are created before yielding the app instance.
But if i comment the first test and execute the second one standalone it succeeds.
I understand that each test before being ran executes the code of the fixture until the yield and then once the test is finished it executes the piece of code after the yield. So the test should succeed in this case.
Also if I remove the SQLBaseModel.metadata.drop_all(bind=engine) sentence both tests run succesfully and i can see the db data as it should be:
Does anyone know what's going on here?

the problem is since requests are asynchronous the connection pool is one at a time so you have to setup event loop first. I used AsyncClient instead of TestClient and setting up event_loop in conftest.py file solved my problem still
then sample test_x.py
I was just trying to test your scenario for non-Asynchronous conftest.py
test_item.py
main.py
this works well to me