2013
24
Jun

Testing Pyramid Web Apps with pytest

I recently took another look at pytest and liked what I saw. Previously, I had used it to try it out and couldn't see much advantage over nose or the Python standard library unittest module (the Python 2.7+ version, that is). Several features of recent versions of pytest changed my mind, but chief among them is fixtures as function arguments. In fact, I think that and other features make pytest the most Pythonic of current crop of testing frameworks. But that's a subject for another post...

In this post I'm going to focus on how to use pytest to test a Pyramid web app. Let's start with a trival Pyramid view function that simply returns a dict that will be used to render a template:

@view_config(route='hello', renderer='hello.mako')
def my_view(request):
    return {'greeting': 'Hello world!'}

and an equally trivial unit test for that view function:

def test_my_view():
    from views import my_view
    response = my_view(request)
    assert response['greeting'] == 'Hello world!'

As written, that test will error out with a syntax error because 'request' is undefined. We'll deal with that by setting up a pytest fixture to provide us with pyramid.testing.DummyRequest instance:

from pyramid import testing
import pytest

@pytest.fixture
def pyramid_req():
    return testing.DummyRequest()

def test_my_view(pyramid_req):
    from views import my_view
    response = my_view(pyramid_req)
    assert response['greeting'] == 'Hello world!'

Easy! Each test function that uses pyramid_req as an argument gets a fresh pyramid.testing.DummyRequest instance to work with. Note that pytest has its own concept of a "request" to allow test fixtures to interact with the requesting text context and that effectively makes request a reserved argument name, so we distinguish the Pyramid request by calling our test fixture function pyramid_req.

Also note the things that we didn't have to do:

  • Our test function is just that - a plain function, not a method of a class that subclasses unittest.TestCase.
  • There are no setUp or tearDown functions for methods.
  • The test assertion is a simple Python assert statement, not a special method or function call like assertEqual.

If we change our test assertion so that the test will fail:

...
assert response['greeting'] == 'Hello Jupiter!'

and run the test suite, we get

blog comments powered by Disqus