4

I'm writing pytest tests for my FastAPI async project. Tests causes error :

session.add(user)

AttributeError: 'async_generator' object has no attribute 'add'

conftest.py:

SQLALCHEMY_DATABASE_URL = f'postgresql+asyncpg://{USER}:{PASSWORD}@{HOST}/{DB}_test'

engine = asyncio.create_async_engine(SQLALCHEMY_DATABASE_URL)
SessionTesting = sessionmaker(
    bind=engine,
    autocommit=False,
    autoflush=False,
    expire_on_commit=False,
    class_=asyncio.AsyncSession
)


@pytest.fixture(name='session')
async def session_fixture() -> Generator[SessionTesting, None, None]:
    Base.metadata.create_all(engine)
    async with SessionTesting(bind=engine.connect()) as session:
    yield session
    Base.metadata.drop_all(engine)

test_auth.py:

@pytest.mark.asyncio
async def test_get_token(session: SessionTesting, create_user):
    # async with AsyncClient(app=app, base_url='http://test') as ac:
    user = User(
    first_name='fixture',
    last_name='fixture',
    username='fixture',
    password=await get_hash('fixture')
    )
    session.add(user)
    await session.commit()
    async with AsyncClient(app=app, base_url='http://localhost:8000') as ac:
    credentials = {
        'username': 'fixture',
        'password': 'fixture'
    }
    response = await ac.post('/token/get_token', data=credentials, headers={"content-type": "application/x-www-form-urlencoded"})
    assert response.status_code == 200

Any ideas?

3
  • 1
    Does this answer your question? AttributeError in pytest with asyncio after include code in fixtures Commented Jun 5, 2023 at 14:14
  • I tried this: Set asyncio_mode to auto—see readthedocs and concepts—in which case you can omit pytest.mark.asyncio and use pytest.fixture for fixtures, OR Error is the same Commented Jun 5, 2023 at 14:59
  • I tried to change pytest.fixture to this: @pytest_asyncio.fixture(name="session") tests/conftest.py:52: in session_fixture Base.metadata.create_all(engine) AttributeError: 'AsyncEngine' object has no attribute '_run_ddl_visitor' Commented Jun 5, 2023 at 14:59

1 Answer 1

2

You are yielding session (which seems to also be a fixture defined somewhere above) inside session_fixture, but you are not passing it as an argument to session_fixture. That results in yielding async generator instead of session.

@pytest.fixture(name='session')
async def session_fixture():
    ...

should be

@pytest.fixture(name='session')
async def session_fixture(session):
    ...

and also

@pytest.mark.asyncio
async def test_get_token(session: SessionTesting, create_user):

should be

@pytest.mark.asyncio
async def test_get_token(session_fixture: SessionTesting, create_user):
Sign up to request clarification or add additional context in comments.

1 Comment

I did everything with pytest_asyncio but anyway thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.