Testing with SQL Alchemy and sqlahelper

40 views
Skip to first unread message

Jason

unread,
Jan 26, 2012, 11:23:15 AM1/26/12
to pylons-...@googlegroups.com
Hello,
I am trying to do unit tests of my handler actions (using pyramid_handlers) and I would like the test method and the view-callable to use the same database transaction which gets rolled back after each test.

I have a test fixture that creates a database engine in the setUp method:

def setUp(self):
    settings = appconfig('config:test.ini', name=myapp, relative_to=os.getcwd())
    engine = sa.engine_from_config(settings, prefix="sqlalchemy.") 
    conn = engine.connect()
    self.trans = conn.begin()
    sqlahelper.get_session().configure(bind=conn)
    self.session = sqlahelper.get_session()

The engine.connect() and conn.begin() is supposed to create a non-orm transaction and bind the session held in sqlahelper to that transaction (I followed the docs at http://docs.sqlalchemy.org/en/latest/orm/session.html#joining-a-session-into-an-external-transaction ). At first I tried without this because I thought that the same thread would always get the same session, but it behaved the same way as described below.

In the tearDown it rollsback the transaction, closes the self.session, and resets sqlahelper.

There is a test method that calls a view-callable that modifies and saves (using Session.flush()) an SQLAlchemy model instance. The test method then issues a query using self.session, but it does not see the changes because it is not in the same transaction as the view-callable's session.

The next test methods (which are all read-only) do see the changes, but I don't know why this happens since I reset sqlahelper in the tearDown() between tests.

After all the tests finish the session that altered the model does is rolled back, but this is probably due to not calling commit in the transaction manager and not because of my explicit rollback call in tearDown.

Has anyone successfully setup testing with SQLAlchemy without rebuilding an entire database on every test?

Thanks,
Jason

Michael Merickel

unread,
Jan 26, 2012, 1:07:33 PM1/26/12
to pylons-...@googlegroups.com
I'd suggest you write your unit tests in a transactional way. setUp will begin a transaction and tearDown rollback the transaction. This will allow you to setup the database once, and have it in the original state at the start of each test. This means doing the population of the database, sqlahelper, engine, etc all only one time (possibly module scope, or in setUpModule or setUpClass). If I remember right you don't even need a setUp, you can just create a tearDown that does transaction.rollback() and a new transaction will begin at the start of each test.

Jason

--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/pylons-discuss/-/jqbX6xHc1CwJ.
To post to this group, send email to pylons-...@googlegroups.com.
To unsubscribe from this group, send email to pylons-discus...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en.

Jason

unread,
Jan 26, 2012, 1:17:39 PM1/26/12
to pylons-...@googlegroups.com
Ah ha! All I had to do was to run transaction.abort() in the tearDown and I could leave the setup as a normal session setup instead of trying to make an external transaction that the session runs in.

Thanks,

Jason
Reply all
Reply to author
Forward
0 new messages