schireson / pytest-mock-resources

Pytest Fixtures that let you actually test against external resource (Postgres, Mongo, Redshift...) dependent code.
https://pytest-mock-resources.readthedocs.io/en/latest/quickstart.html
MIT License
179 stars 19 forks source link

Postgres container doesnt start #211

Closed funkindy closed 5 months ago

funkindy commented 5 months ago

Hi! First of all its a great lib, thanks a lot.

I just wanted to play around with pmr and made a minimal setup for PG engine like this:

@pytest.fixture(scope='session')
def pmr_postgres_config():
    return PostgresConfig(drivername='postgresql+asyncpg', image='postgres:16')

@pytest.fixture(scope='session', autouse=True)
async def async_engine(pmr_postgres_config):
    test_url = URL.create(
        drivername=pmr_postgres_config.drivername,
        username=pmr_postgres_config.username,
        password=pmr_postgres_config.password,
        host=pmr_postgres_config.host,
        port=pmr_postgres_config.port,
        database=pmr_postgres_config.root_database,
    )
    engine = create_async_engine(test_url)
    yield engine
    await engine.dispose()

The problem is when i use this engine in my tests i get connection error like this [Errno 61] Connect call failed ('::1', 5532, 0, 0), [Errno 61] Connect call failed ('127.0.0.1', 5532). Also pg container doesnt start (empty docker ps on breakpoint)

Is there anything else i need to do manually or via code? I expected that containers would somehow start automatically. Docker itself is up and running, image is pulled and i can run it manually.

Thank you!

Environment

Expected behavior PG container is up with desired settings

DanCardin commented 5 months ago

you'd want to do something more like

from pytest_mock_resources import create_postgres_fixture

pg = create_postgres_fixture(async_=True)

Under the hood, this fixture is depending on pmr_postgres_container fixture and doing other fancy things (like waiting for the container to be ready), which is what is causing the container to spin up. Without that here, your fixture is just depending on the config fixture and not invoking any of the plugin internals.

Once you have this fixture, you can depend on it on with other fixtures; for example, if you wanted to retain your autouse usage.

@pytest.fixture(scope='session', autouse=True)
async def async_engine(pg):
    pass

With that said, I'd consider most scenarios that force you into redefining the fixture for this kind of purpose to be a defect of the library (i.e. we should add an autouse flag, if so)

funkindy commented 5 months ago

Thank you for fast response. Its getting better, i can now use pg fixture to run container and make connections. I now want to obtain the actual database name for tests (i dont want to hardcode pytest_mock_resource_db_*) so i can instantiate separate engine and use it in my tests flow.

Can you share any suggestions on how this can be done correctly? Or is it possible at all from pg fixture.

Thank you.

funkindy commented 5 months ago

Got it, pg.engine.url.database