sqlalchemy的测试夹具工厂。灵感来自鲁比的工厂女孩
SQLAlchemy-Fixture-Factor的Python项目详细描述
一个用于sqlalchemy orm映射器的fixture工厂,可以轻松地为单元或集成测试构建测试场景。 灵感来自ruby的factory_girl
安装
pip install sqlalchemy-fixture-factory
用法
假设以下是简单的sqlalchemy orm模型:
# association tableaccount_role=Table('account_role',Base.metadata,Column('id_account',Integer,ForeignKey('account.id')),Column('id_role',Integer,ForeignKey('role.id')))classRole(Base):__tablename__='role'id=Column(Integer,primary_key=True)name=Column(Unicode)classAccount(Base):__tablename__='account'id=Column(Integer,primary_key=True)name=Column('name',Unicode)roles=relationship(Role,secondary=account_role)classPerson(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)
初始化sqlalchemy fixture工厂:
# SQLAlechemy DB session generated from SessionPoolfix_fact=SqlaFixFact(db_session)
定义一个简单的人员固定装置:
classFranzPerson(BaseFix):MODEL=Personfirst_name='Franz'
属性MODEL需要用所需的orm类设置。然后根据需要简单地设置字段。 在本例中,first_name与Franz一起使用。
使用此夹具:
franz_fix=FranzPerson(fix_fact).create()print("Person count:",db_session.query(Person).count())# output: 1# create more instances of the same fixturefranz_fix_2=FranzPerson(fix_fact).create()franz_fix_3=FranzPerson(fix_fact).create()print("Person count:",db_session.query(Person).count())# output: 3print("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 timefranz_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
或者,在不实例化fixture的情况下检索模型,但使用.model()
创建依赖项# retrieve only the (altered) modelfranz_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: 0db_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
如果在不同的fixture中需要相同的实例,请使用.get()
# clean up the DBBase.metadata.drop_all(connection)Base.metadata.create_all(connection)# first call creates the fixture and caches the referencefranz_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: 1print("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
构建更复杂的场景:
classViewRole(BaseFix):MODEL=Rolename="View Role"classEditRole(BaseFix):MODEL=Rolename="Edit Role"classArnoldAccount(BaseFix):MODEL=Accountname="arney"# Use get to reference to the roles, as only one instance in the DB is desiredroles=[sqla_fix_fact.subFactoryGet(ViewRole),sqla_fix_fact.subFactoryGet(EditRole)]classArnoldPerson(BaseFix):MODEL=Personname="Arnold"account=sqla_fix_fact.subFactoryModel(ArnoldAccount)
要实例化ArnoldPersonfixture,以下行足以创建具有所有依赖项的人员:
arnold_fix=ArnoldPerson(fix_fact).create()
查询数据库以查看是否一切按预期到位:
arnold_db=db_session.query(Person).get(arnold_fix.id)print("Account name of Arnold:",arnold_db.account.name)# output: arneyprint("Roles of Arnold:",[r.nameforrinarnold_db.account.roles])# output: ['View Role', 'Edit Role']
您可以在readme_examples.py