一个小的python/django模型,用于将用于测试的模型的创建与生产中的模型的创建分离,从而使更新测试变得不那么痛苦。
django-test-model-builder的Python项目详细描述
一个小的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_db
kwarg,可以设置为选择性地持久化
只在更复杂的测试中使用的内存模型。在
执行预处理
默认情况下,此方法将模型更改为它们的_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
- 项目
标签: