一个小的python/django模型,用于将用于测试的模型的创建与生产中的模型的创建分离,从而使更新测试变得不那么痛苦。

django-test-model-builder的Python项目详细描述


https://travis-ci.com/publons/django-test-model-builder.svg?token=WSHb2ssbuqzAyoqCvdCs&branch=master

一个小的python/django模型,用于分离 从在生产中创建模型开始进行测试,以进行更新测试 不那么痛苦。在

快速启动

创建通用模型而不定义字段

classUser(AbstractBaseUser):username=models.CharField()classUserBuilder(ModelBuilder):model=Userdefget_default_fields(self):return{'username':'test_username'}user=UserBuilder().build()print(user.username)>>>test_username

在需要时重写默认值

^{pr2}$

创建具有相同值的多个模型

builder=UserBuilder().with_username('test')user_1=builder.build()user_2=builder.build()user_1.username==user_2.username>>>Trueuser_1==user_2>>>False

在不更新测试的情况下更新模型

classUser(AbstractBaseUser):username=models.CharField()dob=models.DateField()classUserBuilder(ModelBuilder):model=Userdefget_default_fields(self):return{'username':random_string,'dob':date(1990,1,1),}user=UserBuilder().build()user.dob>>>date(1990,1,1)user=(UserBuilder().with_dob(date(2000,1,1)).build())user.dob>>>date(2000,1,1)

设置默认值

get_default_fields返回用于填充任何未设置的字典 创建模型时的模型字段。如果您 需要延迟模型的创建,直到需要或想要生成 每个实例的随机数据,以避免破坏数据库约束。在

classUserBuilder(ModelBuilder):model=Userdefget_default_fields():return{# Callable, each user will have a random username.'username':random_string,# Value, each user will have the same date of birth.'dob':date(1990,1,1),# Called with uninitiated build() call so duplicate model isn't# generated until comparison with any custom `with_` setter# functions, this field will be thrown away# if custom setter is present. You can also use a# lambda to achieve the same thing.'user':UserBuilder().build}

提供使用“with”前缀的自定义值

with_函数是动态生成的,这些函数用于重写 默认值。在

classUserBuilder(ModelBuilder):model=Userdefget_default_fields():return{'username':random_string,'dob':date(1990,1,1),}user=UserBuilder().with_dob(date(2019,10,10)).build()user.dob>>>date(2019,10,10)

所有这些函数所做的就是将传入的值设置为 内部字典。此模式可用于创建更具可读性的测试。在

任何前缀为with_的函数都会自动用函数包装起来 它返回一个生成器的副本,用于无副作用链接。在

您还可以在ModelBuilder子类上显式定义这些with_<> 添加您自己的实现。在

fromdatetimeimporttimedeltaclassUserBuilder(ModelBuilder):model=Userdefget_default_fields():return{'username':random_string,'dob':date(1990,1,1)}defwith_under_18():self.data['dob']=date.today()-timedelta(years=17)UserBuilder().under_18().build()

最后,with_前缀是可调的,以防有一个阻塞字段 你想要用。例如,您可以通过

classCustomAuthorBuilder(AuthorBuilder):dynamic_field_setter_prefix='set_'author=(CustomAuthorBuilder().set_publishing_name('Billy Fakeington').build())author.publishing_name>>>'Billy Fakeington'

Calling.build()

建立模型分为四个步骤。在

  • 准备数据字典。在
  • 执行预处理。在
  • 创建实例。在
  • 执行职务占有。在

还有一个save_to_dbkwarg,可以设置为选择性地持久化 只在更复杂的测试中使用的内存模型。在

执行预处理

默认情况下,此方法将模型更改为它们的_id后缀。这可能是 扩展以执行字段的附加预处理。在

fromdatetimeimporttimedeltaclassUserBuilder(ModelBuilder):model=Userdefget_default_fields():return{'username':random_string,'dob':date(1990,1,1),}defpre(self):self['dob']+=timedelta(days=1)UserBuilder().build().dob# date(1990, 1, 2)

如果要添加非字段值以通过前/后钩子进行登录 您可以重写get_builder_context调用来加载任何额外的字段 将提供给自我数据初始模型后的dict 字段已设置,例如:

classAuthorBuilder(ModelBuilder):defget_default_fields():return{'username':random_string,'dob':date(1990,1,1)}defget_builder_context(self):return{'email_address':fake_email}defpost(self):print(self.dict)AuthorBuilder().build()>>>{>>>'username':random_string,>>>'dob':date(1990,1,1),>>>'email_address':fake_email>>>}

创建实例

默认情况下,通过调用model.objects.create创建实例 数据来自字典的字段。这种行为是可以改变的 通过重写builders.create方法,此方法必须设置生成器 实例属性`自我实例= …`. 在

classUserBuilder(ModelBuilder):model=Userdefget_default_fields():return{'username':random_string,}defcreate(self):model=self.get_model()try:instance=self.model.objects.get(username=self.data['username'])exceptmodel.objects.DoesNotExist:super(UserBuilder,self).create()builder=UserBuilder().with_username('test')user_1=builder.build()user_2=builder.build()user_1==user_2>>>True

Preform后处理

后处理在实例创建后执行。默认情况下 它什么也不做,但提供了一个有用的地方来执行诸如add related之类的操作 模型。在

classUserBuilder(ModelBuilder):model=Userdefget_default_fields():return{'username':random_string,}defwith_emails(*args):self.data['emails']=argsdefpost(self):foremailinself.data.get('emails',[]):(EmailBuilder().with_address(email).with_user(self.instance).build())user=(UserBuilder().with_emails(random_email(),random_email()).build())user.email_set.count()>>>2

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java从JSP或HTML向servlet发送多个参数   java方法来查看字符是否在字符数组中   使用带有java的MAC地址连接到设备   java如何将csv文件中的数据打印到secondactivity?   java如何从netbean 7.0.1连接到数据库   java考虑所有可能的类值,用于输出测试分割的预测值。   java我的actionListener调用有什么问题   swing在Java中实现粒子过滤器最有效的方法是什么?   java运行。getFontFamily()为返回null。使用apachepoi的docx文件   一个事务中的java领域循环与每个步骤循环中的一个事务   java日期格式与Spring Boot不兼容   java类冲突。处理   java GridBagLayout不工作   java将图像发送到另一个应用程序