f metamethod(fn) ...

makes a method Fixture.meta -compatible

This is necessary when assigning a callable Fixture.meta attribute. It will return your method so that it can be called without taking in the meta class object as the first argument.

testtools.fixtures.storable.CsvFixture will show you an example of how a Fixture might accept a factory method in its meta.

f with_fixtures(*fixtures, **cfg) ...

decorator that attaches fixtures to a test def.

Positional args are Fixture classes to be instantiated and passed into affix

The resulting FixtureCollection object will be the first argument to your decorated def

Keyword Args:

  • clean -- when True (default), all fixtures will be cleaned in a finally block
  • setup -- a callable to be executed before test
  • teardown -- a callable to be executed (finally) after test

For example :

>>> from testtools.fixtures import CsvFixture, with_fixtures
>>> class MyBooks(CsvFixture):
...     class meta:
...         filename = open('/tmp/testtools_example.csv', 'w')
...         data = (('lolita', {'title':'lolita'}),)
...         clean = True
>>> @with_fixtures(MyBooks)
... def test_with_books(fxt):
...     print fxt.lolita
...     # test something ...
>>> test_with_books()
<class 'Fixture.Values' dict(title='lolita') from module testtools.fixtures.fixtures>


C 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 :

>>> # 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.

This class contains 12 members.

C affix(...) ...

returns a collection of Fixture instances, all attributes shared.

accepts fixture instances as arguments, returns an instance with all attributes combined.

This class contains 12 members.

C FixtureCollection(...) ...

returns a collection of Fixture instances, all attributes shared.

accepts fixture instances as arguments, returns an instance with all attributes combined.

This class contains 12 members.

See the source for more information.