sphinx_toolbox.testing

Functions for testing Sphinx extensions.

Attention

This module has the following additional requirements:

coincidence>=0.4.3
pygments>=2.7.4

These can be installed as follows:

python -m pip install sphinx-toolbox[testing]

See also

Sphinx’s own testing library: https://github.com/sphinx-doc/sphinx/tree/3.x/sphinx/testing

Classes:

Sphinx()

A class that pretends to be sphinx.application.Sphinx but that is stripped back to allow the internals to be inspected.

RunSetupOutput(setup_ret, directives, roles, …)

NamedTuple representing the output from run_setup().

HTMLRegressionFixture(datadir, …)

Subclass of pytest_regressions.file_regression.FileRegressionFixture for checking HTML files.

LaTeXRegressionFixture(datadir, …)

Subclass of coincidence.regressions.AdvancedFileRegressionFixture for checking LaTeX files.

Functions:

run_setup(setup_func)

Function for running an extension’s setup() function for testing.

remove_html_footer(page)

Remove the Sphinx footer from HTML pages.

check_html_regression(page, file_regression)

Check an HTML page generated by Sphinx for regressions, using pytest-regressions.

remove_html_link_tags(page)

Remove link tags from HTML pages.

check_asset_copy(func, *asset_files, …)

Helper to test functions which respond to Sphinx build-finished events and copy asset files.

html_regression(datadir, original_datadir, …)

Returns an HTMLRegressionFixture scoped to the test function.

latex_regression(datadir, original_datadir, …)

Returns a LaTeXRegressionFixture scoped to the test function.

class Sphinx[source]

Bases: object

A class that pretends to be sphinx.application.Sphinx but that is stripped back to allow the internals to be inspected. This can be used in tests to ensure the nodes, roles etc. being registered in an extension’s setup() function are actually being registered.

Attributes:

registry

Instance of sphinx.registry.SphinxComponentRegistry

config

Instance of sphinx.config.Config

events

Instance of sphinx.events.EventManager

html_themes

Mapping of HTML theme names to filesystem paths.

Methods:

add_builder(builder[, override])

Register a new builder.

add_config_value(name, default, rebuild[, types])

Register a configuration value.

add_event(name)

Register an event called name.

set_translator(name, translator_class[, …])

Register or override a Docutils translator class.

add_node(node[, override])

Register a Docutils node class.

add_enumerable_node(node, figtype[, …])

Register a Docutils node class as a numfig target.

add_directive(name, cls[, override])

Register a Docutils directive.

add_role(name, role[, override])

Register a Docutils role.

add_generic_role(name, nodeclass[, override])

Register a generic Docutils role.

add_domain(domain[, override])

Register a domain.

add_directive_to_domain(domain, name, cls[, …])

Register a Docutils directive in a domain.

add_role_to_domain(domain, name, role[, …])

Register a Docutils role in a domain.

add_index_to_domain(domain, index[, override])

Register a custom index for a domain.

add_object_type(directivename, rolename[, …])

Register a new object type.

add_crossref_type(directivename, rolename[, …])

Register a new crossref object type.

add_transform(transform)

Register a Docutils transform to be applied after parsing.

add_post_transform(transform)

Register a Docutils transform to be applied before writing.

add_js_file(filename, **kwargs)

Register a JavaScript file to include in the HTML output.

add_css_file(filename, **kwargs)

Register a stylesheet to include in the HTML output.

add_latex_package(packagename[, options, …])

Register a package to include in the LaTeX source code.

add_lexer(alias, lexer)

Register a new lexer for source code.

add_autodocumenter(cls[, override])

Register a new documenter class for the autodoc extension.

add_autodoc_attrgetter(typ, getter)

Register a new getattr-like function for the autodoc extension.

add_source_suffix(suffix, filetype[, override])

Register a suffix of source files.

add_source_parser(*args, **kwargs)

Register a parser class.

add_env_collector(collector)

No-op for now.

add_html_theme(name, theme_path)

Register an HTML Theme.

add_html_math_renderer(name[, …])

Register a math renderer for HTML.

setup_extension(extname)

Import and setup a Sphinx extension module.

require_sphinx(version)

Check the Sphinx version if requested.

connect(event, callback[, priority])

Register callback to be called when event is emitted.

registry

Type:    SphinxComponentRegistry

Instance of sphinx.registry.SphinxComponentRegistry

config

Type:    Config

Instance of sphinx.config.Config

events

Type:    EventManager

Instance of sphinx.events.EventManager

html_themes

Type:    Dict[str, str]

Mapping of HTML theme names to filesystem paths.

add_builder(builder, override=False)[source]

Register a new builder.

The registered values are stored in the app.registry.builders dictionary (typing.Dict[str, typing.Type[sphinx.builders.Builder]]).

add_config_value(name, default, rebuild, types=())[source]

Register a configuration value.

The registered values are stored in the app.config.values dictionary (typing.Dict[str, typing.Tuple]).

add_event(name)[source]

Register an event called name.

The registered values are stored in the app.events.events dictionary (typing.Dict[str, str]).

set_translator(name, translator_class, override=False)[source]

Register or override a Docutils translator class.

The registered values are stored in the app.registry.translators dictionary. (typing.Dict[str, typing.Type[docutils.nodes.NodeVisitor]]).

add_node(node, override=False, **kwargs)[source]

Register a Docutils node class.

The registered values are stored in the additional_nodes set returned by run_setup() (typing.Set[typing.Type[docutils.nodes.Node]]).

add_enumerable_node(node, figtype, title_getter=None, override=False, **kwargs)[source]

Register a Docutils node class as a numfig target.

add_directive(name, cls, override=False)[source]

Register a Docutils directive.

add_role(name, role, override=False)[source]

Register a Docutils role.

The registered values are stored in the roles dictionary returned by run_setup(). (typing.Dict[str, typing.Callable]).

add_generic_role(name, nodeclass, override=False)[source]

Register a generic Docutils role.

add_domain(domain, override=False)[source]

Register a domain.

add_directive_to_domain(domain, name, cls, override=False)[source]

Register a Docutils directive in a domain.

add_role_to_domain(domain, name, role, override=False)[source]

Register a Docutils role in a domain.

add_index_to_domain(domain, index, override=False)[source]

Register a custom index for a domain.

add_object_type(directivename, rolename, indextemplate='', parse_node=None, ref_nodeclass=None, objname='', doc_field_types=[], override=False)[source]

Register a new object type.

add_crossref_type(directivename, rolename, indextemplate='', ref_nodeclass=None, objname='', override=False)[source]

Register a new crossref object type.

add_transform(transform)[source]

Register a Docutils transform to be applied after parsing.

add_post_transform(transform)[source]

Register a Docutils transform to be applied before writing.

add_js_file(filename, **kwargs)[source]

Register a JavaScript file to include in the HTML output.

New in version 2.8.0.

add_css_file(filename, **kwargs)[source]

Register a stylesheet to include in the HTML output.

New in version 2.7.0.

add_latex_package(packagename, options=None, after_hyperref=False)[source]

Register a package to include in the LaTeX source code.

add_lexer(alias, lexer)[source]

Register a new lexer for source code.

add_autodocumenter(cls, override=False)[source]

Register a new documenter class for the autodoc extension.

add_autodoc_attrgetter(typ, getter)[source]

Register a new getattr-like function for the autodoc extension.

add_source_suffix(suffix, filetype, override=False)[source]

Register a suffix of source files.

add_source_parser(*args, **kwargs)[source]

Register a parser class.

add_env_collector(collector)[source]

No-op for now.

add_html_theme(name, theme_path)[source]

Register an HTML Theme.

add_html_math_renderer(name, inline_renderers=None, block_renderers=None)[source]

Register a math renderer for HTML.

setup_extension(extname)[source]

Import and setup a Sphinx extension module.

require_sphinx(version)[source]

Check the Sphinx version if requested.

No-op when testing

connect(event, callback, priority=500)[source]

Register callback to be called when event is emitted.

Return type

int

run_setup(setup_func)[source]

Function for running an extension’s setup() function for testing.

Parameters

setup_func (Union[Callable[[Sphinx], Optional[Dict[str, Any]]], Callable[[Sphinx], Optional[SphinxExtMetadata]], Callable[[Sphinx], Optional[Dict[str, Any]]], Callable[[Sphinx], Optional[SphinxExtMetadata]]]) – The setup() function under test.

Return type

RunSetupOutput

Returns

5-element namedtuple

namedtuple RunSetupOutput(setup_ret, directives, roles, additional_nodes, app)[source]

Bases: NamedTuple

NamedTuple representing the output from run_setup().

Fields
  1.  setup_ret (Union[None, Dict[str, Any], SphinxExtMetadata]) – The output from the setup() function.

  2.  directives (Dict[str, Callable]) – Mapping of directive names to directive functions.

  3.  roles (Dict[str, Callable]) – Mapping of role names to role functions.

  4.  additional_nodes (Set[Type[Any]]) – Set of custom docutils nodes registered in setup().

  5.  app (Sphinx) – Instance of sphinx_toolbox.testing.Sphinx.

__repr__()

Return a string representation of the RunSetupOutput.

Return type

str

Remove the Sphinx footer from HTML pages.

The footer contains the Sphinx and theme versions and therefore changes between versions. This can cause unwanted, false positive test failures.

Parameters

page (BeautifulSoup) – The page to remove the footer from.

Return type

BeautifulSoup

Returns

The page without the footer.

check_html_regression(page, file_regression)[source]

Check an HTML page generated by Sphinx for regressions, using pytest-regressions.

Parameters
  • page (BeautifulSoup) – The page to test.

  • file_regression (FileRegressionFixture) – The file regression fixture.

Example usage

@pytest.mark.parametrize("page", ["index.html"], indirect=True)
def test_page(page: BeautifulSoup, file_regression: FileRegressionFixture):
    check_html_regression(page, file_regression)

Remove link tags from HTML pages.

These may vary between different versions of Sphinx and its extensions. This can cause unwanted, false positive test failures.

Parameters

page (BeautifulSoup) – The page to remove the link tags from.

Return type

BeautifulSoup

Returns

The page without the link tags.

check_asset_copy(func, *asset_files, file_regression)[source]

Helper to test functions which respond to Sphinx build-finished events and copy asset files.

New in version 2.0.0.

Parameters
  • func (Callable[[Sphinx, Exception], Any]) – The function to test.

  • *asset_files (Union[str, Path, PathLike]) – The paths of asset files copied by the function, relative to the Sphinx output directory.

  • file_regression (FileRegressionFixture)

class HTMLRegressionFixture(datadir, original_datadir, request)[source]

Bases: FileRegressionFixture

Subclass of pytest_regressions.file_regression.FileRegressionFixture for checking HTML files.

New in version 2.0.0.

Methods:

check(page, *[, extension, jinja2, …])

Check an HTML page generated by Sphinx for regressions, using pytest-regressions.

check(page, *, extension='.html', jinja2=False, jinja2_namespace=None, **kwargs)[source]

Check an HTML page generated by Sphinx for regressions, using pytest-regressions.

Parameters

Changed in version 2.14.0: Added the jinja2 keyword argument.

Changed in version 2.17.0: Added the jinja2_namespace keyword argument.

When jinja2 is True, the reference file will be rendered as a jinja2 template. The template is passed the following variables:

  • sphinx_version – the Sphinx version number, as a tuple of integers.

  • python_version – the Python version number, in the form returned by sys.version_info.

  • docutils_version – the docutils version number, as a tuple of integers (New in version 2.16.0).

Example usage

@pytest.mark.parametrize("page", ["index.html"], indirect=True)
def test_page(page: BeautifulSoup, html_regression: HTMLRegressionFixture):
    html_regression.check(page, file_regression)
fixture html_regression[source]

Scope:    function

Returns an HTMLRegressionFixture scoped to the test function.

New in version 2.0.0.

Return type

HTMLRegressionFixture

class LaTeXRegressionFixture(datadir, original_datadir, request)[source]

Bases: AdvancedFileRegressionFixture

Subclass of coincidence.regressions.AdvancedFileRegressionFixture for checking LaTeX files.

New in version 2.17.0.

Methods:

check(contents, *[, extension, jinja2, …])

Check a LaTeX file generated by Sphinx for regressions, using pytest-regressions

check(contents, *, extension='.html', jinja2=False, jinja2_namespace=None, **kwargs)[source]

Check a LaTeX file generated by Sphinx for regressions, using pytest-regressions

Parameters

When jinja2 is True, the reference file will be rendered as a jinja2 template. The template is passed the following variables:

  • sphinx_version – the Sphinx version number, as a tuple of integers.

  • python_version – the Python version number, in the form returned by sys.version_info.

  • docutils_version – the docutils version number, as a tuple of integers (New in version 2.16.0).

Note

Unlike standard HTML jinja2 templates, this class expects the use of < and > rather than { and }.

For example:

<% if foo %>
<# This should only happen on Tuesdays #>
<< foo.upper() >>
<% endif %>

Example usage

@pytest.mark.sphinx("latex")
def test_latex_output(app: Sphinx, latex_regression: LaTeXRegressionFixture):
    app.build()
    output_file = app.outdir / "python.tex"
    latex_regression.check(output_file.read_text())
fixture latex_regression[source]

Scope:    function

Returns a LaTeXRegressionFixture scoped to the test function.

New in version 2.17.0.

Return type

LaTeXRegressionFixture