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.
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.
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 ========================
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.
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.