python - Unit tests for Query in SQLAlchemy -
how 1 go testing queries in sqlalchemy? illustration suppose have models.py
from sqlalchemy import ( column, integer, string, ) sqlalchemy.ext.declarative import declarative_base base of operations = declarative_base() class panel(base): __tablename__ = 'panels' id = column(integer, primary_key=true) category = column(integer, nullable=false) platform = column(string, nullable=false) part = column(string, nullable=false) def __init__(self, category, platform, region): self.category = category self.platform = platform self.region = part def __repr__(self): homecoming ( "<panel('{self.category}', '{self.platform}', " "'{self.region}')>".format(self=self) )
and tests.py
import unittest sqlalchemy import create_engine sqlalchemy.orm import sessionmaker models import base, panel class testquery(unittest.testcase): engine = create_engine('sqlite:///:memory:') session = sessionmaker(bind=engine) session = session() def setup(self): base.metadata.create_all(self.engine) self.session.add(panel(1, 'ion torrent', 'start')) self.session.commit() def teardown(self): base.metadata.drop_all(self.engine) def test_query_panel(self): expected = [panel(1, 'ion torrent', 'start')] result = self.session.query(panel).all() self.assertequal(result, expected)
when seek running test, fails, though 2 panels identical.
$ nosetests f ====================================================================== fail: test_query_panel (tests.testquery) ---------------------------------------------------------------------- traceback (most recent phone call last): file "/users/clasher/tmp/tests.py", line 31, in test_query_panel self.assertequal(result, expected) assertionerror: lists differ: [<panel('1', 'ion torrent', 's... != [<panel('1', 'ion torrent', 's... first differing element 0: <panel('1', 'ion torrent', 'start')> <panel('1', 'ion torrent', 'start')> [<panel('1', 'ion torrent', 'start')>, <panel('2', 'ion torrent', 'end')>] ---------------------------------------------------------------------- ran 1 test in 0.063s failed (failures=1)
one solution i've found create query every single instance expect find in query:
class testquery(unittest.testcase): ... def test_query_panel(self): expected = [ (1, 'ion torrent', 'start'), (2, 'ion torrent', 'end') ] successful = true # check create sure every expected item in query try: category, platform, part in expected: self.session.query(panel).filter_by( category=category, platform=platform, region=region).one() except (noresultfound, multipleresultsfound): successful = false self.asserttrue(successful) # check create sure no unexpected items in query self.assertequal(self.session.query(panel).count(), len(expected))
this strikes me pretty ugly, though, , i'm not getting point have complex filtered query i'm trying test. there more elegant solution, or have manually create bunch of individual queries?
your original test on right track, have 1 of 2 things: either create sure 2 panel
objects of same primary key identity compare true
:
class panel(base): # ... def __eq__(self, other): homecoming isinstance(other, panel) , other.id == self.id
or can organize test such create sure you're checking against same panel
instance (because here take advantage of identity map):
class testquery(unittest.testcase): def setup(self): self.engine = create_engine('sqlite:///:memory:') self.session = session(engine) base.metadata.create_all(self.engine) self.panel = panel(1, 'ion torrent', 'start') self.session.add(self.panel) self.session.commit() def teardown(self): base.metadata.drop_all(self.engine) def test_query_panel(self): expected = [self.panel] result = self.session.query(panel).all() self.assertequal(result, expected)
as far engine/session setup/teardown, i'd go pattern utilize single engine tests, , assuming schema fixed, single schema tests, create sure info work performed within transaction can rolled back. session
can made work way, such calling commit()
doesn't commit "real" transaction, wrapping whole test within explicit transaction
. illustration @ http://docs.sqlalchemy.org/en/rel_0_8/orm/session.html#joining-a-session-into-an-external-transaction illustrates usage. having ":memory:" engine on every test fixture take lot of memory , not scale out other databases besides sqlite.
python unit-testing sqlalchemy
No comments:
Post a Comment