New "random_instances" package: gets or creates random instances so you don't have to

19 views
Skip to first unread message

claudioB

unread,
Jan 21, 2011, 3:22:19 PM1/21/11
to Lettuce Developers, gab...@nacaolivre.org
After a couple of weeks using lettuce I found out that one of the
steps I use most often is:

Given there is a Photographer

(substitute Photographer for any Django model you have). For instance,
one typical scenario is:

Given there is a Photographer
And I navigate to his detail page
Then I should see his pictures

In this kind of story, I don't care *which* photographer the test will
run against: any will (or should) work. So the most straightforward
implementation of this step would be:

Photographer.objects.get_or_create()

that either returns an existing photographer or creates a new one. The
problem with Django's get_or_create function is that it will *fail* if
the query returns multiple instances (in the previous case, if there
are multiple photographers).

What I need is a function that returns a *random* instance if any
exists, otherwise creates a new one.

For this purpose, I have created a new Django package called
random_instances (https://github.com/ff0000/random_instances) which
exports a *get_or_create_random* functions that does exactly this.


BASIC USAGE
-----------------------

Using this package, the step

Given there is a Photographer

can be easily implemented as:

from random_instances import get_or_create_random
get_or_create_random(Photographer)


OPTIONAL FIELDS
-----------------------------

This function follows the prototype of Django's get_or_create (http://
www.djangoproject.com/documentation/models/get_or_create/), so you can
pass desired and default values for the model's field. For instance,
say that Photographer has a "name" CharField, an "is_famous"
BooleanField and an "avatar" ImageField, then you can have the step:

Given there is a Photographer named "Helmut Newton"

easily implemented as:

get_or_create_random(Photographer, name="Helmut Newton")

which will either return that photographer (if existing) or create a
new one.
If you have this step as the Background of a Scenario (that is,
executed before each scenario), then the instance will only be created
the first time, and retrieved the successive ones, resulting in better
performance (shorter time) for the test suite to complete.


REQUIRED FIELDS
-----------------------------

What happens if get_or_create_random is invoked without specifying a
value for a required field?
For instance, imagine that the Photographer model has an "is_famous"
BooleanField that is required (blank=False, null=False) and does not
have a default value. If your step states:

Given there is a Photographer named "Helmut Newton"

then you do not really care about the value of "is_famous", so it
would be a waste of time to specify one just because the field is
required. The solution provided by get_or_create_random is quite
intuitive: every field that is required and does not have a default
value is *automatically* assign a *random* value, coherently with the
field type (e.g., a random string for CharField, a random number for
IntegerField, a random image for ImageField).

For this reason, the implementation

get_or_create_random(Photographer, name="Helmut Newton")

would still work, even without specifying a value for "is_famous",
which would be randomly set to True or False. If you really care about
this value, then you can always set it explicitly, e.g.:

Given there is a famous Photographer named "Helmut Newton"

which would be implemented as:

get_or_create_random(Photographer, name="Helmut Newton",
is_famous=True)


I hope you try it out and tell me what you think.

I think random_instances can be beneficial to lettuce users, although
it has a broader extent (can be actually used inside the same Django
application to generate random instances of models… but I don't see
the point of that). For me, it's a faster and more meaningful way to
create fixtures (you only specify the fields that you are interested
in). Can you suggest any other Google Group/mailing list that might be
interested in this package? Thanks again!

Vladimir Shulyak

unread,
Jan 21, 2011, 3:33:34 PM1/21/11
to lettuce-d...@googlegroups.com
Hello Claudio,

Probably you should send a pull request to django-model-utils. I use this app for every Django project, so it would be nice to see get_or_create_random there.

Cheers,
Vladimir Shulyak

2011/1/21 claudioB <clau...@gmail.com>

Gabriel Falcão

unread,
Jan 21, 2011, 9:03:17 PM1/21/11
to lettuce-d...@googlegroups.com
Hey guys,

awesome works!

I'm gonna create a new topic on lettuce's official docs about those "salad recipes"

cheers!

2011/1/21 Vladimir Shulyak <nc0...@gmail.com>



--
 -- Gabriel Falcão
Reply all
Reply to author
Forward
0 new messages