modifying database in webtest based testing

11 views
Skip to first unread message

Zsolt Ero

unread,
Jun 24, 2021, 1:34:02 PM6/24/21
to pylons-discuss
Hi,

I have my webtest based testing set up like the following.

@pytest.fixture(scope="session")
def app():
    testing_config = {
        'sqlalchemy.url': 'postgresql+psycopg2://x@/x',
        'redis.sessions.secret': 'x',  # random string
        'redis.sessions.db': 1,
        'tm.annotate_user': 'no',
    }

    return main({"testing": True}, **testing_config)


@pytest.fixture
def testapp(app):
    return TestApp(app)

main() is a config.make_wsgi_app().

My questions is, how can I have direct database connection - normally a request.dbsession in the app - in the testing fixtures? I'd like to run some DB queries in the setup/teardown process.

I can access testapp.app or "app" from the fixtures, that works. What I don't know is how can I get a request object from there. 

In command line scripts I use 

    request_dummy = Request.blank('/', base_url=base_url)
    env = bootstrap(config_uri, request=request_dummy)
    request = env['request']

Do I need to do something similar here?

Zsolt



Michael Merickel

unread,
Jun 24, 2021, 3:12:10 PM6/24/21
to pylons-...@googlegroups.com
If you have the app, the registry is attached as "app.registry" and you can use the underlying prepare() method with it, same as bootstrap does. See https://docs.pylonsproject.org/projects/pyramid/en/latest/api/scripting.html#pyramid.scripting.prepare.

The rule of thumb is: if you have a registry, use prepare. If you have a config spec (ini file), use bootstrap. Prepare is way more lightweight because it reuses the configured registry whereas bootstrap creates an entirely new registry each time.

- Michael

--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/CAKw-smAqGQjoX1h%2B_rWHjh6Pvi95Vb5RVQ5E%3Djf91B8AW6b1Yg%40mail.gmail.com.

Mike Orr

unread,
Jun 24, 2021, 3:39:37 PM6/24/21
to pylons-...@googlegroups.com
I mock as much as feasible, so I have fake DB Session and Query
classes with a list of fake results to return in order. When I want a
real database connection, I have PyTest fixtures that read the INI
path from a command-line option (pytest_addoption(),
pyramid.paster.getappsettings()), and resolve it to a SQLAlchemy
Session that always rolls back (PyTest request.addfinalizer()). That's
a PyTest's request, not a Pyramid request.

The only time I have to do more is when testing views that call
Pyramid 'request.route_path()'. For those I use something like this:

"""
settings = {...}
with pyramid.testing.testConfig(settings=settings) as config:
config.add_route(...)
request = pyramid.testing.DummyRequest(registry=config.registry)
request.sa_session_main = ... # Emulate property in my real
request subclass. (SQLAlchemy session.)
a = the_view(request)
assert a["my_url"] = expected_url
"""

If necessary I'll use a real Pyramid Request.blank() or my real
Request subclass, but this is sufficient for a lot of cases.

Mike Orr

unread,
Jun 24, 2021, 3:45:29 PM6/24/21
to pylons-...@googlegroups.com
One thing to watch with Postgresql databases in testing is,
autoincrement primary keys do *not* roll back. So on the first test
run the new records may start with 1, but on later runs they may start
with 10,000 or some other absurdly high number, even though the
insertions are always rolled back after every test.
Reply all
Reply to author
Forward
0 new messages