How to set up pytest-plone in your add-on#
This guide shows you how to add pytest-plone to an existing Plone add-on.
Before you start#
You need testing layers.
A testing layer is the object that builds a Plone site for your tests: it loads your ZCML, installs your GenericSetup profile, and hands the result to each test.
By convention you declare yours in a testing.py module in your package, building on the fixtures plone.app.testing provides.
pytest-plone does not replace any of this.
It takes the layers you already have and turns them into pytest fixtures.
If your add-on has no testing.py yet, write one first—the packages that own the layer machinery document how:
See also
plone.app.testing—the Plone-specific layers and fixtures, and how to write your own
testing.py.plone.testing—the underlying layer model.
Install the package#
Add pytest-plone to your test dependencies:
[project.optional-dependencies]
test = [
"pytest-plone",
"plone.app.testing",
]
Write the conftest#
In your top-level conftest.py, import your testing layers and pass them to fixtures_factory together with a prefix for each.
Inject the result into the module namespace so pytest discovers the fixtures.
from my.addon.testing import MY_ADDON_FUNCTIONAL_TESTING
from my.addon.testing import MY_ADDON_INTEGRATION_TESTING
from pytest_plone import fixtures_factory
pytest_plugins = ["pytest_plone"]
globals().update(
fixtures_factory(
(
(MY_ADDON_FUNCTIONAL_TESTING, "functional"),
(MY_ADDON_INTEGRATION_TESTING, "integration"),
)
)
)
The prefixes name the generated fixtures.
With integration and functional you get integration, integration_class, integration_session, and the three functional counterparts.
Stick to these two names unless you have a reason not to—the fixtures in Fixtures are built on them.
Write a test#
Ask for what you need by naming it.
def test_portal_title(portal):
assert portal.title == "Plone site"
Run the suite#
pytest
Declare your package name#
Several add-on fixtures need to know which distribution is under test.
Provide a package_name fixture in your conftest.py:
import pytest
@pytest.fixture
def package_name() -> str:
return "my.addon"
This unlocks uninstalled, which removes the boilerplate from the canonical uninstall test.
Where to go next#
How to test that your add-on installs and uninstalls: the canonical install and uninstall suite.
How to speed up a slow test suite: if the suite feels slower than it should.
Fixtures: everything you can ask for.