Test Fixture Factory for SQLAlchemy. Inspired by Ruby's factory_girl
Project description
A fixture factory for SQLAlchemy ORM mapper to easily build test scenarios for unit or integration testing. Inspired by Ruby’s factory_girl
Installation
pip install sqlalchemy-fixture-factory
Usage
Assume following plain SQLAlchemy ORM models:
# association table
account_role = Table('account_role', Base.metadata,
Column('id_account', Integer, ForeignKey('account.id')),
Column('id_role', Integer, ForeignKey('role.id')))
class Role(Base):
__tablename__ = 'role'
id = Column(Integer, primary_key=True)
name = Column(Unicode)
class Account(Base):
__tablename__ = 'account'
id = Column(Integer, primary_key=True)
name = Column('name', Unicode)
roles = relationship(Role, secondary=account_role)
class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
first_name = Column('first_name', Unicode)
account_id = Column(Integer, ForeignKey('account.id'))
account = relationship(Account)
Initialize SQLAlchemy-Fixture-Factory:
# SQLAlechemy DB session generated from SessionPool
fix_fact = SqlaFixFact(db_session)
Define a simple person fixture:
class FranzPerson(BaseFix):
MODEL = Person
first_name = 'Franz'
The property MODEL needs to be set with the desired ORM class. Then simply set the fields as desired. In this example the first_name with Franz.
Use this fixture:
franz_fix = FranzPerson(fix_fact).create()
print ("Person count:", db_session.query(Person).count())
# output: 1
# create more instances of the same fixture
franz_fix_2 = FranzPerson(fix_fact).create()
franz_fix_3 = FranzPerson(fix_fact).create()
print ("Person count:", db_session.query(Person).count())
# output: 3
print ("Instances and id's are different:",
franz_fix != franz_fix_2 != franz_fix_3,
franz_fix.id != franz_fix_2.id != franz_fix_3.id)
# output: True True
# alter fields at instantiation time
franz_fix_alt_name = FranzPerson(fix_fact, first_name='Sepp').create()
print ("Person count with first_name 'Sepp':",
db_session.query(Person).filter(Person.first_name == "Sepp").count())
# output: 1
Alternatively, retrieve the model without instantiating the fixture, but create the dependencies with .model()
# retrieve only the (altered) model
franz_model_alt_name = FranzPerson(fix_fact, first_name='Hugo').model()
print ("Person count with first_name 'Hugo':",
db_session.query(Person).filter(Person.first_name == "Hugo").count())
# output: 0
db_session.add(franz_model_alt_name)
print ("Person count with first_name 'Hugo':",
db_session.query(Person).filter(Person.first_name == "Hugo").count())
# output: 1
If you need the same instance in different fixtures, use .get()
# clean up the DB
Base.metadata.drop_all(connection)
Base.metadata.create_all(connection)
# first call creates the fixture and caches the reference
franz_get = FranzPerson(fix_fact).get()
franz_get_2 = FranzPerson(fix_fact).get()
franz_get_3 = FranzPerson(fix_fact).get()
print ("Person count:", db_session.query(Person).count())
# output: 1
print ("Instances and id's are the same:",
franz_get == franz_get_2 == franz_get_3,
franz_get.id == franz_get_2.id == franz_get_3.id)
# output: True True
Build a more complex scenario:
class ViewRole(BaseFix):
MODEL = Role
name = "View Role"
class EditRole(BaseFix):
MODEL = Role
name = "Edit Role"
class ArnoldAccount(BaseFix):
MODEL = Account
name = "arney"
# Use get to reference to the roles, as only one instance in the DB is desired
roles = [sqla_fix_fact.subFactoryGet(ViewRole), sqla_fix_fact.subFactoryGet(EditRole)]
class ArnoldPerson(BaseFix):
MODEL = Person
name = "Arnold"
account = sqla_fix_fact.subFactoryModel(ArnoldAccount)
To instantiate the ArnoldPerson fixture, following line is sufficient to create the person with all dependencies:
arnold_fix = ArnoldPerson(fix_fact).create()
Query the DB to see if everything is in place as expected:
arnold_db = db_session.query(Person).get(arnold_fix.id)
print ("Account name of Arnold:", arnold_db.account.name)
# output: arney
print ("Roles of Arnold:", [r.name for r in arnold_db.account.roles])
# output: ['View Role', 'Edit Role']
You can find this examples ready to play around in readme_examples.py
Resources
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for SQLAlchemy-Fixture-Factory-1.0.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 050d25fb1766769b15770e0a9b05d07eb610060e43fb4789b55fbed9bdcb03f5 |
|
MD5 | 5fdd61bbe3a70354c54cd1ccb800b682 |
|
BLAKE2b-256 | ee72346179e8ee97b32048423a57e6483b4b33a7640c363a61458ec41a222f0d |
Hashes for SQLAlchemy_Fixture_Factory-1.0.0-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3df544165e616adf9ce6e1c1cbdf3820b0efc709f0bc6fc3e00ba4731038e0a6 |
|
MD5 | 3b01bf52c846983dfcfc38eff4d1f38b |
|
BLAKE2b-256 | a54defcc4c406c3ae4824f003893af65cba24832591e4f702be679d7e99c3476 |