Python 使用Django测试客户端测试轮询应用程序
我正在尝试使用Django测试客户端测试民意测验应用程序。在这个测试中,我创建了一个POST请求,模拟投票,然后检查响应的状态代码(以检查我是否已被重定向),并验证投票数是否增加。因此,从我所读到的内容来看,我的Python 使用Django测试客户端测试轮询应用程序,python,django,Python,Django,我正在尝试使用Django测试客户端测试民意测验应用程序。在这个测试中,我创建了一个POST请求,模拟投票,然后检查响应的状态代码(以检查我是否已被重定向),并验证投票数是否增加。因此,从我所读到的内容来看,我的tests.py结果如下: from django.test import Client from django.test import TestCase from mysite.polls.models import Question, Choice class PollTest(T
tests.py
结果如下:
from django.test import Client
from django.test import TestCase
from mysite.polls.models import Question, Choice
class PollTest(TestCase):
def test_voting(self):
client = Client()
# Perform a vote on the poll by mocking a POST request.
response = client.post('/polls/1/vote/', {'choice': '1',})
# In the vote view we redirect the user, so check the
# response status code is 302.
self.assertEqual(response.status_code, 302)
# Get the choice and check there is now one vote.
choice = Choice.objects.get(pk=1)
self.assertEqual(choice.votes, 1)
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,)))
from django.conf.urls import url
from . import views
app_name = 'polls'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]
views.py的投票部分如下所示:
from django.test import Client
from django.test import TestCase
from mysite.polls.models import Question, Choice
class PollTest(TestCase):
def test_voting(self):
client = Client()
# Perform a vote on the poll by mocking a POST request.
response = client.post('/polls/1/vote/', {'choice': '1',})
# In the vote view we redirect the user, so check the
# response status code is 302.
self.assertEqual(response.status_code, 302)
# Get the choice and check there is now one vote.
choice = Choice.objects.get(pk=1)
self.assertEqual(choice.votes, 1)
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,)))
from django.conf.urls import url
from . import views
app_name = 'polls'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]
我的url.py
如下所示:
from django.test import Client
from django.test import TestCase
from mysite.polls.models import Question, Choice
class PollTest(TestCase):
def test_voting(self):
client = Client()
# Perform a vote on the poll by mocking a POST request.
response = client.post('/polls/1/vote/', {'choice': '1',})
# In the vote view we redirect the user, so check the
# response status code is 302.
self.assertEqual(response.status_code, 302)
# Get the choice and check there is now one vote.
choice = Choice.objects.get(pk=1)
self.assertEqual(choice.votes, 1)
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,)))
from django.conf.urls import url
from . import views
app_name = 'polls'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]
从django.conf.url导入url
从…起导入视图
应用程序名称='polls'
URL模式=[
url(r'^$',views.IndexView.as_view(),name='index'),
url(r'^(?P[0-9]+)/$',views.DetailView.as_view(),name='detail'),
url(r'^(?P[0-9]+)/results/$',views.ResultsView.as_view(),name='results'),
url(r'^(?P[0-9]+)/vote/$',views.vote,name='vote'),
]
运行python manage.py test
后,我遇到的第一个问题是,我必须将响应状态代码更改为405,而它应该是302,因为在选择投票并单击投票按钮后,我会被重定向到/polls/1/results
。此外,投票实际上没有被注册,因为在更改响应状态代码后,为了查看投票是否至少增加了,我得到一个错误,即1是错误的,应该将其更改为0,这意味着投票过程也没有运行。添加以下装饰程序以允许POST:
from django.views.decorators.http import require_http_methods
@require_http_methods(["POST"])
def vote(request, poll_id): # this is your method from above
p = get_object_or_404(Poll, pk=question_id)
try:
...
否则,此视图默认处理GET
方法。同时,您确实希望vote()
仅限于POST
调用,因为它正在修改您的数据
看
在测试中,使用response=client.post(…,follow=True)
跟踪重定向并测试最终结果。您不应该得到405-这意味着“不允许使用方法”。我猜是错误的观点在处理这个请求。请显示您的轮询/url.py
。注意,您不需要client=client()
。当使用DjangoTestCase
时,只需使用self.client
。我用views.py
编辑了我的文章。我猜问题出在URL上,而不是视图上。看起来你是在遵循一个非常旧的教程版本-很长时间以来模型一直是Question
而不是Poll
。在本例中,这可能不是问题所在,但将来可能会遇到其他问题。请确保您使用的是最新的Django发行版(目前为1.10或1.8长期支持),并按照正确的教程进行操作,因为我不知道应该在哪里添加装饰器以及装饰器的真正用途是什么?最好使用@require\u http\u方法([“POST”])
,但这并不能解释当前的问题。不注册POST
肯定是405错误和数据库中缺少条目的原因。