py.test examples for Grok

In typical Zope/Grok development we have three kinds of tests:

  • unit-tests
  • integration-tests
  • funktional-tests

With the help of py.test we can create and run all of these tests in an easy way for Grok. In this tutorial we will demonstrate the usage of zope.pytest with this three kinds of tests.

Buildout

Let’s start by extending the default buildout.cfg generated by grokproject to use zope.pytest.

To find all relevant packages of pytest we have to add

to the find_links.

Then we can add a new section called pytest. Don’t forget to add it to the global parts too!

Here is the pytest section:

[pytest]
recipe = z3c.recipe.scripts
eggs =
  example
  pytest
arguments = ['src/example'] + sys.argv[1:]

Please notice that example is the name of the package generated by grokproject.

After running bin/buildout we should have a new executable called bin/py.test which can search for tests in the directory src/example.

Unit Tests

To run unit tests with pytest we have to create a file with the prefix test_. So, let’s create a file test_unit.py with the following content:

class TestClass:

    def test_one(self):
        x = "this"
        assert 'h' in x

    def test_two(self):
        x = "servus"
        assert x == "hello"

Now we can run this test with bin/py.test. We should get one failing test:

==================================== FAILURES =====================================
_______________________________ TestClass.test_two ________________________________

self = <pytt.tests.test_unit.TestClass instance at 0x1042d0950>

    def test_two(self):
        x = "servus"
>       assert x == "hello"
E       assert 'servus' == 'hello'
E         - servus
E         + hello

src/pytt/tests/test_unit.py:9: AssertionError
======================= 1 failed, 3 passed in 1.14 seconds ========================

Integration Tests

For integration tests we need a bit more setup. To be more precise we have to load the Zope Component Architecture before respective tests are actually run.

To run the integration test we need a bit of code that registers something in the Zope Component Architecture. Take a look at this example in app.py:

import grok

class Example(grok.Application, grok.Container):
    pass

class Index(grok.View):

    def render(self):
        return "Hello World"

Now we have some code to test.

We have to create another module which contains our test and whose name is prefixed with test_. This time we name it test_integration.py:

import example
import pytest

from zope import component
from example.app import Example
from zope.publisher.browser import TestRequest
from zope.pytest import create_app, configure


def pytest_funcarg__app(request):
    return create_app(request, Example())

def pytest_funcarg__config(request):
    return configure(request, pytt, 'ftesting.zcml')


def test_integration(app, config):
    zope_req = TestRequest()
    view = component.getMultiAdapter(
        (Example(), zope_req), name=u"index")
    assert "Hello World" in view()

The interesting bits are the two pytest_funcarg__ functions:

  • pytest_funcarg__app

    This function creates a test ZODB with our Example application in the ZODB root.

  • pytest_funcarg__config

    This function sets up the Zope Component Registry which groks in this case the contents of our app.py.

Now you can run bin/py.test again and will see that pytest will discover and execute this test_integration module.

Functional Tests

We take again the example in the app.py file for demonstrating the functional tests with zope.pytest in grok. Functional tests showing the perspective of a user. This means we test here with a kind of a browser. We take for this infrae.testbrowser.

We have to include it in our setup.py install_requires.

Again we creat a module called test_functional.py.

import example
import pytest

from example.app import Example
from zope.pytest import create_app, configure

from infrae.testbrowser.browser import Browser

def pytest_funcarg__app(request):
    return create_app(request, Example())

def pytest_funcarg__config(request):
    return configure(request, pytt, 'ftesting.zcml')

def test_with_infrae_testbrowser(config, app):
    browser = Browser(app)
    browser.options.handle_errors = False
    browser.open('http://localhost/test')
    assert browser.status == '200 Ok'

We use again the pytest_funcarg functions to setup a ZODB and the Zope Component Architecture. In our test function we create an instance of Browser with our app as argument.

Now we can open our Index site in the browser and check for example the HTTP Response Status.

You can run now again bin/py.test and look on the running test.

Table Of Contents

Previous topic

Examples

Next topic

zope.pytest API

This Page