Django SECURE_SSL_REDIRECT破坏使用内置客户端的单元测试 [英] Django SECURE_SSL_REDIRECT breaks unit tests that use the in-built client
问题描述
我正在一个已经有数百个单元测试的项目中,其中许多使用内置的django Client或django rest框架APIClient进行请求和测试响应。
最近已实现了使SSL在本地运行的必要条件,并将 SECURE_SSL_REDIRECT
设置为True(试图使我们的dockerized dev
和 test
环境与 possible 尽可能接近生产
),我来找茬了,发现这么多单元测试失败了,这是由于(API)客户端默认情况下始终要求使用HTTP而不是https。
很多(大多数)请求如下所示:
response = self.client.get(some_url)
我知道我可以使用:
响应= self.client.get(some_url,secure = True)
但这确实意味着改变很多单元测试。使用 follow = True
时也是如此,但具有另一个缺点,即这可能会产生其他一些不良行为。
<我在Django客户端中看不到将安全请求的使用设置为默认行为的方法。我可以创建自己的SecureClient(和SecureAPIClient),但随后必须确保创建新的基本TestCase(可能是多个)来继承,并在所有测试中都对其进行更改-仍然很多工作。 / p>
当然可以猴子修补客户端,但是我不愿意这样做,因为它可能会产生不良后果,以后很难调试。 / p>
TLDR;是否有一种简单的(受理想支持的)方法来通过django测试的客户端发出所有单元测试请求,并默认使用SSL?
-
选项1。在需要时禁用
SECURE_SSL_REDIRECT
:
<$ p来自django.test的$ p>导入override_settings
类FooTest(TestCase):
def setUp(self):
settings_manager = override_settings (SECURE_SSL_REDIRECT = False)
settings_manager.enable()
self.addCleanup(settings_manager.disable)
-
选项2:包装
的
:get
和post
方法APIClientclass ApiTestCase(TestCase):
def setUp(self):
self.client = APIClient()
def get(self,* args,** kwargs):
返回self.client.get(secure = True,* args,* * kwargs)
def post(self,* args,** kwargs):
return self.cl ient.post(secure = True,* args,** kwargs)
-
选项3:只需为测试环境维护一个单独的设置文件,而未设置
SECURE_SSL_REDIRECT
。
我已经尝试了所有三个选项,并建议使用(3)。原因如下:
-
django.test.client
只是一个模仿真正的客户。它可以对您的视图进行单元测试。它不会产生真正的WSGI请求,因此测试环境始终无法与生产环境匹配。 -
SECURE_SSL_REDIRECT
是SecurityMiddleware
设置。 请勿对第三方代码进行单元测试 。 -
确保您的代码始终使用SSL是一个好目标。但是,这是一个集成测试问题。这项工作的正确工具是 Selenium + LiveServerTestCase 。
I am working on a project that already has hundreds of unit tests, many of which use either the built in django Client, or the django rest framework APIClient for making requests and testing responses.
Having recently implemented the necessaries to make SSL work locally, and setting the SECURE_SSL_REDIRECT
to True (trying to make our dockerised dev
and test
environments as close to production
as possible), I have come a cropper to find that so many unit tests fail, due to the (API)Clients requesting, by default, always using http, not https.
Many (most) requests look like this:
response = self.client.get(some_url)
I am aware that I could use:
response = self.client.get(some_url, secure=True)
But this does mean changing a lot of unit tests. The same is true for using follow=True
, but had the added disadvantage that this could produce some other undesired behaviour.
I cannot see a way of setting the use of secure requests as a default behaviour in the Django Client. I could make my own SecureClient (and SecureAPIClient), but I would then have to make sure that I make a new base TestCase (possibly multiple) to inherit from, and change this everywhere for all the tests - still a lot of work.
It is possible of course to monkey patch the Client, but I am reluctant to to do this as, again, it could have undesired effects that are hard to debug later.
TLDR; Is there a simple (ideally supported) way, to make all unit test requests via the django test's Client, to use SSL by default?
Option 1. Disable the
SECURE_SSL_REDIRECT
when needed:from django.test import override_settings class FooTest(TestCase): def setUp(self): settings_manager = override_settings(SECURE_SSL_REDIRECT=False) settings_manager.enable() self.addCleanup(settings_manager.disable)
Option 2: Wrap
get
andpost
methods of theAPIClient
:class ApiTestCase(TestCase): def setUp(self): self.client = APIClient() def get(self, *args, **kwargs): return self.client.get(secure=True, *args, **kwargs) def post(self, *args, **kwargs): return self.client.post(secure=True, *args, **kwargs)
Option 3: just maintain a separate settings file for the test environment with the
SECURE_SSL_REDIRECT
not being set.
I've tried all three options and recommend going with the (3). Here is why:
django.test.client
is just an imitation of a real client. It's there to unit test your views. It doesn't produce real WSGI requests, so test environment won't match production environment anyway.SECURE_SSL_REDIRECT
is aSecurityMiddleware
setting. Don't unit test third-party code.Making sure that your code always uses SSL is a good goal. However, this is an integration testing problem. The right tool for this job is Selenium + LiveServerTestCase.
这篇关于Django SECURE_SSL_REDIRECT破坏使用内置客户端的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!