0
votes

I have a Flask application with a POST endpoint that I would like to test. The endpoint does some database munging, and in this particular case I'm trying to assert that calling the endpoint with a particular set of data doesn't change the database.

I have a pytest fixture for my database model, an autouse=True fixture that runs the test in a database transaction, and a fixture to generate a Flask test_client:

@pytest.fixture()
def myfixture():
    return MyModel.create(...)

@pytest.fixture
def testapp():
    app.config['TESTING'] = True

    with app.app_context():
        yield app.test_client()

@pytest.fixture(autouse=True)
def with_database_txn():
    with db.atomic() as txn:
        yield
        txn.rollback()

This works very well for most tests. However, when I'm testing calling my endpoints, I experience a strange issue with my database records:

def test_endpoint(myfixture, testapp):
    assert MyModel.select().count() == 1

    r = app.test_client().post('/endpoint', headers={...}, data=json.dumps({...}))

    assert r.status_code == 200
    assert r.data.decode() == 'no changes'

    assert MyModel.select().count() == 1

My test fails on the final assert, claiming that MyModel.select().count has become 0. The record still exists before the request returns, which I've verified in the handler for /endpoint.

I am assuming (guessing, even) that there is some strange interaction going on between pytest's fixtures, peewee's transactions and flask's request contexts that is causing the transaction to be rolled back before the second assertion is hit, but I can't find any information on what might be happening.

Viewing peewee's log at DEBUG level doesn't provide any information above the insertion of the fixtures and the selection of the records, though interestingly it also doesn't show anything to do with transactions at all, which I'm sure it used to... a smoking gun or simply a change in a recent version?

Either way, any help to track down what is going on would be most appreciated!

1
Could you add your endpoint code? How you initialize app in project and in tests?Danila Ganchar
@DanilaGanchar this turned out to be my mistake in the end, see my answer!kfb

1 Answers

0
votes

In the end this turned out to be a mistake on my end—the database was being closed in another call somewhere in the depths of my code. Sorry for the noise!