Move documentation to read the docs (#402)

* first pass at moving docs to read the docs

* migrate to readthedocs

* Fix broken development link in README

* Use better build command and some stylistic touchups

* Add development section on writing docs

* undo changes to documentation not in readthedocs
This commit is contained in:
Gleb Nikonorov 2020-12-09 08:21:28 -05:00 committed by GitHub
parent ba4f15431c
commit 817d04df58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 562 additions and 1 deletions

View File

@ -16,6 +16,21 @@ on:
- cron: 1 0 * * * # Run daily at 0:01 UTC
jobs:
build_docs:
name: Build Docs
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@master
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.6
- name: Install tox
run: |
python -m pip install --upgrade tox
- name: Build docs with tox
run: |
python -m tox -e docs
build_python:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}

3
.gitignore vendored
View File

@ -48,3 +48,6 @@ Pipfile.lock
# tox folders
.tox
# sphinx/read the docs
docs/_build/

20
docs/Makefile Normal file
View File

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

56
docs/conf.py Normal file
View File

@ -0,0 +1,56 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = "pytest-html"
copyright = "2020, Dave Hunt" # noqa: A001
author = "Dave Hunt"
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "alabaster"
html_theme_options = {
"github_user": "pytest-dev",
"github_repo": "pytest-html",
"github_banner": "true",
"github_type": "star",
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
# The master toctree document.
master_doc = "index"

126
docs/development.rst Normal file
View File

@ -0,0 +1,126 @@
Development
===========
To contribute to `pytest-html` you can use `Pipenv`_ to manage a python virtual environment and
`pre-commit`_ to help you with styling and formatting.
To setup the virtual environment and pre-commit, run:
.. code-block:: bash
$ pipenv install --dev
$ pipenv run pre-commit install
If you're not using `Pipenv`_, run the following to install `pre-commit`_:
.. code-block:: bash
$ pip install pre-commit
$ pre-commit install
Automated Testing
-----------------
All pull requests and merges are tested in `GitHub Actions`_ which are defined inside ``.github`` folder.
To retrigger CI to run again for a pull request, you either use dropdown option, close and reopen pull-request
or to just update the branch containing it.
You can do this with `git commit --allow-empty`
Running Tests
-------------
Python
~~~~~~
You will need `Tox`_ installed to run the tests against the supported Python versions. If you're using `Pipenv`_
it will be installed for you.
With `Pipenv`_, run:
.. code-block:: bash
$ pipenv run tox
Otherwise, to install and run, do:
.. code-block:: bash
$ pip install tox
$ tox
JavaScript
~~~~~~~~~~
You will need `npm`_ installed to run the JavaScript tests. Internally, we use `Grunt`_ and `QUnit`_ to run the tests.
Once `npm`_ is installed, you can install all needed dependencies by running:
.. code-block:: bash
$ npm install
Run the following to execute the tests:
.. code-block:: bash
$ npm test
Documentation
-------------
Documentation is hosted on `Read the Docs`_, and is written in `RST`_. Remember to add any new files to the :code:`toctree`
section in :code:`index.rst`.
To build your documentation, run:
.. code-block:: bash
$ tox -e docs
You can then run a local webserver to verify your changes compiled correctly.
SASS/SCSS/CSS
-------------
You will need `npm`_ installed to compile the CSS, which is generated via `SASS/SCSS`_.
Once `npm`_ is installed, you can install all needed dependencies by running:
.. code-block:: bash
$ npm install
Run the following to generate the CSS:
.. code-block:: bash
$ npm run build:css
Releasing a new version
-----------------------
Follow these steps to release a new version of the project:
#. Update your local master with the upstream master (``git pull --rebase upstream master``)
#. Create a new branch
#. Update ``CHANGES.rst`` with the new version, today's date, and all changes/new features
#. Commit and push the new branch and then create a new pull request
#. Wait for tests and reviews and then merge the branch
#. Once merged, update your local master again (``git pull --rebase upstream master``)
#. Tag the release with the new release version (``git tag v<new tag>``)
#. Push the tag (``git push upstream --tags``)
#. Done. Check `Github Actions`_ for release progress.
.. _GitHub Actions: https://github.com/pytest-dev/pytest-html/actions
.. _Grunt: https://gruntjs.com
.. _npm: https://www.npmjs.com
.. _Pipenv: https://pipenv.pypa.io/en/latest
.. _pre-commit: https://pre-commit.com
.. _QUnit: https://qunitjs.com
.. _Read The Docs: https://readthedocs.com
.. _RST: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html
.. _SASS/SCSS: https://sass-lang.com
.. _Tox: https://tox.readthedocs.io

19
docs/index.rst Normal file
View File

@ -0,0 +1,19 @@
.. pytest-html documentation master file, created by
sphinx-quickstart on Sun Dec 6 20:48:43 2020.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
pytest-html
===========
pytest-html is a plugin for `pytest`_ that generates a HTML report for test results.
.. toctree::
:maxdepth: 2
:caption: Contents:
installing
user_guide
development
.. _pytest: http://pytest.org

24
docs/installing.rst Normal file
View File

@ -0,0 +1,24 @@
Installation
============
Requirements
------------
pytest-html will work with Python >=3.6 or PyPy3.
Installing pytest-html
----------------------
To install pytest-html using `pip`_:
.. code-block:: bash
$ pip install pytest-html
To install from source:
.. code-block:: bash
$ pip install -e .
.. _pip: https://pip.pypa.io/

35
docs/make.bat Normal file
View File

@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

255
docs/user_guide.rst Normal file
View File

@ -0,0 +1,255 @@
User Guide
==========
ANSI codes
----------
Note that ANSI code support depends on the `ansi2html`_ package. Due to the use
of a less permissive license, this package is not included as a dependency. If
you have this package installed, then ANSI codes will be converted to HTML in
your report.
Creating a self-contained report
--------------------------------
In order to respect the `Content Security Policy (CSP)`_, several assets such as
CSS and images are stored separately by default. You can alternatively create a
self-contained report, which can be more convenient when sharing your results.
This can be done in the following way:
.. code-block:: bash
$ pytest --html=report.html --self-contained-html
Images added as files or links are going to be linked as external resources,
meaning that the standalone report HTML file may not display these images
as expected.
The plugin will issue a warning when adding files or links to the standalone report.
Enhancing reports
-----------------
Appearance
~~~~~~~~~~
Custom CSS (Cascasding Style Sheets) can be passed on the command line using
the :code:`--css` option. These will be applied in the order specified, and can
be used to change the appearance of the report.
.. code-block:: bash
$ pytest --html=report.html --css=highcontrast.css --css=accessible.css
Report Title
~~~~~~~~~~~~
By default the report title will be the filename of the report, you can edit it by using the :code:`pytest_html_report_title` hook:
.. code-block:: python
def pytest_html_report_title(report):
report.title = "My very own title!"
Environment
~~~~~~~~~~~
The *Environment* section is provided by the `pytest-metadata`_ plugin, and can be accessed
via the :code:`pytest_configure` hook:
.. code-block:: python
def pytest_configure(config):
config._metadata["foo"] = "bar"
The generated table will be sorted alphabetically unless the metadata is a
:code:`collections.OrderedDict`.
Additional summary information
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can edit the *Summary* section by using the :code:`pytest_html_results_summary` hook:
.. code-block:: python
from py.xml import html
def pytest_html_results_summary(prefix, summary, postfix):
prefix.extend([html.p("foo: bar")])
Extra content
~~~~~~~~~~~~~
You can add details to the HTML report by creating an 'extra' list on the
report object. Here are the types of extra content that can be added:
========== ============================================
Type Example
========== ============================================
Raw HTML ``extra.html('<div>Additional HTML</div>')``
`JSON`_ ``extra.json({'name': 'pytest'})``
Plain text ``extra.text('Add some simple Text')``
URL ``extra.url('http://www.example.com/')``
Image ``extra.image(image, mime_type='image/gif', extension='gif')``
Image ``extra.image('/path/to/file.png')``
Image ``extra.image('http://some_image.png')``
========== ============================================
**Note**: When adding an image from file, the path can be either absolute
or relative.
**Note**: When using ``--self-contained-html``, images added as files or links
may not work as expected, see section `Creating a self-contained report`_ for
more info.
There are also convenient types for several image formats:
============ ====================
Image format Example
============ ====================
PNG ``extra.png(image)``
JPEG ``extra.jpg(image)``
SVG ``extra.svg(image)``
============ ====================
The following example adds the various types of extras using a
:code:`pytest_runtest_makereport` hook, which can be implemented in a plugin or
conftest.py file:
.. code-block:: python
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
pytest_html = item.config.pluginmanager.getplugin("html")
outcome = yield
report = outcome.get_result()
extra = getattr(report, "extra", [])
if report.when == "call":
# always add url to report
extra.append(pytest_html.extras.url("http://www.example.com/"))
xfail = hasattr(report, "wasxfail")
if (report.skipped and xfail) or (report.failed and not xfail):
# only add additional html on failure
extra.append(pytest_html.extras.html("<div>Additional HTML</div>"))
report.extra = extra
You can also specify the :code:`name` argument for all types other than :code:`html` which will change the title of the
created hyper link:
.. code-block:: python
extra.append(pytest_html.extras.text("some string", name="Different title"))
It is also possible to use the fixture :code:`extra` to add content directly
in a test function without implementing hooks. These will generally end up
before any extras added by plugins.
.. code-block:: python
from pytest_html import extras
def test_extra(extra):
extra.append(extras.text("some string"))
Modifying the results table
~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can modify the columns of the report by implementing custom hooks for the header and rows.
The following example :code:`conftest.py` adds a description column with the test function docstring,
adds a sortable time column, and removes the links column:
.. code-block:: python
from datetime import datetime
from py.xml import html
import pytest
def pytest_html_results_table_header(cells):
cells.insert(2, html.th("Description"))
cells.insert(1, html.th("Time", class_="sortable time", col="time"))
cells.pop()
def pytest_html_results_table_row(report, cells):
cells.insert(2, html.td(report.description))
cells.insert(1, html.td(datetime.utcnow(), class_="col-time"))
cells.pop()
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
report.description = str(item.function.__doc__)
You can also remove results by implementing the
:code:`pytest_html_results_table_row` hook and removing all cells. The
following example removes all passed results from the report:
.. code-block:: python
def pytest_html_results_table_row(report, cells):
if report.passed:
del cells[:]
The log output and additional HTML can be modified by implementing the
:code:`pytest_html_results_html` hook. The following example replaces all
additional HTML and log output with a notice that the log is empty:
.. code-block:: python
from py.xml import html
def pytest_html_results_table_html(report, data):
if report.passed:
del data[:]
data.append(html.div("No log output captured.", class_="empty log"))
Display options
---------------
By default, all rows in the **Results** table will be expanded except those that have :code:`Passed`.
This behavior can be customized either with a query parameter: :code:`?collapsed=Passed,XFailed,Skipped`
or by setting the :code:`render_collapsed` in a configuration file (pytest.ini, setup.cfg, etc).
.. code-block:: ini
[pytest]
render_collapsed = True
**NOTE:** Setting :code:`render_collapsed` will, unlike the query parameter, affect all statuses.
The formatting of the timestamp used in the :code:`Durations` column can be modified by setting :code:`duration_formatter`
on the :code:`report` attribute. All `time.strftime`_ formatting directives are supported. In addition, it is possible
to supply :code:`%f` to get duration milliseconds. If this value is not set, the values in the :code:`Durations` column are
displayed in :code:`%S.%f` format where :code:`%S` is the total number of seconds a test ran for.
Below is an example of a :code:`conftest.py` file setting :code:`duration_formatter`:
.. code-block:: python
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
setattr(report, "duration_formatter", "%H:%M:%S.%f")
**NOTE**: Milliseconds are always displayed with a precision of 2
.. _ansi2html: https://pypi.python.org/pypi/ansi2html/
.. _Content Security Policy (CSP): https://developer.mozilla.org/docs/Web/Security/CSP/
.. _JSON: https://json.org/
.. _pytest-metadata: https://pypi.python.org/pypi/pytest-metadata/
.. _time.strftime: https://docs.python.org/3/library/time.html#time.strftime

10
tox.ini
View File

@ -4,7 +4,7 @@
# and then run "tox" from this directory.
[tox]
envlist = py{36,37,38,39,py3}, linting
envlist = py{36,37,38,39,py3}, docs, linting
isolated_build = True
[testenv]
@ -43,6 +43,14 @@ basepython = {[testenv:devel]basepython}
pip_pre = {[testenv:devel]pip_pre}
deps = {[testenv:devel]deps}
[testenv:docs]
# NOTE: The command for doc building was taken from readthedocs documentation
# See https://docs.readthedocs.io/en/stable/builds.html#understanding-what-s-going-on
basepython = python
changedir = docs
deps = sphinx
commands = sphinx-build -b html . _build/html
[testenv:packaging]
description =
Do packaging/distribution. If tag is not present or PEP440 compliant upload to