Python Django测试客户端不处理异常?
我需要使用Django测试虚拟客户端在Django中为定制handler404和handler500编写一些测试。 第一个很容易测试,而第二个我有问题 基本上,问题是Django测试客户端并没有捕获异常,也并没有路由到正确的处理程序。这是一个问题,因为我们需要测试是否使用了正确的自定义处理程序和模板 我们有一个简单的中间件类来模拟测试异常:Python Django测试客户端不处理异常?,python,django,django-testing,Python,Django,Django Testing,我需要使用Django测试虚拟客户端在Django中为定制handler404和handler500编写一些测试。 第一个很容易测试,而第二个我有问题 基本上,问题是Django测试客户端并没有捕获异常,也并没有路由到正确的处理程序。这是一个问题,因为我们需要测试是否使用了正确的自定义处理程序和模板 我们有一个简单的中间件类来模拟测试异常: class HTTPStatusCodeMiddleware(object): def process_view(self, request,
class HTTPStatusCodeMiddleware(object):
def process_view(self, request, *args):
if 'cookie_500_error' in request.COOKIES:
raise Exception('Test exception')
上述代码对于在浏览器中进行手动测试非常有效
现在,测试是:
def test_404_template(self):
c = Client()
url = '/not_existing.html'
response = c.get(url)
self.assertEqual(response.status_code, 404) # success
self.assertTemplateUsed(response, 'custom/404.html') # success
def test_500_template(self):
c = Client()
c.cookies['cookie_500_error'] = '1'
response = c.get('/') # here middleware raises exception!!!
self.assertEqual(response.status_code, 500)
self.assertTemplateUsed(response, 'custom/500.html')
有什么想法吗?
我没有选择使用硒。
谢谢 Django测试客户端只处理一些异常(请参阅)。所有其他的都在测试中可见,您可以对它们进行测试;) 所以django测试客户端类不会通过设计捕获异常,这是一件好事 由于具体的问题是测试定制handler500,这是由定制中间件在特定设置上设置的,只需将request.urlconf变量替换为定制urlconf模块,因此解决方案是使用RequestFactory构建请求,并测试request.urlconf.handler500视图: 在custom/client1/url.py中
def handler500(request):
data = {'client', 'client1 is sorry!'}
ctx = RequestContext(request)
content = render_to_string('client1/500.html', data, ctx)
return http.HttpResponseServerError(content)
在tests/views/test_error_pages.py中
def test_500_template(self):
req = RequestFactory().get('/')
req.user = AnonymousUser()
req.session = {}
cust_mw = CustomUrlconfMiddleware()
cust_mw.process_request(req) # set the custom request.urlconf
urlconf = importlib.import_module(req.urlconf)
response = urlconf.handler500(req)
self.assertEqual(response.status_code, 500)
assert_str = '/static/img/custom/client1/'
self.assertTrue(assert_str in response.content,
msg='500 template is not for client1. String {} is not in content'.format(assert_str))
好的,我在单元测试中使用
PermissionDenied
异常时遇到了类似的问题。由于Django没有捕捉到它们,这导致我的测试崩溃而不是失败。我确实想出了一个我还没有看到的简单解决方案,它是这样的:
示例视图:
from django.core.exceptions import PermissionDenied
class SampleView(object):
def setup(request):
if not request_is_authenticated(request):
raise PermissionDenied
from django.core.exceptions import PermissionDenied
def test_permission(self):
try:
SampleView.setup(request)
except PermissionDenied:
print('Hallelujah no crashing!')
单元测试:
from django.core.exceptions import PermissionDenied
class SampleView(object):
def setup(request):
if not request_is_authenticated(request):
raise PermissionDenied
from django.core.exceptions import PermissionDenied
def test_permission(self):
try:
SampleView.setup(request)
except PermissionDenied:
print('Hallelujah no crashing!')
Django3.0现在支持这一点
新的testClient
参数raise\u request\u exception
允许控制在请求期间引发的异常是否也应在测试中引发。该值默认为True
,以实现向后兼容性。如果为False
且发生异常,测试客户端将返回一个500响应,该响应具有属性exc_info
,该元组提供发生异常的信息
c=Client(提出请求\u异常=False)
有关Django 2.x的信息,可以通过修补其
store\u exc\u info
方法停止测试客户端引发异常:
c=Client()
c、 store_exc_info=lambda*args,**千瓦:无
response=c.get(“/error”)
assert response.status_code==500
假设处理/error
url的视图引发异常,这将允许我们获得500服务器错误
响应
对于Django>=3.0,应使用
raise\u request\u exception
参数(如@cesarcanasa answer中所述)。您将需要创建一个引发SystemExit()以获得500的虚拟接口。测试客户机显示的行为是经过设计的,以便验证在无效/错误输入上是否引发了正确的异常。谢谢您的回答。无论如何,我想添加的测试实际上应该检查是否正在使用right handler500视图(取决于当前设置)。如何断言这一点?然后使用激发真实web服务器实例(如开发服务器)的LiveServerTestCase,并执行真实的http请求(self.live_server_url+reverse('viewname'))。但是您将得到一个呈现的页面,而不是HttpResponse实例,因此您需要使用一些库对其进行解析以测试响应内容。问题是,我在setUpClass中执行的某些服务器配置不可见,因为我应该重新启动WSGI服务器。有什么把戏吗?