API#

fixtures_factory#

fixtures_factory is the one function you call yourself. It takes your plone.testing layers and returns a dictionary of pytest fixtures, which you inject into your conftest.py namespace.

pytest_plone.helpers.fixtures_factory(test_layers: collections.abc.Iterable[tuple[plone.testing.layer.Layer, str]], *, keep_session: bool = True) dict[str, Any]#

Create pytest fixtures for a group of plone.testing.layer.Layer.

Parameters:
  • test_layers – Iterable (tuple or list) containing two-element tuple with the Layer object and a string with the prefix to use for fixtures created for that layer.

  • keep_session – When True (the default) an autouse session fixture is registered per layer so the layer is set up once per session instead of once per function-style test. Set to False to restore the previous behavior.

    fixtures_factory(
        (
            (PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING, "functional"),
            (PRODUCTS_CMFPLONE_INTEGRATION_TESTING, "integration"),
        )
    )

Generated fixtures#

For each (layer, prefix) pair you pass, three fixtures are generated:

Fixture

Scope

Purpose

{prefix}

Function

The layer, with testSetUp and testTearDown run around each test.

{prefix}_class

Class

The layer, set up once per test class.

{prefix}_session

Session

The layer, kept for the whole session.

With the conventional prefixes integration and functional, that yields:

Fixture

Scope

integration

Function

integration_class

Class

integration_session

Session

functional

Function

functional_class

Class

functional_session

Session

The fixtures in Fixtures are built on these. You rarely request them directly—ask for portal rather than integration.

Session-wide layers#

By default, fixtures_factory also registers an autouse session fixture per layer. This keeps each testing layer set up once per session instead of once per test.

The default matters. Function-style tests depend only on the function- and class-scoped fixtures, never on the session fixture. Without the autouse fixture, zope.pytestlayer tears the layer down and sets it up again (running a full applyProfile) around every single test.

Per-test isolation is unaffected: IntegrationTesting still rolls back the transaction after each test.

To restore the previous behavior, pass keep_session=False:

globals().update(
    fixtures_factory(
        (
            (PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING, "functional"),
            (PRODUCTS_CMFPLONE_INTEGRATION_TESTING, "integration"),
        ),
        keep_session=False,
    )
)

For the reasoning behind this, see About testing layers, scopes, and isolation.