Testing ======= Builds and links ---------------- .. _build-errors: Build errors ~~~~~~~~~~~~ You have the option of checking whether your content is built correctly before publishing your changes. `Sphinx `_ has a nitpicky mode for this, which can be called up with the ``-n`` option, for example with: .. tab:: Linux/macOS .. code-block:: console $ python -m sphinx -nb html docs/ docs/_build/ .. tab:: Windows .. code-block:: ps1con C:> python -m sphinx -nb html docs\ docs\_build\ .. _link-checks: links ~~~~~ You can also automatically ensure that the link targets you specify are accessible. Our documentation tool Sphinx uses a ``linkcheck`` builder for this, which you can call up with: .. tab:: Linux/macOS .. code-block:: console $ python -m sphinx -b linkcheck docs/ docs/_build/ .. tab:: Windows .. code-block:: ps1con C:> python -m sphinx -b linkcheck docs\ docs\_build\ The output can then look like this, for example: .. tab:: Linux/macOS .. code-block:: console $ python -m sphinx -b linkcheck docs/ docs/_build/ Running Sphinx v3.5.2 loading translations [de]... done … building [mo]: targets for 0 po files that are out of date building [linkcheck]: targets for 27 source files that are out of date … (content/accessibility: line 89) ok https://bbc.github.io/subtitle-guidelines/ (content/writing-style: line 164) ok http://disabilityinkidlit.com/2016/07/08/introduction-to-disability-terminology/ … ( index: line 5) redirect https://cusy-design-system.readthedocs.io/ - with Found to https://cusy-design-system.readthedocs.io/de/latest/ … (accessibility/color: line 114) broken https://chrome.google.com/webstore/detail/nocoffee/jjeeggmbnhckmgdhmgdckeigabjfbddl - 404 Client Error: Not Found for url: https://chrome.google.com/webstore/detail/nocoffee/jjeeggmbnhckmgdhmgdckeigabjfbddl .. tab:: Windows .. code-block:: ps1con C:> python -m sphinx -b linkcheck docs\ docs\_build\ Running Sphinx v3.5.2 loading translations [de]... done … building [mo]: targets for 0 po files that are out of date building [linkcheck]: targets for 27 source files that are out of date … (content/accessibility: line 89) ok https://bbc.github.io/subtitle-guidelines/ (content/writing-style: line 164) ok http://disabilityinkidlit.com/2016/07/08/introduction-to-disability-terminology/ … ( index: line 5) redirect https://cusy-design-system.readthedocs.io/ - with Found to https://cusy-design-system.readthedocs.io/de/latest/ … (accessibility/color: line 114) broken https://chrome.google.com/webstore/detail/nocoffee/jjeeggmbnhckmgdhmgdckeigabjfbddl - 404 Client Error: Not Found for url: https://chrome.google.com/webstore/detail/nocoffee/jjeeggmbnhckmgdhmgdckeigabjfbddl .. _ci-docs: Continuous integration ~~~~~~~~~~~~~~~~~~~~~~ If necessary, you can also check automatically in your :term:`CI` pipeline whether the documentation is being built and the links are valid. In :doc:`../../test/tox`, the configuration can be added as follows: .. code-block:: ini :caption: tox.ini [testenv:docs] # Keep base_python in sync with ci.yml and .readthedocs.yaml. base_python = py312 extras = docs commands = sphinx-build -n -T -W -b html -d {envtmpdir}/doctrees docs docs/_build/html [testenv:docs-linkcheck] base_python = {[testenv:docs]base_python} extras = {[testenv:docs]extras} commands = sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees docs docs/_build/html You can then define the following jobs for GitHub, for example: .. code-block:: yaml :caption: .github/workflows/ci.yml docs: name: Build docs and run doctests needs: build-package runs-on: ubuntu-latest steps: - name: Download pre-built packages uses: actions/download-artifact@v4 with: name: Packages path: dist - run: tar xf dist/*.tar.gz --strip-components=1 - uses: actions/setup-python@v5 with: # Keep in sync with tox.ini/docs and .readthedocs.yaml python-version: "3.12" cache: pip - run: python -m pip install tox - run: python -m tox run -e docs reST formatting --------------- Whether the :doc:`Sphinx ` documentation is written in valid :doc:`rest` format can be checked with `sphinx-lint `_. We usually include this in our :doc:`pre-commit ` configuration: .. code-block:: yaml :caption: .pre-commit-config.yaml - repo: https://github.com/sphinx-contrib/sphinx-lint rev: v1.0.0 hooks: - id: sphinx-lint types: [rst] .. seealso:: With :doc:`Sybil:index` you can not only check :doc:`rest`, but also :doc:`Markdown ` and :doc:`Myst `, for example. Sybil can also check code blocks in the documentation with either :doc:`../../test/pytest/index` or :doc:`../../test/unittest`. .. _test_code: Code ---- With the built-in Python library :doc:`../doctest`, you can also test code in your documentation with the :func:`doctest.testfile` method: .. code-block:: Python import doctest doctest.testfile("example.rst") This short script executes and checks all interactive Python examples contained in the :file:`example.rst` file. The content of the file is treated as if it were a single huge docstring. .. seealso:: A simple example can be found in the Python documentation: `Simple Usage: Checking Examples in a Text File `_. Another way to test code in documentation is `pytest-doctestplus `_. Code formatting --------------- The formatting of code blocks can be checked with `blacken-docs `_, which uses :doc:`Python4DataScience:productive/qa/black`. We usually integrate the library via the :doc:`pre-commit ` framework: .. code-block:: yaml - repo: https://github.com/adamchainz/blacken-docs rev: "v1.12.1" hooks: - id: blacken-docs additional_dependencies: - black blacken-docs currently supports the following black options: * `line-length `_ * `preview `_ * `skip-string-normalization `_ * `target-version `_ `Vale `_ goes beyond spelling and grammar checks. It also checks the language style: Is what is said repeated? Is the language too informal? Is the language inconsistent? Are undesirable clichés being used? Or is the language sexist? Vale is used by many open source projects, including * GitLab (`.vale.ini `_, `rules `__) * Homebrew (`.vale.ini `__, `rules `__) The following styles come with Vale itself: `Microsoft `_ An implementation of the `Microsoft Writing Style Guide `__. `Google `_ An implementation of the style guide for the `Google developer documentation style guide `__. `write-good `_ An implementation of the guidelines enforced by the `write-good `__ linter. `proselint `_ An implementation of the guidelines enforced by the `proselint `__ linter. `Joblint `_ An implementation of the directives enforced by the `Joblint `__ linter. Vale is configured in the :file:`.vale.ini` file: .. code-block:: ini :caption: .vale.ini StylesPath = styles MinAlertLevel = suggestion Packages = https://github.com/cusyio/cusy-vale/archive/refs/tags/v0.1.0.zip [*.{md,rst}] BasedOnStyles = cusy-en .. seealso:: * `Vale Configuration `_ You should then update your :ref:`.gitignore ` file if necessary: .. code-block:: ini :caption: .gitignore styles/* You can configure Vale for the :doc:`pre-commit ` framework with: .. code-block:: yaml :caption: .pre-commit-config.yaml - repo: https://github.com/errata-ai/vale rev: v3.7.1 hooks: - id: vale sync pass_filenames: false args: [sync] - id: vale args: [--output=line, --minAlertLevel=error, .] .. _docstrings-coverage: Docstrings coverage ------------------- `interrogate `_ checks your codebase for missing documentation strings and generates a `shields.io-like badge `_. You can configure ``interrogate`` in the :ref:`pyproject-toml` file, for example: .. code-block:: toml :caption: pyproject.toml :emphasize-lines: 4, 8- [project.optional-dependencies] tests = [ "coverage[toml]", "interrogate", "pytest>=6.0", ] [tool.interrogate] ignore-init-method = true ignore-init-module = false ignore-magic = false ignore-semiprivate = false ignore-private = false ignore-module = false ignore-property-decorators = false fail-under = 95 exclude = ["tests/functional/sample", "setup.py", "docs"] verbose = 0 omit-covered-files = false quiet = false whitelist-regex = [] ignore-regex = [] color = true .. seealso:: * `Configuration `_ You can now insert ``interrogate`` into your :doc:`../../test/tox` file, for example with .. code-block:: ini :caption: tox.ini [testenv:doc] deps = interrogate skip_install = true commands = interrogate --quiet --fail-under 95 src tests You can also use ``interrogate`` with :doc:`pre-commit `: .. code-block:: yaml :caption: .pre-commit-config.yaml repos: - repo: https://github.com/econchick/interrogate rev: 1.7.0 hooks: - id: interrogate args: [--quiet, --fail-under=95] pass_filenames: false