Skip to content

Test conftest: app.warning_list captures only setup warnings, not build warnings #1703

@ubmarco

Description

@ubmarco

In tests/conftest.py (around lines 316–324), the fixture populates app.warning_list immediately after make_app(...) and before yielding the app:

# Add the Sphinx warning as list to the app
# Somehow "app._warning" seems to be just a boolean, if the builder is "latex" or "singlehtml".
# In this case we don't catch the warnings.
if builder_params.get("buildername", "html") == "html":
    app.warning_list = strip_colors(
        app._warning.getvalue().replace(str(app.srcdir) + os.sep, "srcdir/")
    ).splitlines()
else:
    app.warning_list = None

Problem

app.build() is called by the individual test cases, not by the fixture. Since warning_list is captured before yield app, it only contains warnings emitted during Sphinx app construction (config loading, extension setup, etc.) — not the warnings emitted during the actual build, which are typically what tests want to assert against.

Any test that does:

def test_something(test_app):
    app = test_app
    app.build()
    assert "expected warning" in app.warning_list  # build warnings missing

…will silently miss build-time warnings, leading to false negatives in warning-based assertions.

Suggested fix

Replace the eager attribute with a helper method that test cases can call at the right time (e.g. after app.build()):

def _collect_warnings(app):
    if app.builder.name != "html":
        return None
    return strip_colors(
        app._warning.getvalue().replace(str(app.srcdir) + os.sep, "srcdir/")
    ).splitlines()

app.get_warnings = lambda: _collect_warnings(app)

Test usage:

app.build()
warnings = app.get_warnings()
assert "expected warning" in warnings

This also avoids the latex/singlehtml _warning quirk by letting the caller decide when (and whether) to read it.

Impact

Tests asserting on app.warning_list after build may be passing/failing for the wrong reasons. A grep for warning_list across tests/ should surface affected cases.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions