[TIP] How can self.r1 and self.r2 fixture records appear automagically when used?
phlip2005 at gmail.com
Fri Oct 29 23:04:12 PDT 2010
Hi. I'm a test-Nazi, currently working on a new greenfield project
with extremely tight Django requirements.
(Parenthetically: We recently switched from .JSON fixtures (with
SQLite3 :memory: and the transaction-test-cases trick) to Fixture.
(The time to test doubled, from 1 second to 2.5 seconds.
(I hope this implies Fixture will have a flatter response profile as
the number of fixture records and test cases go up!)
That said, I have a code tweak that I'd like help integrating directly
into Fixture. As a test-Nazi, I dislike this kind of test case:
r1 = Record.objects.get(name='r1')
r2 = Record.objects.get(name='r2')
Django makes simple record queries as verbose as raw SQL!
I prefer this:
The self.r1 and self.r2 fixture records appear automagically when used.
Below my sig is the __getattr__() needed to fetch them. But the code
currently binds with my specific object model. This is odious, because
self.fixture is available, so in theory the code could bind thru
Fixture and get the items by their internal class names - not their
name field, which might not exist.
The shim works by taking my_record_model, splitting off the model,
converting it to Model, and querying
Model.objects.get(name=my_record_model). This clearly limits the kinds
of names or other handles that target records can have.
Any idea how to refactor that?
(The shim class is called "SquirrelData" because I think Ruby's
"factory-girl" should be answered with "factory-squirrel". As
from my_app.models import * # eval() needs to see these models.
from fixture.django_testcase import FixtureTestCase
from datasets.sample_database import db_fixture, ThangData, ThangAttributeData
fixture = db_fixture
datasets = [ThangData, ThangAttributeData]
def __getattr__(self, attr):
'CONSIDER Merge this with the fixture project directly!'
sought = re.search(r'^(.*)_([^_]+$)', attr)
record_name, model_name = sought.groups()
model = self._interpret_model(model_name)
record = model.objects.get(name=attr)
setattr(self, attr, record) # So we needn't do it again.
raise AttributeError("%r object has no attribute %r" %
def _interpret_model(self, model_name):
More information about the testing-in-python