簡體   English   中英

Django 測試客戶端不處理異常?

[英]Django test client does not handle exceptions?

我需要使用 django 測試虛擬客戶端為 Django 中的自定義 handler404 和 handler500 編寫一些測試。 第一個很容易測試,而我對第二個有問題。

基本上,問題在於 Django 測試客戶端沒有捕獲異常並且沒有路由到正確的處理程序。 這是一個問題,因為我們需要測試是否使用了正確的自定義處理程序和模板。

我們有一個簡單的中間件類來模擬測試異常:

  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 3.0 支持了

新的測試Client參數raise_request_exception允許控制在請求期間引發的異常是否也應在測試中引發。 為了向后兼容,該值默認為True 如果它是False並且發生異常,則測試客戶端將返回一個帶有屬性exc_info的 500 響應,這是一個提供發生異常信息的元組。

c = Client(raise_request_exception=False)

有關文檔中的信息

對於 Django 2.x,可以通過修補其store_exc_info方法來阻止測試客戶端引發異常:

c = Client()                                                             
c.store_exc_info = lambda *args, **kw: None
response = c.get("/error")
assert response.status_code == 500

假設處理/error url 的視圖引發異常,這將允許我們獲得500 Server Error響應。

對於 Django>=3.0,應該使用raise_request_exception參數(如@CesarCanassa 回答中所述)

所以 django test Client 類在設計上不會捕獲異常,這是一件好事。

由於問題具體是測試自定義 handler500,它是由自定義中間件在特定設置上設置的,只需將 request.urlconf 變量替換為自定義 urlconf 模塊,解決方案是使用 RequestFactory 構建請求,並測試 request.urlconf.handler500看法:

在 custom/client1/urls.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)

在測試/視圖/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!')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM