fixture utils for python ORMs
Project description
distillery is another factory_girl like library for python ORMs.
Installation
pip install distillery
Distilleries
Each distillery has a __model__ and a set of attributes and methods. The __model__ is the ORM model class from which instance will be produced:
class UserDistillery(MyOrmDistillery):
__model__ = User
Attributes
A distillery class attribute defines default values for specific model field:
class UserDistillery(MyOrmDistillery):
__model__ = User
username = "defaultusername"
The distillery’s attribute values act as defaults. If a User object is created using this distillery, its username attribute will default to "defaultusername".
Lazy attributes
Using the lazy decorator, you can provide dynamic attributes.
from distillery import lazy
class UserDistillery(MyOrmDistillery):
__model__ = User
username = "defaultusername"
@lazy
def email_address(cls, instance, sequence):
return "%s@%s" % (instance.username, instance.company.domain)
All new User created from UserDistillery will have an email_address computed from his username and his company domain.
Note: all lazies received an instance and a sequence that are the object instance and an auto-incremented sequence, respectively.
Hooks
A distillery can provide an _after_create class method to hook into the factory machinery.
class UserDistillery(MyOrmDistillery):
__model__ = User
username = "defaultusername"
@classmethod
def _after_create(cls, instance):
# Do stuff after instance creation
# ...
Distillery.init()
The init() method creates and populates a new instance.
user = UserDistillery.init()
assert user.username == "defaultusername"
assert user.id is None
user = UserDistillery.create(username="overriddenusername")
assert user.username == "overriddenusername"
assert user.id is None
Distillery.create()
The create() method initializes the object using init() and subsequently saves it.
user = UserDistillery.create()
assert user.username == "defaultusername"
assert user.id is not None
Distillery.bulk()
Creates instances in bulk.
users = UserDistillery.bulk(12, username="user_%(i)%")
assert users[7].username = 'user_7'
Sets
The distillery.Set class acts as a fixture container.
It’s required to define a __distillery__ attribute which is used to create objects.
from distillery import Set
class UserSet(Set):
__distillery__ = UserDistillery
class jeanphix:
username = 'jeanphix'
To create the fixtures, simply instantiate the set.
users = UserSet()
assert users.jeanphix.username == 'jeanphix'
Importantly, as long as a reference to the instantiated set is held (e.g. the users variable in this example), the set can be called again and the same instance is returned:
assert UserSet() is UserSet()
You can reference other sets, too. Note that you must reference using the class, or use a lazy attribute (described later):
from distillery import Set
class CompanySet(Set):
__distillery__ = CompanyDistillery
class my_company:
name = 'My company'
class UserSet(Set):
__distillery__ = UserDistillery
class jeanphix:
username = 'jeanphix'
company = CompanySet.company
users = UserSet()
assert users.jeanphix.company == 'My company'
In addition to classes, methods can be defined; each will result in an object which is added to the set.
class ProfileSet(Set)
class __distillery__:
__model__ = Profile
admin = lambda s: UserDistillery.create(username='admin').profile
This functionality extends to class-based references. Note that the reference must be resolvable at the point of creation; circular relationships are currently not supported.
class UserSet(Set):
class peter:
friend = None
class paul:
friend = classmethod(lambda c: UserSet.peter)
If the on_demand flag is set, objects are created only when first accessed.
users = UserSet(on_demand=True)
users.jeanphix # jeanphix will be created here.
Finally, sets can be nested.
class fixtures(Set):
users = UserSet
assert fixtures().users.jeanphix.username == 'jeanphix'
Hooks
Each fixture in a set can provide an _after_create listener:
class ProfileSet(Set):
class __distillery__:
__model__ = Profile
class admin:
@classmethod
def _after_create(cls, profile):
profile.name = 'Full name'
assert ProfileSet().admin.name == 'Full name'
ORMs
Both Django and SQLAlchemy are supported.
Django
Django models could be distilled using DjangoDistillery that only requires a __model__ class member:
from distillery import DjangoDistillery
from django.auth.models import User
class UserDistillery(DjangoDistillery):
__model__ = User
# ...
SQLAlchemy
SQLAlchemy distilleries require both the __model__ and __session__ attributes.
from distillery import SQLAlchemyDistillery
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite://', echo=False)
Session = sessionmaker()
Session.configure(bind=engine)
session = Session()
Base = declarative_base()
class User(Base):
# ...
class UserDistillery(SQLAlchemyDistillery):
__model__ = User
__session__ = session
# ...
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.