How to follow Django redirect using django-pytest?

早过忘川 提交于 2019-12-10 21:23:16

问题


In setting up a ArchiveIndexView in Django I am able to successfully display a list of items in a model by navigating to the page myself.

When going to write the test in pytest to verify navigating to the page "checklist_GTD/archive/" succeeds, the test fails with the message:

>       assert response.status_code == 200
E       assert 301 == 200
E        +  where 301 = <HttpResponsePermanentRedirect status_code=301, "text/html; charset=utf-8", url="/checklist_GTD/archive/">.status_code

test_archive.py:4: AssertionError

I understand there is a way to follow the request to get the final status_code. Can someone help me with how this done in pytest-django, similar to this question? The documentation on pytest-django does not have anything on redirects. Thanks.


回答1:


pytest-django provides both an unauthenticated client and a logged-in admin_client as fixtures. Really simplifies this sort of thing. Assuming for the moment that you're using admin_client because you just want to test the redirect as easily as possible, without having to log in manually:

def test_something(admin_client):
    response = admin_client.get(url, follow=True)
    assert response.status_code == 200

If you want to log in a standard user:

def test_something(client):
    # Create user here, then:
    client.login(username="foo", password="bar")
    response = client.get(url, follow=True)
    assert response.status_code == 200

By using follow=True in either of these, the response.status_code will equal the return code of the page after the redirect, rather than the access to the original URL. Therefore, it should resolve to 200, not 301.

I think it's not documented in pytest-django because the option is inherited from the Django test client it subclasses from (making requests).




回答2:


UPDATE: I'm getting downvoted into oblivion but I still think my answer is better so let me explain.

I still think there is a problem with Shacker's answer, where you can set follow=True and get a response code of 200 but not at the URL you expect. For example, you could get redirected unexpectedly to the login page, follow and get a response code of 200.

I understand that I asked a question on how to accomplish something with pytest and the reason I'm getting downvoted is because I provided an answer using Django's built-in TestCase class. However, the correct answer for the test is/was more important to me at the time than exclusively using pytest. As noted below, my answer still works with pytest's test discovery so I think the answer is still valid. After all, pytest is built upon Django's built-in TestCase. And my answer asserts the response code of 200 came from where I expected it to come from.

The best solution would be to modify pytest to include the expected_url as a parameter. If anyone is up for doing this I think it would be a big improvement. Thanks for reading.

ORIGINAL CONTENT:

Answering my own question here. I decided to include final expected URL using the built-in Django testing framework's assertRedirects and verify that it (1) gets redirected initially with 302 response and (2) eventually succeeds with a code 200 at the expected URL.

from django.test import TestCase, Client

def test_pytest_works():
    assert 1==1

class Test(TestCase):
    def test_redirect(self):
        client = Client()
        response = client.get("/checklist_GTD/archive/")
        self.assertRedirects(response, "/expected_redirect/url", 302, 200)

Hat tip to @tdsymonds for pointing me in the right direction. I appreciated Shacker's answer but I have seen in some scenarios the redirect result being 200 when the page is redirected to an undesirable URL. With the solution above I am able to enforce the redirect URL, which pytest-django does not currently support.

Please note: This answer is compliant with the auto-discover feature of pytest-django and is thus not incompatible (it will auto-discover both pytest-django and Django TestCase tests).



来源:https://stackoverflow.com/questions/48166839/how-to-follow-django-redirect-using-django-pytest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!