Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django测试:请参阅创建错误响应的回溯_Python_Django_Unit Testing_Http Response Codes - Fatal编程技术网

Python Django测试:请参阅创建错误响应的回溯

Python Django测试:请参阅创建错误响应的回溯,python,django,unit-testing,http-response-codes,Python,Django,Unit Testing,Http Response Codes,此模式来自django文档: class SimpleTest(unittest.TestCase): def test_details(self): client = Client() response = client.get('/customer/details/') self.assertEqual(response.status_code, 200) 发件人: 如果测试失败,则错误消息没有多大帮助。例如,如果状态代码为302,则

此模式来自django文档:

class SimpleTest(unittest.TestCase):
    def test_details(self):
        client = Client()
        response = client.get('/customer/details/')
        self.assertEqual(response.status_code, 200)
发件人:

如果测试失败,则错误消息没有多大帮助。例如,如果状态代码为302,则我看到
302!=200

现在的问题是:哪里创建了错误的HTTPResponse

我希望看到解释器的stacktrace,其中创建了错误的HTTPResponse对象

我阅读了文档,但是没有找到匹配的方法

更新

这是一个一般性问题:如果断言失败,如何立即查看所需信息?因为这些断言(
self.assertEqual(response.status\u code,200)
)很常见,所以我不想开始调试

2016年更新

我又有了同样的想法,发现目前的答案不是100%容易。我写了一个新的答案,它有一个简单易用的解决方案(django web客户端的子类):

如果断言在没有调试的情况下失败,我如何看到回溯

如果断言失败,则没有回溯。
client.get()
没有失败,它只是返回了一个与预期不同的响应

您可以使用来逐步完成
client.get()
调用,并查看它返回意外响应的原因

如果断言在没有调试的情况下失败,我如何看到回溯

如果断言失败,则没有回溯。
client.get()
没有失败,它只是返回了一个与预期不同的响应


您可以使用一个来逐步完成
client.get()
调用,并查看它返回意外响应的原因。

我认为可以通过创建一个
TestCase
子类(monkeypatches
django.http.response.HttpResponseBase)来实现
记录堆栈跟踪并将其存储在
Response
对象上,然后编写
AssertResponseCodeQuals(Response,status\u code=200)
方法,在出现故障时打印存储的堆栈跟踪,以显示
响应的创建位置

实际上,我自己也可以使用一个解决方案,并可以考虑实现它

更新: 这里是一个v1实现,它可能需要一些改进(例如只打印堆栈跟踪的相关行)


我认为可以通过创建monkeypatches
django.http.response.HttpResponseBase.\uuu init\uuu()
记录堆栈跟踪并将其存储在
response
对象上,然后编写
AssertResponseCodeQuals(响应,状态\u code=200)来实现
方法,该方法在出现故障时打印存储的堆栈跟踪,以显示
响应的创建位置

实际上,我自己也可以使用一个解决方案,并可以考虑实现它

更新: 这里是一个v1实现,它可能需要一些改进(例如只打印堆栈跟踪的相关行)


也许这对你有用:

class SimpleTest(unittest.TestCase):
    @override_settings(DEBUG=True)
    def test_details(self):
        client = Client()
        response = client.get('/customer/details/')
        self.assertEqual(response.status_code, 200, response.content)
使用
@override\u settings
使
DEBUG=True
具有堆栈跟踪,就像您在
DEBUG
模式下运行实例一样

其次,为了提供响应的内容,您需要
打印它或使用
日志记录
模块记录它,或者将它添加为
断言
方法的消息。如果没有调试器,一旦您
断言
,打印任何有用的东西(通常)就太晚了


您还可以配置
日志记录
,并添加一个处理程序将消息保存在内存中,然后打印所有这些信息;无论是在自定义断言方法中还是在自定义测试运行程序中。

这可能适用于您:

class SimpleTest(unittest.TestCase):
    @override_settings(DEBUG=True)
    def test_details(self):
        client = Client()
        response = client.get('/customer/details/')
        self.assertEqual(response.status_code, 200, response.content)
使用
@override\u settings
使
DEBUG=True
具有堆栈跟踪,就像您在
DEBUG
模式下运行实例一样

其次,为了提供响应的内容,您需要
打印它或使用
日志记录
模块记录它,或者将它添加为
断言
方法的消息。如果没有调试器,一旦您
断言
,打印任何有用的东西(通常)就太晚了


您还可以配置
日志记录
,并添加一个处理程序将消息保存在内存中,然后打印所有这些信息;无论是在自定义断言方法中还是在自定义测试运行程序中。

我受到@Fush提出的解决方案的启发,但我的代码使用的是assertRedirects,这是一种较长的方法,代码太多,无法复制而不会对自己感到不好

我花了一点时间弄清楚如何为每个断言调用super(),并得出了这个结论。我已经包括了两个示例assert方法——它们基本上都是相同的。也许一些聪明的灵魂可以想出一些元类魔法,对所有以“响应”为第一个参数的方法都能做到这一点

from bs4 import BeautifulSoup
from django.test.testcases import TestCase


class ResponseTracebackTestCase(TestCase):

    def _display_response_traceback(self, e, content):
        soup = BeautifulSoup(content)
        assert False, u'\n\nOriginal Traceback:\n\n{}'.format(
            soup.find("textarea", {"id": "traceback_area"}).text
        )

    def assertRedirects(self, response, *args, **kwargs):
        try:
            super(ResponseTracebackTestCase, self).assertRedirects(response, *args, **kwargs)
        except Exception as e:
            self._display_response_traceback(e, response.content)

    def assertContains(self, response, *args, **kwargs):
        try:
            super(ResponseTracebackTestCase, self).assertContains(response, *args, **kwargs)
        except Exception as e:
            self._display_response_traceback(e, response.content)

我受到@Fush提出的解决方案的启发,但我的代码使用了assertRedirects,这是一种较长的方法,代码太多了,无法复制而不会对自己感到不好

我花了一点时间弄清楚如何为每个断言调用super(),并得出了这个结论。我已经包括了两个示例assert方法——它们基本上都是相同的。也许一些聪明的灵魂可以想出一些元类魔法,对所有以“响应”为第一个参数的方法都能做到这一点

from bs4 import BeautifulSoup
from django.test.testcases import TestCase


class ResponseTracebackTestCase(TestCase):

    def _display_response_traceback(self, e, content):
        soup = BeautifulSoup(content)
        assert False, u'\n\nOriginal Traceback:\n\n{}'.format(
            soup.find("textarea", {"id": "traceback_area"}).text
        )

    def assertRedirects(self, response, *args, **kwargs):
        try:
            super(ResponseTracebackTestCase, self).assertRedirects(response, *args, **kwargs)
        except Exception as e:
            self._display_response_traceback(e, response.content)

    def assertContains(self, response, *args, **kwargs):
        try:
            super(ResponseTracebackTestCase, self).assertContains(response, *args, **kwargs)
        except Exception as e:
            self._display_response_traceback(e, response.content)

我对django web客户端进行了子类化,以获得以下结果:

用法 实施 结论 如果创建了状态代码错误的http响应,这将导致一个长异常。如果你不怕长时间的异常,你很快就会发现问题的根源。这就是我想要的,我很高兴

信用
这是基于这个问题的其他答案

我对django web客户端进行了子类化,以获得以下结果:

用法 实施 结论 如果http响应使用错误的sta,则会导致长时间异常
from django.test import Client

class MyClient(Client):
    def generic(self, method, path, data='',
                content_type='application/octet-stream', secure=False,
                assert_status=None,
                **extra):
        if assert_status:
            return self.assert_status(assert_status, super(MyClient, self).generic, method, path, data, content_type, secure, **extra)
        return super(MyClient, self).generic(method, path, data, content_type, secure, **extra)

    @classmethod
    def assert_status(cls, status_code, method_pointer, *args, **kwargs):
        assert hasattr(method_pointer, '__call__'), 'Method pointer needed, looks like the result of a method call: %r' % (method_pointer)

        def new_init(self, *args, **kwargs):
            orig_response_init(self, *args, **kwargs)
            if not status_code == self.status_code:
                raise HTTPResponseStatusCodeAssertionError('should=%s is=%s' % (status_code, self.status_code))
        def reraise_exception(*args, **kwargs):
            raise

        with mock.patch('django.core.handlers.base.BaseHandler.handle_uncaught_exception', reraise_exception):
            with mock.patch.object(HttpResponseBase, '__init__', new_init):
                return method_pointer(*args, **kwargs)