Проблема с повторяющимися значениями, генерируемыми при использовании factory_boy и randint

#python-2.7 #faker #django-1.11 #factory-boy

#python-2.7 #подделыватель #django-1.11 #factory-boy

Вопрос:

Я вижу повторяющиеся значения, генерируемые при использовании randint и factory_boy. Мой тест завершается неудачей при проверке ресурса для каждого объекта. Штрих-код также одинаков между ними при вызове create() на заводе.

Нужно ли мне предоставлять разные начальные данные перед созданием каждого объекта?

Упаковка

  • factory-boy 2.11.1
  • Faker 1.0.4
  • python 2.7
  • django 1.11

Файлы

seed/factories.py

 import factory
from A1.models import *
from random import randint, random
faker = Factory.create()

class AssetFactory(factory.DjangoModelFactory):

    class Meta:
        model = Asset

asset = "ABC"   str(randint(0000, 9999))
barcode = "AA"   randint(111111, 999999)
user = factory.lazy_attribute(lambda x: faker.name())
  

tests.py

 def test_randomCreation(self):
    new_asset = AssetFactory.create()
    new_asset2 = AssetFactory.create()
    self.assertNotEqual(new_asset.asset, new_asset2.asset)  #FAILS
  

A1/models.py

 class Asset(models.Model):
    asset =  models.CharField(max_length=255, verbose_name="Asset")
    barcode = models.CharField(max_length=255)
    user = models.CharField(max_length=255)
  

Может кто-нибудь указать мне правильное направление?
Заранее спасибо!!

Ответ №1:

Из-за того, как разработан язык Python, ваш код не может работать.

Это строго эквивалентно следующему:

 _RANDOM_ASSET = "ABC"   str(randint(0000, 9999))
_RANDOM_BARCODE = "AA"   str(randint(111111, 999999))

class AssetFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Asset
    asset = _RANDOM_ASSET
    barcode = _RANDOM_BARCODE
    user = factory.LazyAttribute(lambda x: faker.name())
  

Вы исправили случайное значение для asset и barcode , поэтому каждый объект, сгенерированный с помощью этой фабрики, будет иметь точно такое же значение.

Правильным способом было бы использовать различные встроенные объявления:

 class AssetFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.Asset

    asset = factory.fuzzy.FuzzyText(length=4, prefix='ABC', chars=string.digits)
    barcode = factory.fuzzy.FuzzyText(length=6, prefix='AA', chars=string.digits)
    user = factory.Faker('name')
  

Комментарии:

1. Спасибо! Я также попробовал следующее, и это сработало: штрих-код = фабрика. Атрибут LazyAttribute(лямбда x: «ABC» str(randint(111111, 999999)) Однако я не уверен, следует ли мне использовать его таким образом. Есть ли польза в любом случае? Примечание от factoryboy.readthedocs.io/en/latest/… «LazyAttribute вызывает функцию с создаваемым объектом в качестве аргумента»

2. @AeroChocolate основное преимущество прохождения FuzzyText заключается в том, что в нем используется «управляемое» случайное начальное значение; это важно, если вы хотите иметь возможность воспроизводить тесты на основе случайных данных. Смотрите factoryboy.readthedocs.io/en/latest /… подробнее.