Django 如何测试清洁<;fieldname>;方法?

Django 如何测试清洁<;fieldname>;方法?,django,django-forms,django-testing,Django,Django Forms,Django Testing,我试图为我的clean_uu方法编写一个测试 这是我的测试代码 def test_clean_restraints(self): form = NewTaskForm(dict(restraints="90 20 <>")) form.clean_restraints() NewTaskForm如下所示: class NewTaskForm(ModelForm): class Meta: model = Task restraint

我试图为我的clean_uu方法编写一个测试

这是我的测试代码

def test_clean_restraints(self):
    form = NewTaskForm(dict(restraints="90 20 <>"))
    form.clean_restraints()
NewTaskForm如下所示:

class NewTaskForm(ModelForm):
    class Meta:
        model = Task

    restraints = forms.CharField()
    region = forms.CharField()
    interactions = forms.CharField()

    def clean_restraints(self):
        if self.cleaned_data.get('restraints') == '':
            return self.cleaned_data.get('restraints')
        data = self.cleaned_data.get('restraints').strip().split('\n')
        regexp = re.compile(r'^(\d+)[\t ]+(\d+)[ \t]+([><]{2})?$')
        cleaned_data = []
        for i, line in enumerate(data):
            match = regexp.match(line)
            if not match:
                raise forms.ValidationError(f"Error in restraints in line {i + 1}")
            else:
                rst_1, rst_2, loop_type = match.groups()
                rst_1 = int(rst_1)
                rst_2 = int(rst_2)
                cleaned_data.append((rst_1, rst_2, loop_type))
        return cleaned_data
def test_clean_restraints(self):
    initial_data = dict(restraints="90 20 <>")
    form = NewTaskForm()
    form.cleaned_data = initial_data
    form.clean_restraints()
    (...)
class NewTaskForm(模型形式):
类元:
模型=任务
约束=forms.CharField()
region=forms.CharField()
交互=forms.CharField()
def清洁_约束装置(自身):
如果自清理数据获取('restrictions')='':
返回自清理的\u数据。获取('约束')
data=self.cleaned_data.get('restrictions').strip().split('\n'))

regexp=re.compile(r'^(\d+[\t]+(\d+[\t]+)([>您应该测试验证过程的结果

form = NewTaskForm(dict(restraints="90 20 <>"))
self.assertFalse(form.is_valid())
self.assertEqual(form.errors['restraints'], "Error in restraints in line 1")
form=NewTaskForm(dict(restrictions=“90 20”))
self.assertFalse(form.is\u valid())
self.assertEqual(表格错误[‘约束’],“第1行约束错误”)

您应该测试验证过程的结果

form = NewTaskForm(dict(restraints="90 20 <>"))
self.assertFalse(form.is_valid())
self.assertEqual(form.errors['restraints'], "Error in restraints in line 1")
form=NewTaskForm(dict(restrictions=“90 20”))
self.assertFalse(form.is\u valid())
self.assertEqual(表格错误[‘约束’],“第1行约束错误”)

好的,我找到了问题所在

form.cleaned_data
是在
full_clean()
中创建的,而不是像我想的那样在构造函数中创建的。它还调用每个
clean_fieldname()
。所以难看的解决方法是这样的:

class NewTaskForm(ModelForm):
    class Meta:
        model = Task

    restraints = forms.CharField()
    region = forms.CharField()
    interactions = forms.CharField()

    def clean_restraints(self):
        if self.cleaned_data.get('restraints') == '':
            return self.cleaned_data.get('restraints')
        data = self.cleaned_data.get('restraints').strip().split('\n')
        regexp = re.compile(r'^(\d+)[\t ]+(\d+)[ \t]+([><]{2})?$')
        cleaned_data = []
        for i, line in enumerate(data):
            match = regexp.match(line)
            if not match:
                raise forms.ValidationError(f"Error in restraints in line {i + 1}")
            else:
                rst_1, rst_2, loop_type = match.groups()
                rst_1 = int(rst_1)
                rst_2 = int(rst_2)
                cleaned_data.append((rst_1, rst_2, loop_type))
        return cleaned_data
def test_clean_restraints(self):
    initial_data = dict(restraints="90 20 <>")
    form = NewTaskForm()
    form.cleaned_data = initial_data
    form.clean_restraints()
    (...)
def测试清洁约束系统(自身):
初始数据=dict(约束=“90 20”)
form=NewTaskForm()
form.cleaned\u数据=初始\u数据
表格.清洁约束装置()
(...)

好的,我找到了问题所在

form.cleaned_data
是在
full_clean()
中创建的,而不是像我想的那样在构造函数中创建的。它还调用每个
clean_fieldname()
。所以难看的解决方法是这样的:

class NewTaskForm(ModelForm):
    class Meta:
        model = Task

    restraints = forms.CharField()
    region = forms.CharField()
    interactions = forms.CharField()

    def clean_restraints(self):
        if self.cleaned_data.get('restraints') == '':
            return self.cleaned_data.get('restraints')
        data = self.cleaned_data.get('restraints').strip().split('\n')
        regexp = re.compile(r'^(\d+)[\t ]+(\d+)[ \t]+([><]{2})?$')
        cleaned_data = []
        for i, line in enumerate(data):
            match = regexp.match(line)
            if not match:
                raise forms.ValidationError(f"Error in restraints in line {i + 1}")
            else:
                rst_1, rst_2, loop_type = match.groups()
                rst_1 = int(rst_1)
                rst_2 = int(rst_2)
                cleaned_data.append((rst_1, rst_2, loop_type))
        return cleaned_data
def test_clean_restraints(self):
    initial_data = dict(restraints="90 20 <>")
    form = NewTaskForm()
    form.cleaned_data = initial_data
    form.clean_restraints()
    (...)
def测试清洁约束系统(自身):
初始数据=dict(约束=“90 20”)
form=NewTaskForm()
form.cleaned\u数据=初始\u数据
表格.清洁约束装置()
(...)

为什么?如果我的验证过程非常复杂怎么办?我不能将其拆分为更小的测试吗?如果您使用所有其他字段有效而只有一个字段无效进行测试,那么您实际上是在测试特定字段的验证。这就是您应该做的。使用一个特定的已知错误创建表单,并测试该错误是否确实发生在g、 这样,您就可以测试完整验证过程的每一部分。为什么?如果我的验证过程非常复杂怎么办?我不能将其拆分为较小的测试吗?如果您使用所有其他字段有效而只有一个字段无效进行测试,那么您实际上是在测试特定字段的验证。这就是您应该做的。使用一个sp创建表单指定已知错误并测试错误是否实际发生。这样,您就可以测试完整验证过程的每一部分。有一个更简单的解决方案:将有效验证写入受保护的
\u clean\u restricts(self,clean\u data)
方法,并从公共
clean\u restricts(self)调用此方法
-通过这种方式,您可以测试
\u clean\u restriction()
,而无需“丑陋的变通方法”。有一个更简单的解决方案:在受保护的
\u clean\u restriction(self,clean\u data)
方法中编写有效验证,并从公共
clean\u restriction(self)
-通过这种方式,您可以测试
\u clean\u restriction()
没有“丑陋的解决方法”。请注意,在PyCharm中调试表单清理方法时,在调用清理方法本身之前,必须小心不要在任何地方设置断点。这是因为调试器本身想要内省表单,并将调用
form.errors
(哪个调用
form.is\u valid()
哪个调用
form.full\u clean()
…)因此,
clean
中的断点不再到达,因为
form.\u错误
已被填充。请注意,在PyCharm中调试表单清理方法时,必须小心不要在调用清理方法本身之前的任何位置设置断点。这是因为调试器本身希望内省form并将调用
form.errors
来执行此操作(调用
form.is\u valid()
调用
form.full\u clean()
…),因此
clean
中的断点不再到达,因为
form.\u errors
已填充。