Fixture

Encapsulates one or more datasets to be loaded into a storage medium.

Most likely you will only use one of the wrapper classes designed for dealing with a specific storage medium (i.e. SOFixture for SQLObjects or CsvFixture for csv files).

before looking at how you load data and work with it, here is how fixtures are designed to work inside a test case:

>>> from testtools.testself.myfixtures import EmployeeData
>>> class TestTPSCoverSheet:
...     def setUp(self):
...         self.fxt = EmployeeData()
...     def tearDown(self):
...         self.fxt.clean()
>>>

Keyword Arguments

  • data -- if this is not None then your data will be loaded from here.

    see Defining Data. Setting this keyword will also make your object unregistrable.

  • stor_obj -- object to store data. if you don't provide this here or in meta, you will get a ValueError.

  • clean -- if this is True, your object is cleanable, meaning that its

    data can be deleted from the storage object (i.e. when db load fails, all will be deleted for you in try/except). Defaults to False.

  • build_meta -- if this is True then the internal meta object will be

    built from the outermost parent class (defaults to True). This is only provided so that wrapper classes can do their own building, which was necessary for some reason.

  • is_registrable -- if True (the default) the fixture object will have its data loaded only once per class instance unless data is

    unloaded via Fixture.clean`(). This is set internally for file-based fixtures (i.e. `CsvFixture ) and the like.

Now for the more low level examples ...

Example with CsvFixture

>>> from testtools.fixtures import CsvFixture
>>> class Products(CsvFixture):
...     class meta:
...         data = ( ('product_on_sale', {'name':'toy truck', 'on_sale':True}), )
>>> fxt = Products(filename='/tmp/testtools_example.csv' )
>>> fxt.product_on_sale
<class 'Fixture.Values' dict(on_sale='True', name='toy truck') from module testtools.fixtures.fixtures>

Defining data

Data is an iterable of tuples where each row unpacks to a context key and dictionary of values. The context key becomes an attribute and/or dictionary key in the fixture object.

For example:

>>> # NOTE: the trailing comma here forces the type into a tuple :
>>> fxt.load( (('reversible_slacks_on_sale',
...             {'name': 'slacks, reversible', 'on_sale': True}),) )
>>> fxt.reversible_slacks_on_sale
<class 'Fixture.Values' dict(on_sale='True', name='slacks, re...') from module testtools.fixtures.fixtures>

A fixture's data can also be set in the following ways, respectively :

From the data keyword :

>>> from testtools.testself.model import Employee
>>> from testtools.fixtures import SOFixture
>>> fxt = SOFixture(data = (
...     ('bob', {'name':'bob','hair_color':'black'}),),
...                                     so_class=Employee)
>>> fxt.bob
<class 'Fixture.Values' dict(name='bob', hair_color='black') from module testtools.fixtures.fixtures>

from meta.data :

>>> # here the SQLObject "Employee" is pulled out from meta.env
>>> # because it matches the class name employee
>>> from testtools.testself import model
>>> class Employee(SOFixture):
...     class meta:
...         env = model
...         data = (('jane', {'name':'jane','hair_color':'brown'}),)
>>> fxt = Employee()
>>> fxt.jane
<class 'Fixture.Values' dict(name='jane', hair_color='brown') from module testtools.fixtures.fixtures>

... or by defining a data() method :

>>> # or you can set meta.so_class to the specific SQLObject
>>> class JaneEmployee(SOFixture):
...     class meta:
...         so_class = model.Employee
...     def data(self):
...         return (('jane', {'name':'jane','hair_color':'brown'}),)
>>> fxt = JaneEmployee()
>>> fxt.jane
<class 'Fixture.Values' dict(name='jane', hair_color='brown') from module testtools.fixtures.fixtures>

A Word About Meta

Fixture.meta is a namespace for common properties and is populated with any keyword arguments (above) that might be passed in to an instance. Most Fixture wrappers, like SOFixture , use meta to set up some common attributes for you. With the exception of "build_meta" all default meta attributes are defined like the Keyword Arguments, documented above.

I.E. all instances of EmployeeData will share the same data and will only be loaded once ... but DepartmentData instances have their own data.


Methods

f __init__(self, data=None, build_meta=True, clean=False, is_registrable=True) ...

see Fixture for signature.

f __len__(self) ...

f add_fixture(self, fixture) ...

merges attributes from another fixture into self.

f assert_has(self, dataset, transkey=None, transval=None, quiet=False) ...

assert this fixture has a dataset somewhere in it.

fetching dataset items will be tried like: dataset.key and dataset[key]

Keyword arguments

  • transkey -- dict called like: ''dataset_key = transkey[fixture_key]'' to match dataset items with fixture items
  • quiet -- True if you don't want a big explanation of mismatches

f clean(self, cascade=True) ...

perform clean() on all storage objects loaded for this instance only.

goes in reverse order so foreign key constraints aren't violated. does not clean self's fixture attributes.

NOTE: clean() raises an error if self.meta.clean is False. See Fixture doc for more info on meta.clean

f close(self) ...

f data(self) ...

hook for subclasses to return a data definition.

returns a tuple of tuples. see class signature for example of the format

f items(self) ...

yields (fixture_key, fixture) in self.

f load(self, data=None, stor_obj=None, clean=False) ...

load all data using stor_obj.save().

data is an iterable of context and dataset that looks like this::
(('context1', {} ), ('context2', {} ), ... )

Each dataset is stored in self as an attribute (or key) named context. For example, self.context1 == {}. if clean is True, calls stor_obj.clean() before loading.

See the source for more information.