我创建了工厂类“ShopModelFactory”vie factory-boy包,它应该返回django模型“Shop”,另外模型的字段通过faker感觉起来,比我通过pytest编写测试,但是 在 django 项目中运行 pytest 后出现此错误 ->
django.db.utils.IntegrityError: duplicate key value violates unique constraint "shops_shop_pkey"
DETAIL: Key (id)=(cd84e095-7d1a-41fc-adb3-7f5db5e07d50) already exists.
========================================================================== short test summary info ===========================================================================
FAILED tests/models/test_shop.py::test_shop_creation - django.db.utils.IntegrityError: duplicate key value violates unique constraint "shops_shop_pkey"
但是我的数据库是空的,另外我要删除之前的所有记录
我的模型
class Shop(TimedBaseModel):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
first_name = models.CharField("First Name", max_length=20)
last_name = models.CharField("Last Name", max_length=20)
email = models.EmailField("Email", unique=True)
phone = PhoneNumberField(
"Phone Number",
unique=True,
)
shop_name = models.CharField("Shop Name", max_length=50, unique=True)
shop_url = models.URLField("Shop URL", unique=True)
logo = models.ImageField("Logo", upload_to="logos/", blank=True, null=True)
banner = models.ImageField(
"Banner",
upload_to="banners/",
blank=True,
null=True,
)
street1 = models.CharField("Street 1", max_length=50)
street2 = models.CharField("Street 2", max_length=50, blank=True)
city = models.CharField("Town / City", max_length=100)
zip_code = models.CharField("Zip Code", max_length=10)
country = CountryField("Country", blank_label="(select country)")
state = models.CharField("State", max_length=100, blank=True, default="")
password = models.CharField("Password")
confirm_password = models.CharField("Confirm Password")
is_visible = models.BooleanField(
verbose_name="Is the shop visible in the shops catalog",
default=True,
)
class Meta:
verbose_name = "Խանութ"
verbose_name_plural = "Խանութներ"
app_label = "shops"
def __str__(self):
return self.shop_name
def save(self, *args, **kwargs):
instance = super().save(*args, **kwargs)
if self.logo:
instance = super().save(*args, **kwargs)
logo_path = self.logo.path
logo = Image.open(logo_path)
logo_size = os.path.getsize(logo_path) # in bytes
thirty_mb = 30 * 1024 * 1024
while logo_size > thirty_mb:
logo = logo.convert("RGB")
logo.save(
logo_path,
quality=60,
optimize=True,
format="JPEG",
)
return instance
我的工厂
import factory
from factory.django import DjangoModelFactory, ImageField
from api.v1.apps.shops.models.shops import Shop
class ShopModelFactory(DjangoModelFactory):
class Meta:
model = Shop
first_name = factory.Faker('first_name')
last_name = factory.Faker('last_name')
email = factory.Faker('email')
phone = factory.Faker('phone_number')
shop_name = factory.Faker('company')
shop_url = factory.Faker('url')
logo = ImageField(color='blue')
banner = ImageField(color='red')
street1 = factory.Faker('street_address')
street2 = factory.Faker('secondary_address')
city = factory.Faker('city')
zip_code = factory.Faker('postcode')
country = factory.Faker('country_code')
state = factory.Faker('state')
password = factory.Faker('password')
confirm_password = password
is_visible = factory.Faker('boolean')
我的测试
@pytest.mark.django_db(transaction=True)
def test_shop_creation():
Shop.objects.all().delete() # even before model creation I'm deleting all records from database
shop = ShopModelFactory()
assert Shop.objects.count() == 1
assert Shop.objects.first() == shop
assert shop.first_name
assert shop.last_name
assert shop.email
assert shop.phone
assert shop.shop_name
assert shop.shop_url
assert shop.street1
assert shop.city
assert shop.zip_code
assert shop.country
assert shop.state
assert shop.password
assert shop.confirm_password
assert isinstance(shop.is_visible, bool)
再次请注意,在我的测试函数中,我还在使用 ShopModelFactory 创建新模型之前从数据库中删除了所有记录。此外,我可以说我可以在管理面板中无缝创建记录
删除
@pytest.mark.django_db(transaction=True)
不要使用
transaction=True
,因为你不需要它,它会导致不需要的行为,因此删除操作和创建将在最后作为一个事务发生,这不是你想要测试的东西