Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

faker (python) randomizes in shell, but not in DjangoModelFactory object

I have some models for unittest using faker (http://www.joke2k.net/faker/), and it is random in the shell:

In [50]: get_random()
Out[50]: 22347376

In [51]: get_random()
Out[51]: 66840240

In [52]: import factory, random, time

In [53]: from factory import DjangoModelFactory, lazy_attribute

In [54]: from faker import Faker

In [55]: FAKER = Faker(locale='en_US')

In [60]: FAKER.email()
Out[60]: u'[email protected]'

In [61]: FAKER.seed(get_random())

In [62]: FAKER.email()
Out[62]: u'[email protected]'

In [63]: FAKER.seed(get_random())

In [64]: FAKER.email()
Out[64]: u'[email protected]'

In [65]: FAKER.email()
Out[65]: u'[email protected]'

In [66]: FAKER.email()
Out[66]: u'[email protected]'

Seeding is optional. But when I make a new object, I always get that it made the same email:

In [2]: u = User()

In [3]: u
Out[3]: <User: Ut fugiat quasi aperiam provident error iure. Enim dolor totam quia sint. Porro laudantium aut non ducimus veritatis.>

In [5]: u.email
Out[5]: '[email protected]'

In [6]: u = User()

IntegrityError: duplicate key value violates unique constraint "users_user_email_key"
DETAIL:  Key (email)=([email protected]) already exists.

The model looked like:

../users.py:

import factory, time
from factory import DjangoModelFactory, lazy_attribute
from faker import Faker

FAKER = Faker(locale='en_US')

class User(DjangoModelFactory):
    class Meta:
        model   = 'users.User'

    first_name              = FAKER.first_name()
    last_name               = FAKER.last_name()
    email                   = FAKER.email()

And now I have:

import factory, random, time
from factory import DjangoModelFactory, lazy_attribute
from faker import Faker


FAKER = Faker(locale='en_US')

def get_random():
    return int((random.SystemRandom(random.seed()).random())*100000000)

class User(DjangoModelFactory):
    class Meta:
        model   = 'users.User'

    FAKER.seed(get_random())

    first_name              = FAKER.first_name()
    last_name               = FAKER.last_name()
    email                   = FAKER.email()

which made no difference. How can something randomize in the shell, but not on object creation even if fed a seed? Thank you

like image 895
codyc4321 Avatar asked Nov 27 '25 10:11

codyc4321


1 Answers

Looking in your factory, you are setting your attributes to a call to faker, you are not setting them as lazy_attributes. In your factory (which I would strongly recommend naming UserFactory or something similar to prevent confusion with your users.User model), declare your attributes like I have below:

import factory
from factory import DjangoModelFactory, lazy_attribute
from faker import Faker

FAKER = Faker(locale='en_US')

class User(DjangoModelFactory):
    class Meta:
        model   = 'users.User'

first_name              = lazy_attribute(lambda x: FAKER.first_name())
last_name               = lazy_attribute(lambda x: FAKER.last_name())
email                   = lazy_attribute(lambda x: FAKER.email())

This change will cause your factory to call your Faker on every execution instead of just on the initialization of the factory. If you are attempting to generate test data that you want to look at for specific values, you can use the seed() method of your initialized Faker to make sure that your data starts the same every time (for example generating 3 people would always give "John Smith", then "Jane Doe", then "Joe Blow") in case you are specifically testing for those names in your data.

Lastly, the link to faker that you provided looks like it goes to the author's blog, but you can find comprehensive documentation for that repository over at readthedocs.

like image 85
Stephen Ross Avatar answered Nov 29 '25 23:11

Stephen Ross



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!