-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SphinxTestApp
builds in _build
, not separated build
folder
#9524
Comments
|
@tk0miya Please refer to this PyGotham2018, this PyOhio2018, and this PyBay2019 tutorial on Customizing Sphinx by Paul Everitt. The issue is The build directory should not be hard coded, or at the very least, the constructor should have an argument the developer can set to set where to put build files. |
If I understand correctly from the tutorial(s) the starting point is that you import |
@jakobandersen I actually import from
"""Configuration file for `pytest` tests
"""
from typing import Any, Callable, Generator, List, Sequence, Union
from unittest.mock import patch
import pytest
from _pytest.fixtures import SubRequest
from bs4 import BeautifulSoup
from sphinx.testing.path import path
from sphinx.testing.util import SphinxTestApp
pytest_plugins: Union[str, Sequence[str]] = ["sphinx.testing.fixtures",]
"""A ``pytest`` global variable that registers plugins for use in testing."""
# Exclude 'roots' dirs for pytest test collector
collect_ignore: List[str] = ["roots", "__init__.py"]
"""A ``pytest`` global variable that excludes directories or modules from being collected by the ``pytest`` runner"""
@pytest.fixture()
def rootdir() -> Generator[str, None, None]:
"""Root directory for sphinx tests.
Yields:
Generator[str, None, None]: Generator that yields test root directories
"""
yield path(".\\docs\\source").abspath()
@pytest.fixture()
def content(
make_app: Callable[..., Any], rootdir: str
) -> Generator[SphinxTestApp, None, None]:
"""Content of generated html pages.
Args:
make_app (Callable[..., Any]): Function that creates a sphinx app for testing purposes
rootdir (str): Test root directory
Yields:
Generator[SphinxTestApp, None, None]: Generator that yields sphinx apps for testing purposes
"""
app = make_app("html", rootdir)
app.build()
yield app
@pytest.fixture()
def page(
content: SphinxTestApp, request: SubRequest
) -> Generator[BeautifulSoup, None, None]:
"""Generated HTML page of docs
Args:
content (SphinxTestApp): A sphinx app for testing purposes
request (SubRequest): A sub request for handling getting a fixture from a test function/fixture
Yields:
Generator[BeautifulSoup, None, None]: Generator of beautiful soup web scraper instances using the html5lib parser
"""
page_name = request.param
page_content = (content.outdir / page_name).read_text()
yield BeautifulSoup(page_content, "html5lib")
"""Test the documentation index page
"""
from typing import Any, Callable, TypeVar
import pytest
pytestmark = pytest.mark.sphinx("html")
Fixture = TypeVar("Fixture", bound=Callable[..., Any])
FixtureFactory = Callable[[Fixture], Fixture]
@pytest.mark.parametrize(
"page",
[
"index.html",
],
indirect=True,
)
def test_index(page):
"""Test the index page to our documentation
Args:
page ([type]): [description]
"""
expected_title = "Main Page"
return_value = page.find("title").contents[0].strip()
assert return_value == expected_title |
@jakobandersen How is testing done for Right now, I am literally monkey-patching this by changing builddir = srcdir / '_build' to builddir = srcdir.parent / "build" inside @pytest.fixture()
def make_app(test_params: Dict, monkeypatch: Any) -> Generator[Callable, None, None]:
"""
provides make_app function to initialize SphinxTestApp instance.
if you want to initialize 'app' in your test function. please use this
instead of using SphinxTestApp class directory.
"""
monkeypatch.setattr('sphinx.application.abspath', lambda x: x)
apps = []
syspath = sys.path[:]
def make(*args, **kwargs):
status, warning = StringIO(), StringIO()
kwargs.setdefault('status', status)
kwargs.setdefault('warning', warning)
app_: Any = SphinxTestApp(*args, **kwargs)
apps.append(app_)
if test_params['shared_result']:
app_ = SphinxTestAppWrapperForSkipBuilding(app_)
return app_
yield make
sys.path[:] = syspath
for app_ in reversed(apps): # clean up applications from the new ones
app_.cleanup() It's a one-line change. |
tl;dr: (1) we might want to replace Just for the record, I watched @pauleveritt 2018-2019 talks on customizing Sphinx mentioned by @adamgranthendry, which are based on https:/pauleveritt/customizing_sphinx, and I have some remarks:
This leaves me wondering if there should be a more clear way of designating what is considered "public API" and what is not (see also our recent discussion on sphinx-dev). Apart from "what is documented", perhaps it should be in a private namespace ( On the other hand, none of the tutorials on Sphinx extensions nor the overview mention how Sphinx extensions should be tested, so I think it's natural that people try to find their way. @jakobandersen @tk0miya do you have any thoughts on how this should be done, perhaps in the form of some raw notes that we can turn into actual docs? |
@astrojuanlu +1 on replacing |
I've not watched the pointed videos yet. But I understand you'd like to test your extensions using I think there is no special reason to fix the build directory. So +1 for add a new argument to pass it from the caller. |
It would be nice if we can migrate to the pathlib. Our path module has some additional methods to it. So we need to find the way to migrate. Anyway, it's another topic.
We called the APIs described on our document are "public APIs":
Indeed. It has been requested #7008. But not progressed yet... |
I posted #9549 now. Could you try it please? |
Close #9524: test: SphinxTestApp can take ``builddir`` as an argument
Describe the bug
When running
sphinx-quickstart
, users may choose to put build files in a folderbuild
separate fromsource
. However, when running unit tests,SphinxTestApp
automatically builds insource/_build
, which creates two sets of build files. This is evident from the source:How to Reproduce
Then, when running a test, files are built to
source/_build
instead of the desiredbuild
folder.Expected behavior
sphinx
uses the environment variable${BUILDDIR}
(written out toMakefile
andmake.bat
) set when runningsphinx-quickstart
as the folder to put build files in.Your project
N/A
Screenshots
OS
Windows 10 Professional x64, Build 1909
Python version
3.8.10
Sphinx version
4.1.2
Sphinx extensions
N/A
Extra tools
N/A
Additional context
NOTE: If this was intentional, then users who do build under the source directory have their build files overwritten with each unit test, and then this is still a bug.
The text was updated successfully, but these errors were encountered: