python-gino / gino

GINO Is Not ORM - a Python asyncio ORM on SQLAlchemy core.
https://python-gino.org/
Other
2.67k stars 150 forks source link

Gino transaction not rollback with Quart test_client #647

Open lawrencealexander10 opened 4 years ago

lawrencealexander10 commented 4 years ago

Description

I'm trying to write tests for my Quart application. As per this ticket https://github.com/python-gino/gino/issues/512 it appears that pytest-async's fixtures doesn't allow us to yield the connection and rollback and it's suggested that we do something like this within each test:

from myproject import db  # this is the usual gino db

@pytest.mark.asyncio
async def test_something():
    async with db.bind.transaction() as transaction:
        # - first load whatever data into the db
        # - then perform test logic
        # - finally, clean up the DB by rolling back 
        transaction.raise_rollback()`

My issue is that when I utilize Quart's builtin test_client for testing of my routes that use Gino to perform db insert/update operations, my transactions performed in the endpoints are not rolled back. Is there a way to rollback these transactions? Is another db connection being spawned and used from my Pool? Is it because a new asyncio execution context is being used by test_client?

I can provide additional code if the below example is not clear.

What I Did

async def test_something():
    async with db.bind.transaction() as transaction:
        # - first load whatever data into the db
        # - then perform test logic
       ### The operations performed in this call are not rolled back
        response = await test_app.post()
        # - finally, clean up the DB by rolling back 
        transaction.raise_rollback()`
fantix commented 4 years ago

Thanks for the report! A quick heads-up here is that, we are kinda moving the framework extensions (e.g. the Quart plugin in GINO 0.8.x if you are using it) to community support in GINO 1.0 due to lack of hands from the core team, so this kind of issues might not be solved in mainline GINO after its 1.0 release. I'll take a look into this one still when time, but please allow some delay.

lawrencealexander10 commented 4 years ago

Understood. I noticed that some of the tests on the ext frameworks had disappeared. Thanks again!

wwwjfy commented 4 years ago

test_client, as the name suggests, is just a normal http client, so test_app.post only sends requests, but doesn't actually execute the handlers.

One way is to do cleanup at the end of each test case, maybe in a fixture.

lawrencealexander10 commented 4 years ago

@wwwjfy Thanks for the reply! I'm a little confused on how I would do the proposed cleanup. Is there a better way than dropping tables/db after each test? Also as per https://github.com/python-gino/gino/issues/512 connections/transactions cannot be created within a fixture so what type of fixture are you proposing. Currently I have tests running against a static test db which should not be truncated/dropped.

wwwjfy commented 4 years ago

I mean to undo whatever changes are done in the tests, like this https://github.com/python-gino/gino/blob/master/tests/conftest.py#L29 In your case, if possible, I would create a table or db cloning the current ones and drop/truncate that one. Cleaner for tests.

fantix commented 4 years ago

I noticed that some of the tests on the ext frameworks had disappeared.

FYI they're now back here: https://github.com/python-gino/gino-quart