Skip to content

Commit

Permalink
Major rework of docs
Browse files Browse the repository at this point in the history
Signed-off-by: Andreas Maier <andreas.r.maier@gmx.de>
  • Loading branch information
andy-maier committed Mar 30, 2021
1 parent ed83f9d commit 171e37b
Show file tree
Hide file tree
Showing 18 changed files with 234 additions and 660 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -558,11 +558,11 @@ safety_$(python_pymn_version).done: develop_reqs_$(python_pymn_version).done Mak
test: develop
ifeq ($(python_mn_version),3.4)
@echo "Makefile: Running unit tests (without coverage)"
pytest --color=yes $(pytest_warning_opts) $(pytest_opts) $(test_dir)/unittest -s
pytest --color=yes $(pytest_warning_opts) $(pytest_opts) $(test_dir)/unittest -s --es-server-file $(test_dir)/unittest/server.yml --es-vault-file $(test_dir)/unittest/vault.yml
@echo "Makefile: Done running unit tests (without coverage)"
else
@echo "Makefile: Running unit tests (with coverage)"
coverage run --source=$(package_name) --rcfile=.coveragerc -m pytest --color=yes $(pytest_warning_opts) $(pytest_opts) $(test_dir)/unittest -s
coverage run --source=$(package_name) --rcfile=.coveragerc -m pytest --color=yes $(pytest_warning_opts) $(pytest_opts) $(test_dir)/unittest -s --es-server-file $(test_dir)/unittest/server.yml --es-vault-file $(test_dir)/unittest/vault.yml
coverage report --rcfile=.coveragerc
@echo "Makefile: Done running unit tests (with coverage)"
endif
29 changes: 24 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pytest-easy-server - Pytest plugin for testing against real servers
pytest-easy-server - Pytest plugin for easy testing against servers
===================================================================

.. image:: https://badge.fury.io/py/pytest-easy-server.svg
Expand All @@ -23,12 +23,31 @@ pytest-easy-server - Pytest plugin for testing against real servers
Overview
--------

The **pytest-easy-server** package is a `Pytest`_ plugin that provides a
`Pytest fixture`_ named `server_definition`_ that
resolves to the set of servers the tests should run against.
The **pytest-easy-server** package is a
`Pytest <https://docs.pytest.org/en/stable/>`_ plugin that provides a
:func:`~pytest_easy_server.server_definition` fixture that resolves to the set
of servers the tests should run against.

The set of servers is defined in a *server definition file* and the secrets
to access the servers are defined in a *vault file*.
to access the servers are defined in a *vault file* in the formats defined
by the
`easy-server package <https://easy-server.readthedocs.io/en/stable/>`_.

The files to use and the server or group nickname to select for the test
can be specified in pytest options added by the plugin:

.. code-block:: text
--es-server-file=FILE Use the specified server definition file.
Default: server.yml in current directory.
--es-vault-file=FILE Use the specified vault file.
Default: vault.yml in current directory.
--es-nickname=NICKNAME Use the server or server group with this
nickname to test against.
Default: default server or server group
specified in the server definition file.
.. _`Documentation and change log`:
Expand Down
25 changes: 8 additions & 17 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@
API Reference
=============

This section describes the API of the pytest-easy-server package.
This section describes the API of the **pytest-easy-server** package.
The API is kept stable using the compatibility rules defined for
`semantic versioning <https://semver.org/>`_. An exception to this rule
are fixes for security issues.

Any functions not described in this section are considered internal and may
change incompatibly without warning.


.. _`server_definition fixture`:
Expand All @@ -32,19 +38,4 @@ server_definition fixture
Package version
---------------

The package version can be accessed by programs using the
``pytest_easy_server.__version__`` variable [#]_:

.. autodata:: pytest_easy_server._version.__version__

This documentation may have been built from a development level of the
package. You can recognize a development version of this package by the
presence of a ".devD" suffix in the version string. Development versions are
pre-versions of the next assumed version that is not yet released. For example,
version 0.1.2.dev25 is development pre-version #25 of the next version to be
released after 0.1.1. Version 1.1.2 is an `assumed` next version, because the
`actually released` next version might be 0.2.0 or even 1.0.0.

.. [#] For tooling reasons, that variable is shown as
``pytest_easy_server._version.__version__`` in this documentation, but
it should be accessed as ``pytest_easy_server.__version__``.
.. autodata:: pytest_easy_server.__version__
34 changes: 1 addition & 33 deletions docs/appendix.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,32 +36,6 @@ Glossary
:class:`py3:bytes` in Python 3). Unless otherwise
indicated, byte strings in this project are always UTF-8 encoded.

number
one of the number types :class:`py:int`, :class:`py2:long` (Python 2
only), or :class:`py:float`.

integer
one of the integer types :class:`py:int` or :class:`py2:long` (Python 2
only).

callable
a callable object; for example a function, a class (calling it returns a
new object of the class), or an object with a :meth:`~py:object.__call__`
method.

hashable
a hashable object. Hashability requires an object not only to be able to
produce a hash value with the :func:`py:hash` function, but in addition
that objects that are equal (as per the ``==`` operator) produce equal
hash values, and that the produced hash value remains unchanged across
the lifetime of the object. See `term "hashable"
<https://docs.python.org/3/glossary.html#term-hashable>`_
in the Python glossary, although the definition there is not very crisp.
A more exhaustive discussion of these requirements is in
`"What happens when you mess with hashing in Python"
<https://www.asmeurer.com/blog/posts/what-happens-when-you-mess-with-hashing-in-python/>`_
by Aaron Meurer.


.. _`References`:

Expand All @@ -70,12 +44,6 @@ References

.. glossary::

Pytest
`Pytest <https://docs.pytest.org/en/stable/>`_

Pytest fixtures
`Pytest Fixtures <https://docs.pytest.org/en/stable/fixture.html>`_

Python glossary
* `Python 2.7 Glossary <https://docs.python.org/2.7/glossary.html>`_
* `Python 3.4 Glossary <https://docs.python.org/3.4/glossary.html>`_
* `Python 3.9 Glossary <https://docs.python.org/3.9/glossary.html>`_
167 changes: 4 additions & 163 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def get_version(version_file):
# but since it already provides a full TOC in the navigation pane, the
# sphinxcontrib.fulltoc extension is not needed.
'sphinx_rtd_theme',
'autodocsumm',
]

# Add any paths that contain templates here, relative to this directory.
Expand All @@ -113,7 +114,7 @@ def get_version(version_file):
author = u"Andreas Maier"

# The short description of the package.
_short_description = u"Pytest plugin for testing against real servers"
_short_description = u"Pytest plugin for easy testing against servers"

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -495,6 +496,8 @@ def get_version(version_file):
'py': ('https://docs.python.org/2/', None), # agnostic to Python version
'py2': ('https://docs.python.org/2', None), # specific to Python 2
'py3': ('https://docs.python.org/3', None), # specific to Python 3
'easy_vault': ('https://easy-vault.readthedocs.io/en/stable/', None),
'easy_server': ('https://easy-server.readthedocs.io/en/stable/', None),
}

intersphinx_cache_limit = 5
Expand Down Expand Up @@ -539,166 +542,4 @@ def get_version(version_file):
# results in the link caption "this issue".

extlinks = {

}

# -- Support for autoautosummary ----------------------------------------------
#
# Idea taken from https://stackoverflow.com/a/30783465/1424462
#

class AutoAutoSummary(Autosummary):
"""
Sphinx extension that automatically generates a table of public methods or
attributes of a class, using the AutoSummary extension.
(i.e. each row in the table shows the method or attribute name with a
link to the full description, and a one-line brief description).
Usage in RST source::
.. autoclass:: path.to.class
:<autoclass-options>:
.. rubric:: Methods
.. autoautosummary:: path.to.class
:methods:
.. rubric:: Attributes
.. autoautosummary:: path.to.class
:attributes:
.. rubric:: Details
"""

option_spec = {
'methods': directives.unchanged,
'attributes': directives.unchanged
}
option_spec.update(Autosummary.option_spec)

required_arguments = 1 # Fully qualified class name

def __init__(self, *args, **kwargs):
self._logger = logging.getLogger(__name__) # requires Sphinx 1.6.1
self._log_prefix = "conf.py/AutoAutoSummary"
self._excluded_classes = ['BaseException']
super(AutoAutoSummary, self).__init__(*args, **kwargs)

def _get_members(self, class_obj, member_type, include_in_public=None):
"""
Return class members of the specified type.
class_obj: Class object.
member_type: Member type ('method' or 'attribute').
include_in_public: set/list/tuple with member names that should be
included in public members in addition to the public names (those
starting without underscore).
Returns:
tuple(public_members, all_members): Names of the class members of
the specified member type (public / all).
"""
try:
app = self.state.document.settings.env.app
except AttributeError:
app = None
if not include_in_public:
include_in_public = []
all_members = []
for member_name in dir(class_obj):
try:
documenter = get_documenter(
app,
safe_getattr(class_obj, member_name),
class_obj)
except AttributeError:
continue
if documenter.objtype == member_type:
all_members.append(member_name)
public_members = [x for x in all_members
if x in include_in_public or not x.startswith('_')]
return public_members, all_members

def _get_def_class(self, class_obj, member_name):
"""
Return the class object in MRO order that defines a member.
class_obj: Class object that exposes (but not necessarily defines) the
member. I.e. starting point of the search.
member_name: Name of the member (method or attribute).
Returns:
Class object that defines the member.
"""
member_obj = getattr(class_obj, member_name)
for def_class_obj in inspect.getmro(class_obj):
if member_name in def_class_obj.__dict__:
if def_class_obj.__name__ in self._excluded_classes:
return class_obj # Fall back to input class
return def_class_obj
self._logger.warning(
"%s: Definition class not found for member %s.%s, "
"defaulting to class %s",
self._log_prefix, class_obj.__name__, member_name,
class_obj.__name__)
return class_obj # Input class is better than nothing

def run(self):

try:
full_class_name = str(self.arguments[0])
module_name, class_name = full_class_name.rsplit('.', 1)
module_obj = __import__(module_name, globals(), locals(),
[class_name])
class_obj = getattr(module_obj, class_name)
if 'methods' in self.options:
_, methods = self._get_members(
class_obj, 'method', ['__init__'])
self.content = []
for method in methods:
if method.startswith('_'):
# Skip private methods
continue
def_class = self._get_def_class(class_obj, method)
def_module_name = def_class.__module__
if def_module_name.startswith('pytest_easy_server'):
def_module_name = def_module_name.split('.')[0]
content_str = "~%s.%s.%s" % (
def_module_name,
def_class.__name__,
method)
self.content.append(content_str)
elif 'attributes' in self.options:
_, attributes = self._get_members(class_obj, 'attribute')
self.content = []
for attrib in attributes:
if attrib.startswith('_'):
# Skip private attributes
continue
def_class = self._get_def_class(class_obj, attrib)
def_module_name = def_class.__module__
if def_module_name.startswith('pytest_easy_server'):
def_module_name = def_module_name.split('.')[0]
content_str = "~%s.%s.%s" % (
def_module_name,
def_class.__name__,
attrib)
self.content.append(content_str)

except Exception as exc:
self._logger.error(
"%s: Internal error: %s: %s",
self._log_prefix, exc.__class__.__name__, exc)

finally:
return super(AutoAutoSummary, self).run()


def setup(app):
app.add_directive('autoautosummary', AutoAutoSummary)
36 changes: 25 additions & 11 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,42 @@
.. limitations under the License.
pytest-easy-server - Pytest plugin for testing against real servers
pytest-easy-server - Pytest plugin for easy testing against servers
*******************************************************************

The **pytest-easy-server** package is a `Pytest`_ plugin that provides a
`Pytest fixture`_ named :func:`~pytest_easy_server.server_definition` that
resolves to the set of servers the tests should run against.
The **pytest-easy-server** package is a
`Pytest <https://docs.pytest.org/en/stable/>`_ plugin that provides a
:func:`~pytest_easy_server.server_definition` fixture that resolves to the set
of servers the tests should run against.

The set of servers is defined in a *server definition file* and the secrets
to access the servers are defined in a *vault file*.
to access the servers are defined in a *vault file* in the formats defined
by the
`easy-server package <https://easy-server.readthedocs.io/en/stable/>`_.

The files to use and the server or group nickname to select for the test
can be specified in pytest options added by the plugin:

.. code-block:: text
--es-server-file=FILE Use the specified server definition file.
Default: server.yml in current directory.
--es-vault-file=FILE Use the specified vault file.
Default: vault.yml in current directory.
--es-nickname=NICKNAME Use the server or server group with this
nickname to test against.
Default: default server or server group
specified in the server definition file.
.. toctree::
:maxdepth: 2
:numbered:

intro.rst
usage.rst
api.rst
development.rst
appendix.rst
changes.rst

.. # Links to documentation:
.. _`Pytest`: https://docs.pytest.org/en/stable/
.. _`Pytest fixture`: https://docs.pytest.org/en/stable/fixture.html

0 comments on commit 171e37b

Please sign in to comment.