Saturday, May 29, 2010

need help writing FactorySquirrel - a custom fixture handler

Django-users:

Our tests take too long to run, so I'm spending the weekend sketching
an alternate fixture system, based on RoR's "factory girl".

The fixtures inject model objects directly into the current namespace,
but this test fails:

class UseFactorySquirrelTests(TestCase, FactorySquirrelTest):

squirrel = ['order'] # injects order models into namespace

def test_isolate_case_fixtures(self):
assert( order_11.bill_lastname not in ('foo', 'bar'),
order_11.bill_lastname )
up(order_11, bill_lastname='foo')

def test_each_test_case_sees_different_instances(self):
assert( order_11.bill_lastname not in ('foo', 'bar'),
order_11.bill_lastname )
up(order_11, bill_lastname='bar')

The test isolation fails because the first test case pollutes the
models' data, and the second one detects the pollution.

The line squirrel = ['order'] pulls in a file order_nuts.py containing
this:

order_11 = squirrel.dig_up(Order, None, id=11
, ship_firstname=u'Rudyard'
, ship_lastname=u'Desuchan'
...
)

the squirrel.dig_up() call trivially calls Order(id=11,
ship_firstname=...) etc.

These lines evaluate the order_nuts.py file:

with open(path, 'r') as q:
exec q in globals()

I will naturally optimize that after it works. This decorator on
TestCase calls it:

class FactorySquirrelTest(TestCase):

def _fixture_setup(self):
self._fs = FactorySquirrel()

for granary in getattr(self, 'squirrel', []):
self._fs.load_granary_file(granary)

#return super(FactorySquirrelTest, self)._fixture_setup()

def _fixture_teardown(self):
#dunn = super(FactorySquirrelTest, self)._fixture_teardown()

for nut in self._fs.nuts.values():
del nut

self._fs.nuts = {}
# return dunn

Note the objects inject into memory, not the database. I will
naturally provide that as an option, going forward. And of course the
squirrel must coexist with classical fixtures; I will decomment the
method chaining methods when they work.

The _setup and _teardown methods really do call before and after each
test case.

So am I mishandling the exec...globals() part? Is there a better way
to register a handler?

Help me bring squirrel-like speed to test cases!

--
Phlip
http://c2.com/cgi/wiki?ZeekLand

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

No comments:

Post a Comment