revsys / django-test-plus

Useful additions to Django's default TestCase

Home Page:https://django-test-plus.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

More intuitive http response assertions

epicserve opened this issue · comments

I've been thinking it would be better to make assert methods for http status codes instead of the current response_XXX pattern.

Rational:

  • The camel case and assert prefix match the Python TestCase pattern.
  • Remembering a name instead of a number is easier.
  • It makes your code more human readable.

For example we could add the following:

class BaseTestCase(object):

    def assertHttpStatus(self, status_code: int, response: object = None):
        response = self._which_response(response)
        self.assertEqual(response.status_code, status_code)

    def assertHttpOk(self, response=None):
        self.assertHttpStatus(200, response)

    def assertHttpRedirects(self, response: object = None, url: str = None):
        self.assertHttpStatus(302, response)
        response = self._which_response(response)
        if url is not None:
            self.assertEqual(response.url, url)

    def asssertHttpForbidden(self, response: object = None):
        self.assertHttpStatus(403, response)

    def asssertHttpNotFound(self, response: object = None):
        self.assertHttpStatus(404, response)

    def asssertHttpBadRequest(self, response: object = None):
        self.assertHttpStatus(403, response)

I like this idea as long as we keep the ones we have for backward compatibility. That way we can have the best of both worlds (I tend to think in the numbers not names, but I'm sure I'm probably in the minority there)

@frankwiles, I think it's cool to keep the old ones around. If the project was new I probably would want to change them to assertHttp200, assertHttp302, etc. for consistency and to match the test case pattern.

At some point it might be worth considering deprecating and then removing old methods as some point.

Just "thinking out loud" :)

Want me to contribute a PR?

Yep that would be great!

@frankwiles,

Added a PR, let me know what you think.

We were talking about this earlier and are struggling with having 2 or 3 names for the same methods. I think filling in any missing status codes is valid, but I'm not sure how to resolve us wanting to keep backward compatibility while trying to keep the API clean.

Moving from response_200 to assertHttpOk is hard for me to wrap my dyslexic brain around. I'm going to have to look it up everything I reach a new status code. The assertHttp200 methods are a bit easier to remember, but I'm also not a fan of camel case just for the sake of unit tests roots originating from Java.

@jefftriplett and @frankwiles,

What about keeping all the existing assert methods and then going forward use a hybrid solution that the Django Rest Framework uses where they have both the error code number and a slug of what the status code is.

The new assert methods would like the following?

def assert_http_200_ok()
def assert_http_403_forbidden()
def assert_http_404_not_found()
def assert_http_500_internal_server_error()

The benefit would be that if you're using an IDE you could find the method by either the number or name. This also has the added benefit of helping those that are new to the status codes of learning the number and what the meaning is behind the number.

@epicserve I like that idea a lot. It fits my brain better, and we still have to have backward compatibility either way. I'll defer to the others to see what they think.

yeah if we can keep response_200 and just add in assert_http_200_ok as an option I'm all for it!

@frankwiles and @jefftriplett,

Do you want me to make a PR based on what has been outlined?

@frankwiles and @jefftriplett,

I went ahead and created a new PR. If it looks good, let me know and I can update the README as well.

@frankwiles,

I created a PR for the readme updates. Once merged, we can close this issue.

@jefftriplett or @frankwiles,

Any change we could get the readme changes merged in and a release made? I have a project I would like to update with the changes made in this issue.

Done! I'm going to add a ticket for myself to re-add in the older response_200 style to the docs as I personally prefer them and while I think many users will like yours better, I don't really intend to deprecate them as much as keep both in parallel.

@frankwiles,

Thank you for merging that in. I sort of wish now that you would have said you didn't want this contribution because I'm not a fan of having two ways to do things. That feels less pythonic and seems to go against, "There should be one-- and preferably only one --obvious way to do it."