Django - 测试功能视图的 URL 时是否需要所有相关模型?
Django - Are all relevent models needed when testing the URL of a functional view?
我有几个传递参数的功能视图。我正在尝试编写测试来检查 url、状态等。到目前为止,我只是从测试 URL 名称开始。我在视图中有一些查询集,从回溯来看,我需要为 setUp
中的查询定义对象
urls
app_name = 'gradebook'
urlpatterns = [
path('updatesinglegrade/<int:assess_pk>/<int:class_pk>/<int:grade_pk>/',
views.updatesinglegrade, name='updatesinglegrade'),
]
查看
def updatesinglegrade(request, assess_pk, class_pk, grade_pk):
grade = Grade.objects.get(id=grade_pk)
gradescale = GradeBookSetup.objects.get(user=request.user)
scale_choice = grade_scale_choice(gradescale.scale_mode)
form = UpdateGradeForm(gradescale=scale_choice)
context = {'form': form}
context['grade'] = grade
if request.method == 'POST':
form = UpdateGradeForm(
request.POST, gradescale=scale_choice)
if form.is_valid():
cd = form.cleaned_data
grade.score = cd['score']
grade.save()
return redirect('gradebook:assessdetail', assess_pk, class_pk)
else:
return render(request, "gradebook/grade_single_form.html", context)
else:
return render(request, "gradebook/grade_single_form.html", context)
测试
class UpdateSingleGradeTests(TestCase):
def setUp(self):
self.user = CustomUser.objects.create_user(
username='tester',
email='tester@email.com',
password='tester123'
)
login = self.client.login(username='tester', password='tester123')
def test_updatesinglegrade_url_name(self):
response = self.client.get(reverse('gradebook:updatesinglegrade', kwargs={
'assess_pk': 1, 'class_pk': 2, 'grade_pk': 3}))
self.assertEqual(response.status_code, 200)
回溯
======================================================================
ERROR: test_updatesinglegrade_url_name (gradebook.tests.UpdateSingleGradeTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\Doug\OneDrive\django\gradebook\gradebook\tests.py", line 102, in test_updatesinglegrade_url_name
response = self.client.get(reverse('gradebook:updatesinglegrade', kwargs={
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\test\client.py", line 742, in get
response = super().get(path, data=data, secure=secure, **extra)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\test\client.py", line 396, in get
return self.generic('GET', path, secure=secure, **{
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\test\client.py", line 473, in generic
return self.request(**r)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\test\client.py", line 719, in request
self.check_exception(response)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\test\client.py", line 580, in check_exception
raise exc_value
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\Doug\OneDrive\django\gradebook\gradebook\views.py", line 1030, in updatesinglegrade
grade = Grade.objects.get(id=grade_pk)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\db\models\query.py", line 435, in get
raise self.model.DoesNotExist(
gradebook.models.Grade.DoesNotExist: Grade matching query does not exist.
----------------------------------------------------------------------
Ran 6 tests in 1.527s
FAILED (errors=1)
我可以创建一个 Grade
对象,如回溯所示,但我的 Grade
模型依赖于五个外键,其中一个有另一个外键:
型号
class Grade(models.Model):
score = models.CharField(max_length=3, blank=True, default="INC")
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
assessment = models.ForeignKey(
Assessment, on_delete=models.CASCADE, null=True, blank=True)
objective = models.ForeignKey(
Objective, on_delete=models.CASCADE, blank=True)
student = models.ForeignKey(Student, on_delete=models.CASCADE)
cblock = models.ForeignKey(Classroom, on_delete=models.CASCADE, default=1)
time_created = models.DateField(
auto_now=False, auto_now_add=False, default=timezone.now)
工作测试
from .models import CustomUser, Grade, Student, Course, Classroom, Objective, Assessment, GradeBookSetup
class UpdateSingleGradeTests(TestCase):
def setUp(self):
self.user = CustomUser.objects.create_user(
username='tester',
email='tester@email.com',
password='tester123',
is_teacher=True,
)
studentuser = CustomUser.objects.create(
username='student_test'
)
stud = Student.objects.create(
user=studentuser,
student_number='111222'
)
course = Course.objects.create(
user=self.user
)
classroom = Classroom.objects.create(
user=self.user,
course=course
)
# classroom.students.set(stud)
objective = Objective.objects.create(
user=self.user,
course=course
)
assessment = Assessment.objects.create(
user=self.user,
course=course
)
# assessment.objectives.set(objective)
login = self.client.login(username='tester', password='tester123')
grade = Grade.objects.create(
id=3,
user=self.user,
student=stud,
objective=objective,
cblock=classroom,
assessment=assessment
)
gbs = GradeBookSetup.objects.create(
id=1,
user=self.user
)
def test_updatesinglegrade_url_name(self):
response = self.client.get(reverse('gradebook:updatesinglegrade', kwargs={
'assess_pk': 1, 'class_pk': 2, 'grade_pk': 3}))
self.assertEqual(response.status_code, 200)
这是否意味着我需要在 setUp
中创建 6 个对象?我得到了这个测试的工作,我想知道这是否是我必须添加到我的许多 class TestCase
(涉及类似 objects/models)的东西?或者也许有更有效的方法来做到这一点?
您可以创建夹具并在您的测试用例中使用它class
关于主题的文档:https://docs.djangoproject.com/en/3.2/topics/testing/tools/#fixture-loading
class UpdateSingleGradeTests(TestCase):
fixtures = ['fixture.json']
简短的回答是,是的,非空 ForeignKey
字段必须在测试中填充,因为它们是非空的。
有几种方法可以做到这一点:
对每个模型调用 objects.create()
。这可能非常乏味且耗时。
使用一个fixture。创建 JSON 文件也很繁琐,但幸运的是,您可以使用 Django admin 进行数据输入,然后 ./manage.py dumpdata
生成 JSON.
使用第 3 方库,例如 factory-boy
或 model-bakery
。这些库可以为除了具有价值之外对测试无关紧要的字段生成随机数据。如果您需要某个测试的特定值,那么您可以提供它。
我有几个传递参数的功能视图。我正在尝试编写测试来检查 url、状态等。到目前为止,我只是从测试 URL 名称开始。我在视图中有一些查询集,从回溯来看,我需要为 setUp
urls
app_name = 'gradebook'
urlpatterns = [
path('updatesinglegrade/<int:assess_pk>/<int:class_pk>/<int:grade_pk>/',
views.updatesinglegrade, name='updatesinglegrade'),
]
查看
def updatesinglegrade(request, assess_pk, class_pk, grade_pk):
grade = Grade.objects.get(id=grade_pk)
gradescale = GradeBookSetup.objects.get(user=request.user)
scale_choice = grade_scale_choice(gradescale.scale_mode)
form = UpdateGradeForm(gradescale=scale_choice)
context = {'form': form}
context['grade'] = grade
if request.method == 'POST':
form = UpdateGradeForm(
request.POST, gradescale=scale_choice)
if form.is_valid():
cd = form.cleaned_data
grade.score = cd['score']
grade.save()
return redirect('gradebook:assessdetail', assess_pk, class_pk)
else:
return render(request, "gradebook/grade_single_form.html", context)
else:
return render(request, "gradebook/grade_single_form.html", context)
测试
class UpdateSingleGradeTests(TestCase):
def setUp(self):
self.user = CustomUser.objects.create_user(
username='tester',
email='tester@email.com',
password='tester123'
)
login = self.client.login(username='tester', password='tester123')
def test_updatesinglegrade_url_name(self):
response = self.client.get(reverse('gradebook:updatesinglegrade', kwargs={
'assess_pk': 1, 'class_pk': 2, 'grade_pk': 3}))
self.assertEqual(response.status_code, 200)
回溯
======================================================================
ERROR: test_updatesinglegrade_url_name (gradebook.tests.UpdateSingleGradeTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\Doug\OneDrive\django\gradebook\gradebook\tests.py", line 102, in test_updatesinglegrade_url_name
response = self.client.get(reverse('gradebook:updatesinglegrade', kwargs={
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\test\client.py", line 742, in get
response = super().get(path, data=data, secure=secure, **extra)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\test\client.py", line 396, in get
return self.generic('GET', path, secure=secure, **{
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\test\client.py", line 473, in generic
return self.request(**r)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\test\client.py", line 719, in request
self.check_exception(response)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\test\client.py", line 580, in check_exception
raise exc_value
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\Doug\OneDrive\django\gradebook\gradebook\views.py", line 1030, in updatesinglegrade
grade = Grade.objects.get(id=grade_pk)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Doug\.virtualenvs\gradebook-6RQSg7dk\lib\site-packages\django\db\models\query.py", line 435, in get
raise self.model.DoesNotExist(
gradebook.models.Grade.DoesNotExist: Grade matching query does not exist.
----------------------------------------------------------------------
Ran 6 tests in 1.527s
FAILED (errors=1)
我可以创建一个 Grade
对象,如回溯所示,但我的 Grade
模型依赖于五个外键,其中一个有另一个外键:
型号
class Grade(models.Model):
score = models.CharField(max_length=3, blank=True, default="INC")
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
assessment = models.ForeignKey(
Assessment, on_delete=models.CASCADE, null=True, blank=True)
objective = models.ForeignKey(
Objective, on_delete=models.CASCADE, blank=True)
student = models.ForeignKey(Student, on_delete=models.CASCADE)
cblock = models.ForeignKey(Classroom, on_delete=models.CASCADE, default=1)
time_created = models.DateField(
auto_now=False, auto_now_add=False, default=timezone.now)
工作测试
from .models import CustomUser, Grade, Student, Course, Classroom, Objective, Assessment, GradeBookSetup
class UpdateSingleGradeTests(TestCase):
def setUp(self):
self.user = CustomUser.objects.create_user(
username='tester',
email='tester@email.com',
password='tester123',
is_teacher=True,
)
studentuser = CustomUser.objects.create(
username='student_test'
)
stud = Student.objects.create(
user=studentuser,
student_number='111222'
)
course = Course.objects.create(
user=self.user
)
classroom = Classroom.objects.create(
user=self.user,
course=course
)
# classroom.students.set(stud)
objective = Objective.objects.create(
user=self.user,
course=course
)
assessment = Assessment.objects.create(
user=self.user,
course=course
)
# assessment.objectives.set(objective)
login = self.client.login(username='tester', password='tester123')
grade = Grade.objects.create(
id=3,
user=self.user,
student=stud,
objective=objective,
cblock=classroom,
assessment=assessment
)
gbs = GradeBookSetup.objects.create(
id=1,
user=self.user
)
def test_updatesinglegrade_url_name(self):
response = self.client.get(reverse('gradebook:updatesinglegrade', kwargs={
'assess_pk': 1, 'class_pk': 2, 'grade_pk': 3}))
self.assertEqual(response.status_code, 200)
这是否意味着我需要在 setUp
中创建 6 个对象?我得到了这个测试的工作,我想知道这是否是我必须添加到我的许多 class TestCase
(涉及类似 objects/models)的东西?或者也许有更有效的方法来做到这一点?
您可以创建夹具并在您的测试用例中使用它class
关于主题的文档:https://docs.djangoproject.com/en/3.2/topics/testing/tools/#fixture-loading
class UpdateSingleGradeTests(TestCase):
fixtures = ['fixture.json']
简短的回答是,是的,非空 ForeignKey
字段必须在测试中填充,因为它们是非空的。
有几种方法可以做到这一点:
对每个模型调用
objects.create()
。这可能非常乏味且耗时。使用一个fixture。创建 JSON 文件也很繁琐,但幸运的是,您可以使用 Django admin 进行数据输入,然后
./manage.py dumpdata
生成 JSON.使用第 3 方库,例如
factory-boy
或model-bakery
。这些库可以为除了具有价值之外对测试无关紧要的字段生成随机数据。如果您需要某个测试的特定值,那么您可以提供它。