Testing API¶
Added in version 1.6.
Sphinx provides utility functions and pytest fixtures to make it easier to write test suites that build multiple Sphinx documentation projects.
Using the pytest plugin¶
To use pytest helpers that are provided by sphinx.testing, add the
'sphinx.testing.fixtures' plugin to your conftest.py file
as follows:
pytest_plugins = ['sphinx.testing.fixtures']
Markers¶
- @pytest.mark.sphinx(buildername='html', *, testroot='root', ...)¶
Arguments to initialize the Sphinx test application.
- Parameters:
buildername (str) – Builder to use.
testroot (str) – Test root directory to use.
srcdir – Source directory to use.
confoverrides (dict) – Configuration values to override.
freshenv (bool) – Whether to refresh the environment.
warningiserror (bool) – Treat warnings as errors.
tags – List of tags to set.
verbosity (int) – Verbosity level.
parallel (int) – Number of parallel processes.
builddir – Build directory.
docutils_conf – Docutils configuration.
@pytest.mark.sphinx('html', testroot='something') def test_html_output(app: SphinxTestApp) -> None: app.build() # ... test something about the HTML output ...
- @pytest.mark.test_params(*, shared_result=...)¶
Parameters associated with a test.
- Parameters:
shared_result (str) – A key that allows sharing the build result, status, and warnings between tests that use the same key.
When multiple tests with a module are marked with the same
shared_resultvalue, they will share the same build result as well as status and warning buffers. This allows related tests to avoid redundant rebuilds and reuse the same build context.Attention
shared_result and srcdir are mutually incompatible.
@pytest.mark.test_params(shared_result='html_build') def test_html_title(app: SphinxTestApp) -> None: app.build() # ... test something about the HTML output ... @pytest.mark.test_params(shared_result='html_build') def test_html_index(app: SphinxTestApp) -> None: app.build() # ... test something else about the HTML output ...
Fixtures¶
- sphinx.testing.fixtures.app: SphinxTestApp¶
- Scope:
function
Provides a
SphinxTestAppinstance. This is the most common way to get a Sphinx application for testing.The app can be configured by using the
@pytest.mark.sphinxmarker.def test_something(app: SphinxTestApp) -> None: app.build() # ... test something about the built documentation ...
- sphinx.testing.fixtures.make_app(*args: Any, **kwargs: Any) SphinxTestApp¶
- Scope:
function
Factory function that constructs a
SphinxTestAppinstance for use in tests. This is the preferred way to create instances of theSphinxobject, as it handles clean-up. The arguments are the same as those toSphinxTestApp.def test_something(make_app: Callable[..., SphinxTestApp]) -> None: app = make_app('html') app.build() # ... test something about the built documentation ...
- sphinx.testing.fixtures.app_params: tuple[Sequence[Any], Mapping[str, Any]]¶
- Scope:
function
The positional keyword arguments used to create the
SphinxTestAppfor this test. These are derived from the markers applied to the test function.Returns a namedtuple of
(args, kwargs).
- sphinx.testing.fixtures.rootdir: pathlib.Path | None¶
- Scope:
session
Default is
None, meaning tests use empty temporary directories.Can be overridden in a project’s
conftest.pyto return aPathto a directory, containing multiple Sphinx documentation sources under sub-directories prefixed withtest-.@pytest.fixture(scope='session') def rootdir() -> Path: return Path(__file__).resolve().parent / 'roots'
tests/ ├── conftest.py <-- defines rootdir fixture ├── roots/ │ ├── test-example1/ │ │ ├── conf.py │ │ └── index.rst │ └── test-example2/ │ ├── conf.py │ └── index.rst └── test_something.py
- sphinx.testing.fixtures.sphinx_test_tempdir: pathlib.Path¶
- Scope:
session
Base temporary directory
Pathused for building the test apps.
Utilities¶
- class sphinx.testing.util.SphinxTestApp(buildername: str = 'html', srcdir: Path | None = None, builddir: Path | None = None, freshenv: bool = False, confoverrides: dict[str, Any] | None = None, status: StringIO | None = None, warning: StringIO | None = None, tags: Sequence[str] = (), docutils_conf: str | None = None, parallel: int = 0, verbosity: int = 0, warningiserror: bool = False, pdb: bool = False, exception_on_warning: bool = False, **extras: Any)[source]¶
Bases:
SphinxA subclass of
Sphinxfor tests.The constructor uses some better default values for the initialization parameters and supports arbitrary keywords stored in the
extrasread-only mapping.It is recommended to use:
@pytest.mark.sphinx('html', testroot='root') def test(app): app = ...
instead of:
def test(): app = SphinxTestApp('html', srcdir=srcdir)
In the former case, the ‘app’ fixture takes care of setting the source directory, whereas in the latter, the user must provide it themselves.
- class sphinx.testing.util.SphinxTestAppWrapperForSkipBuilding(buildername: str = 'html', srcdir: Path | None = None, builddir: Path | None = None, freshenv: bool = False, confoverrides: dict[str, Any] | None = None, status: StringIO | None = None, warning: StringIO | None = None, tags: Sequence[str] = (), docutils_conf: str | None = None, parallel: int = 0, verbosity: int = 0, warningiserror: bool = False, pdb: bool = False, exception_on_warning: bool = False, **extras: Any)[source]¶
Bases:
SphinxTestAppA wrapper for SphinxTestApp.
This class is used to speed up the test by skipping
app.build()if it has already been built and there are any output files.
Examples¶
For practical examples, refer to tests/conftest.py
and other test_*.py files under the tests/ directory
of the Sphinx source code.