Django 教程 - 测试投票(请求,question_id)
Django Tutorial - Testing vote(request, question_id)
我正在学习 django 教程,我到达了第 5 部分 - 介绍自动化测试。
我想超越并为 views.py 中的投票方法编写测试,但无法实现如何模拟一个选择接受投票的行为。有办法吗?
models.py:
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
views.py
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
我在 tests.py 中尝试了多种方法。这是最新版本 - 我知道 choice_vote 目前不是我想要的,仍然需要过滤:
class QuestionVoteTests(TestCase):
def test_vote(self):
"""
Placeholder for vote method test.
"""
question = create_question(question_text="Question.", days=-5)
self.client.post(
reverse('polls:vote', args=(question.id,))
)
vote(self.client, question.id)
choice_vote = Choice.objects.filter(question_id=question.id).values()
print(choice_vote)
#self.assertEqual(choice_vote, 1)
return 0
我查看了有关如何测试多项选择的答案,但它只让我走到了这一步。
谢谢!
稍后编辑:
我 运行 使用 manage.py 命令进行测试。这是结果:
======================================================================
ERROR: test_vote (polls.tests.QuestionVoteTests)
Placeholder for vote method test.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/gabo/django_projects/mysite/polls/tests.py", line 239, in test_vote
vote(self.client, question.id)
File "/home/gabo/django_projects/mysite/polls/views.py", line 52, in vote
selected_choice = question.choice_set.get(pk=request.POST['choice'])
AttributeError: 'Client' object has no attribute 'POST'
也应该post这部分来自模板 - detail.html
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
<fieldset>
<legend><h1>{{ question.question_text }}</h1></legend>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}"
value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label>
<br>
{% endfor %}
</fieldset>
<input type="submit" value="Vote">
</form>
当我在 tests.py 中注释掉 vote(self.client, question.id) 时,这是响应:
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.................<QuerySet [{'id': 1, 'question_id': 1, 'choice_text': 'choice 1', 'votes': 0}, {'id': 2, 'question_id': 1, 'choice_text': 'choice 2', 'votes': 0}]>
.
----------------------------------------------------------------------
Ran 18 tests in 0.213s
查看上面的测试代码,对于所采用的方法存在一些问题和疑问。将它们与下面的代码一起添加
def test_vote(self):
"""
Placeholder for vote method test.
"""
question = create_question(question_text="Question.", days=-5)
self.client.post(
reverse('polls:vote', args=(question.id,))
)
vote(self.client, question.id) # Why is the vote call made here?
choice_vote = Choice.objects.filter(question_id=question.id).values()
print(choice_vote) # What is the value of choice vote here?
#self.assertEqual(choice_vote, 1)
return 0. # Do not return from test
除此之外,您在 运行 进行单元测试时在日志中看到了什么?您是使用 pytest 运行 测试还是 Django 的 manage.py 测试命令?
我正在学习 django 教程,我到达了第 5 部分 - 介绍自动化测试。 我想超越并为 views.py 中的投票方法编写测试,但无法实现如何模拟一个选择接受投票的行为。有办法吗?
models.py:
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
views.py
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
我在 tests.py 中尝试了多种方法。这是最新版本 - 我知道 choice_vote 目前不是我想要的,仍然需要过滤:
class QuestionVoteTests(TestCase):
def test_vote(self):
"""
Placeholder for vote method test.
"""
question = create_question(question_text="Question.", days=-5)
self.client.post(
reverse('polls:vote', args=(question.id,))
)
vote(self.client, question.id)
choice_vote = Choice.objects.filter(question_id=question.id).values()
print(choice_vote)
#self.assertEqual(choice_vote, 1)
return 0
我查看了有关如何测试多项选择的答案,但它只让我走到了这一步。 谢谢!
稍后编辑: 我 运行 使用 manage.py 命令进行测试。这是结果:
======================================================================
ERROR: test_vote (polls.tests.QuestionVoteTests)
Placeholder for vote method test.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/gabo/django_projects/mysite/polls/tests.py", line 239, in test_vote
vote(self.client, question.id)
File "/home/gabo/django_projects/mysite/polls/views.py", line 52, in vote
selected_choice = question.choice_set.get(pk=request.POST['choice'])
AttributeError: 'Client' object has no attribute 'POST'
也应该post这部分来自模板 - detail.html
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
<fieldset>
<legend><h1>{{ question.question_text }}</h1></legend>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}"
value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label>
<br>
{% endfor %}
</fieldset>
<input type="submit" value="Vote">
</form>
当我在 tests.py 中注释掉 vote(self.client, question.id) 时,这是响应:
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.................<QuerySet [{'id': 1, 'question_id': 1, 'choice_text': 'choice 1', 'votes': 0}, {'id': 2, 'question_id': 1, 'choice_text': 'choice 2', 'votes': 0}]>
.
----------------------------------------------------------------------
Ran 18 tests in 0.213s
查看上面的测试代码,对于所采用的方法存在一些问题和疑问。将它们与下面的代码一起添加
def test_vote(self):
"""
Placeholder for vote method test.
"""
question = create_question(question_text="Question.", days=-5)
self.client.post(
reverse('polls:vote', args=(question.id,))
)
vote(self.client, question.id) # Why is the vote call made here?
choice_vote = Choice.objects.filter(question_id=question.id).values()
print(choice_vote) # What is the value of choice vote here?
#self.assertEqual(choice_vote, 1)
return 0. # Do not return from test
除此之外,您在 运行 进行单元测试时在日志中看到了什么?您是使用 pytest 运行 测试还是 Django 的 manage.py 测试命令?