如何为自定义 Django 通用视图编写测试?
How to write tests for custom Django generic view?
我不明白我们应该如何为 Django 视图编写测试。因为,我的情况感觉和别人不一样。
我有一个视图,比方说 MyView,它继承自 Django 通用 class 基于视图的 CreateView。但是,在后台,我的意思是在 form_valid 函数中,这个视图尝试使用 Python 库连接到远程服务器,然后根据用户的输入获取数据,然后处理其他细节和如果一切正常,则保存对象,否则,它会 returns 自定义错误。
我应该如何处理这种视图以便编写测试?
(我可以使用类似的东西,但处理可能的错误并不好:
from django.test import Client
c = Client()
c.login(mydetails..)
y = c.post('/url/', {'my': 'data'})
有效,是的,但在这种情况下我只检查状态代码。 y.status_code
帮不上忙,因为Django returns 200 即使表单有错误。
为了简化 django 中的测试框架,测试将模拟客户端请求(就像用户单击 link "url")此 url 与将处理的视图相关联请求和 return 对用户的响应。例如,在您的测试中,您将断言视图是否呈现正确的响应和模板。假设我们有一个创建博客的视图,如何测试?请参阅下面的代码。
views.py
def createblog_view(request):
if request.method == 'POST':
form = BlogForm(request.POST)
if form.is_valid():
blog = form.save(commit=False)
blog.author = request.user # save the user who created the blog
blog.save()
return redirect(blog.get_absolute_url())
else:
form = BlogForm()
context = {'form': form}
return render(request, 'blog/createblog.html', context)
test.py
class BlogTest(TestCase):
def setUp(self):
# this user will be used to create the blog
self.user = User.objects.create_superuser(
'foo',
'foo@test.com',
'password'
)
def test_create_blog(self): # create update and delete a blog
# log user in and user
self.client.login(username='foo', password='password')
# create new blog
# expected date from the user, you can put invalid data to test from validation
form_data = {
'title': 'new test blog',
'body': 'blog body'
}
form = BlogForm(data=blogform_data) # create form indstance
"""
simulate post request with self.client.post
/blog/createblog/ is the url associated with create_blog view
"""
response = self.client.post('/blog/createblog/', form_data)
# get number of created blog to be tested later
num_of_blogs = Blog.objects.all().count()
# get created blog
blog = Blog.objects.get(title=form_data['title'])
# test form validation
self.assertTrue(blogform.is_valid())
# test slugify method, if any
self.assertEqual(blog.slug, 'new-test-blog')
# test if the blog auther is the same logged in user
self.assertEqual(blog.author, self.user1)
# one blog created, test if this is true
self.assertEqual(num_of_blogs, 1)
# test redirection after blog created
self.assertRedirects(
createblog_response,
'/blog/new-test-blog/',
status_code=302,
target_status_code=200
)
我不明白我们应该如何为 Django 视图编写测试。因为,我的情况感觉和别人不一样。
我有一个视图,比方说 MyView,它继承自 Django 通用 class 基于视图的 CreateView。但是,在后台,我的意思是在 form_valid 函数中,这个视图尝试使用 Python 库连接到远程服务器,然后根据用户的输入获取数据,然后处理其他细节和如果一切正常,则保存对象,否则,它会 returns 自定义错误。
我应该如何处理这种视图以便编写测试?
(我可以使用类似的东西,但处理可能的错误并不好:
from django.test import Client
c = Client()
c.login(mydetails..)
y = c.post('/url/', {'my': 'data'})
有效,是的,但在这种情况下我只检查状态代码。 y.status_code
帮不上忙,因为Django returns 200 即使表单有错误。
为了简化 django 中的测试框架,测试将模拟客户端请求(就像用户单击 link "url")此 url 与将处理的视图相关联请求和 return 对用户的响应。例如,在您的测试中,您将断言视图是否呈现正确的响应和模板。假设我们有一个创建博客的视图,如何测试?请参阅下面的代码。
views.py
def createblog_view(request):
if request.method == 'POST':
form = BlogForm(request.POST)
if form.is_valid():
blog = form.save(commit=False)
blog.author = request.user # save the user who created the blog
blog.save()
return redirect(blog.get_absolute_url())
else:
form = BlogForm()
context = {'form': form}
return render(request, 'blog/createblog.html', context)
test.py
class BlogTest(TestCase):
def setUp(self):
# this user will be used to create the blog
self.user = User.objects.create_superuser(
'foo',
'foo@test.com',
'password'
)
def test_create_blog(self): # create update and delete a blog
# log user in and user
self.client.login(username='foo', password='password')
# create new blog
# expected date from the user, you can put invalid data to test from validation
form_data = {
'title': 'new test blog',
'body': 'blog body'
}
form = BlogForm(data=blogform_data) # create form indstance
"""
simulate post request with self.client.post
/blog/createblog/ is the url associated with create_blog view
"""
response = self.client.post('/blog/createblog/', form_data)
# get number of created blog to be tested later
num_of_blogs = Blog.objects.all().count()
# get created blog
blog = Blog.objects.get(title=form_data['title'])
# test form validation
self.assertTrue(blogform.is_valid())
# test slugify method, if any
self.assertEqual(blog.slug, 'new-test-blog')
# test if the blog auther is the same logged in user
self.assertEqual(blog.author, self.user1)
# one blog created, test if this is true
self.assertEqual(num_of_blogs, 1)
# test redirection after blog created
self.assertRedirects(
createblog_response,
'/blog/new-test-blog/',
status_code=302,
target_status_code=200
)