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 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.test_params(...)¶
Parameters associated with a test.
- Parameters:
shared_result (str) – A key that allows sharing the build result, status, and warning 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.@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 ...
- @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 (overridden when
shared_resultis used).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 ...
Fixtures¶
- sphinx.testing.fixtures.rootdir()¶
- Scope:
session
Defaults to
Noneso tests operate on (empty) temporary paths.Can be overridden in a project’s
conftest.pyto return aPathto a directory, containing multiple Sphinx documentation sources under sub-directories prefixed with test-.@pytest.fixture(scope='session') def rootdir() -> pathlib.Path | None: return pathlib.Path(__file__).parent / 'docsets'
tests/ ├── conftest.py <-- defines rootdir fixture ├── docsets/ ├── test-example1/ │ ├── conf.py │ └── index.rst ├── test-example2/ │ ├── conf.py │ └── index.rst └── test_something.py
- sphinx.testing.fixtures.sphinx_test_tempdir()¶
- Scope:
session
Base temporary directory
Pathused for building the test apps.
- sphinx.testing.fixtures.app_params()¶
The positional
argsand keywordkwargsused to build theSphinxTestAppfor this test. These are derived from thepytest.mark.sphinx(),pytest.mark.test_params(), and default settings.If
rootdirfixture is notNone, the contents ofrootdir / f'test-{testroot}'get copied into the source directory that the app would build in.Returns a namedtuple of
(args, kwargs).
- sphinx.testing.fixtures.make_app()¶
Factory function that constructs a
SphinxTestAppfromapp_params.def test_something(make_app: Callable[..., SphinxTestApp]) -> None: app = make_app("html") app.build() # ... test something about the built documentation ...
- sphinx.testing.fixtures.app()¶
A
SphinxTestAppconstructed fromapp_params.def test_something(app: SphinxTestApp) -> None: app.build() # ... test something about the built documentation ...
- sphinx.testing.fixtures.if_graphviz_found()¶
Skip the test if
graphviz_dotis not configured or the binary is unavailable.@pytest.mark.usefixtures('if_graphviz_found') def test_graphviz_diagram(app: SphinxTestApp) -> None: app.build() # ... test something about the graphviz diagram ...
- sphinx.testing.fixtures.rollback_sysmodules()¶
Iterator that snapshots
sys.modulesbefore the test and removes any modules imported during the test body. Helps tests reload target modules to clear caches.This mostly exists to help test
sphinx.ext.autodoc.@pytest.mark.usefixtures('rollback_sysmodules') def test_module_reload(app: SphinxTestApp) -> None: import my_extension # ... test something about my_extension ...
- sphinx.testing.fixtures.status()¶
Compatibility fixture returning
app.status(StringIO).
- sphinx.testing.fixtures.warning()¶
Compatibility fixture returning
app.warning(StringIO).
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.
- extras¶
A dictionary to store arbitrary data associated with this app.
- 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.
Usage¶
If you want to know more detailed usage,
please refer to tests/conftest.py and other test_*.py files
under the tests/ directory of the Sphinx source code.