propagate assertion errors from custom handlers
thrau opened this issue · 2 comments
I would like to perform fuzzy assertions on the request body. Since that doesn't seem possible with the default RequestHandler
, I added my own handler that does the assertions, and would like that assertion errors produced in these handlers are propagated to the pytest run via httpserver.check_assertions()
.
What I've currently done is:
my test:
def assert_appender(httpserver, handler):
def _handler(response):
try:
return handler(response)
except AssertionError as e:
httpserver.add_assertion(e)
raise
return _handler
def test_append(httpserver: HTTPServer):
def handler(request):
actual_data = request.data.decode()
assert 'hello' in actual_data
# ... more asserts
return Response('', 200)
httpserver.expect_request("/path").respond_with_handler(assert_appender(httpserver, handler))
httpserver.check_assertions() # should re-raise the assertion error from "handler"
assert response.ok
and i've modified this bit here:
pytest-httpserver/pytest_httpserver/httpserver.py
Lines 900 to 912 in d98a6c4
to do the following:
if self.assertions:
assertion = self.assertions.pop(0)
if isinstance(assertion, AssertionError):
raise assertion
raise AssertionError(assertion)
now i get the proper assertion formatting in pytest:
def handler(request):
actual_data = request.data.decode()
> assert "hello" in actual_data
E assert 'hello' in '{"foo":"bar"}'
test_http.py:34: AssertionError
would this be interesting to add? i'm happy to contribute a PR
Yes, this sounds to be an excellent idea. It is very cool that pytest is able to format the assertion in that nice format, showing the variables, etc. :)
If you want to volunteer, you are free to proceed with the PR. :)
I have a few thoughts about the implementation:
-
I'm thinking about the effect of adding a catch all exception handler so every exception (including AssertionError of course) would be re-raised in the check_assertions() call. But I'm unsure about how it would break the code of the users. What do you think?
-
The request matcher objects (
RequestMatcher
andRequestHandler
) are not receiving the server object. So basically there are two ways to solve it (in my view):- add the
assert_appender
function definition torespond_with_handler
method, so it will wrap the given callable - add the server object to the
RequestMatcher
object in thecreate_matcher
method. This could be an API breaking point.
- add the
For me the 1st option is better, but if API breaking can be managed (eg. adding a kwarg which is optional) that would be also ok.
FYI: pytest-httpserver 1.0.1 has been released to pypi with your changes. Thanks for your contribution! 👍