pytest-dev / pytest-django

A Django plugin for pytest.
https://pytest-django.readthedocs.io/
Other
1.39k stars 342 forks source link

--liveserver-verbose parameter could be useful #1023

Open mpasternak opened 2 years ago

mpasternak commented 2 years ago

In my development this is a recurring pattern: I run Selenium tests just to get a simple "500 Internal server error" page and no output from the standard live_server fixture. This is fine, because this is exactly what Django does officially and what people coming from Django testing framework to pytest-django should expect. Also I don't feel like extending live_server test case as it is already threaded and pretty environment-sensible if you ask me, so I'd rather not touch it as perhaps other people's testing workflows depend on it's documented and undocumented behavior.

But what I would love for those hard-to-debug cases is a verbose live server - a server that dumps a traceback to the standard output of pytest. This is not a complicated thing to do, I already have one but I needed to patch a few things in pytest-django. To get it all clean and done I will need some extra time, but I'm documenting this in hope somebody will pick this up or give some insightful feedback at least.

So basically in live_server_helper.py one needs to add:

class VerboseWSGIRequestHandler(WSGIRequestHandler):
    def handle_uncaught_exception(self, request, resolver, exc_info):
        traceback.print_tb(exc_info[2], file=sys.stderr)
        return super(WSGIHandler, self).handle_uncaught_exception(request, resolver, exc_info)

class VerboseLiveServerThread(LiveServerThread):
    def _create_server(self):
        return ThreadedWSGIServer((self.host, self.port), VerboseWSGIRequestHandler, allow_reuse_address=False)

Then later, in LiveServer.__init__ change self.thread line to:

        self.thread = VerboseLiveServerThread(host, **liveserver_kwargs)

This will make your pytest session dump the output on exit (if -s is given), tracebacks included.

For me this is a big step forward from the default configuration of live_server, which acts just like in Django, which is explicitly silent (https://github.com/django/django/blob/0dd29209091280ccf34e07c9468746c396b7778e/django/test/testcases.py#L1636). For me, having a chance of getting a traceback on stdout is pretty much enough. What I would love in the future, perhaps, is the ability of giving the live_server fixture a proper configuration, for example enabling or disabling some settings or running the live_server from a different settings.py file.

So... if you're a dev and want to drop a comment, please let me know what you think and what would be the easiest way to extend LiveServer. I think I'll go with factory approach, which seems to be common through pytest-django source. After some time I'll submit a PR. Thanks!

mpasternak commented 2 years ago

Wow, I even got a thumbs up. Thanks, @mgax!

Here's the code: https://github.com/pytest-dev/pytest-django/pull/1024

mpasternak commented 1 year ago

Hi, just trying to catch your attention. This is useful.