Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
buddly27 committed Oct 11, 2024
1 parent 7f0593f commit bdd7575
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 52 deletions.
28 changes: 25 additions & 3 deletions doc/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ API Reference
pytest_discover_tests(NAME
[WORKING_DIRECTORY dir]
[TRIM_FROM_NAME pattern]
[TRIM_FROM_FULL_NAME pattern]
[LIBRARY_PATH_PREPEND path1 path2...]
[PYTHON_PATH_PREPEND path1 path2...]
[ENVIRONMENT env1 env2...]
[DEPENDS target1 target2...]
[INCLUDE_FILE_PATH]
[STRIP_PARAM_BRACKETS]
[BUNDLE_TESTS]
)
Expand All @@ -35,11 +37,21 @@ API Reference
Specify the directory in which to run the :term:`Pytest` command. If
this option is not provided, the current source directory is used.

* ``INCLUDE_FILE_PATH``

Include the file path of each collected :term:`Pytest` test into its generated
test name. This helps distinguish tests with the same class or function names
by including their source file for clearer identification::

pytest_discover_tests(
...
INCLUDE_FILE_PATH
)

* ``TRIM_FROM_NAME``

Specify a `regular expression
<https://en.wikipedia.org/wiki/Regular_expression>`_ to trim part of the
class, method and function names discovered before creating the test.
Specify a :term:`regular expression` to trim part of each
class, method and function name discovered before creating the test.
This option can be used to trim the convention prefix required by
:term:`Pytest` for discovery::

Expand All @@ -48,6 +60,16 @@ API Reference
TRIM_FROM_NAME "^(Test|test_)"
)

* ``TRIM_FROM_FULL_NAME``

Specify a :term:`regular expression` to trim parts of the full test name
generated::

pytest_discover_tests(
...
TRIM_FROM_FULL_NAME "(Test|test_)"
)

* ``STRIP_PARAM_BRACKETS``

Remove square brackets added to the test identifier when using
Expand Down
24 changes: 12 additions & 12 deletions doc/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,6 @@ Glossary

.. seealso:: https://cmake.org/cmake/help/latest/command/add_test.html

Boost
Set of C++ libraries providing features complementary from the standard
library.

.. seealso:: https://www.boost.org/

Boost Python
Component library from :term:`Boost` which is a framework for
interfacing Python and C++.

.. seealso:: https://wiki.python.org/moin/boost.python

CMake
CMake is a compilation configuration platform that manages the build
process in an operating system and in a compiler-independent manner.
Expand Down Expand Up @@ -50,13 +38,25 @@ Glossary

.. seealso:: https://docs.pytest.org/en/latest/explanation/fixtures.html

nanobind
Nanobind is a fast, minimalistic C++ library designed to create Python
bindings for C++ code.

.. seealso:: https://nanobind.readthedocs.io/en/latest/index.html

parametrizing tests
Parameterized tests in :term:`Pytest` enable the execution of a single test function
with multiple sets of input parameters, facilitating the evaluation of different
test cases within a unified test structure.

.. seealso:: https://docs.pytest.org/en/stable/how-to/parametrize.html

regular expression
A regular expression is a sequence of characters that defines a search pattern,
typically used for pattern matching and manipulation within strings.

.. seealso:: https://en.wikipedia.org/wiki/Regular_expression

Pip
Pip is a package-management system written for Python.

Expand Down
11 changes: 6 additions & 5 deletions doc/integration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ able to discover the newly installed configuration automatically using its
option should not be set to False.

When using a Python virtual environment, or if Python is installed in a
non-standard location, the :envvar:`CMAKE_PREFIX_PATH` environment variable
non-standard location, the :envvar:`Pytest_ROOT` environment variable
(or :term:`CMake` option) can be used to guide the discovery process::

cmake -S . -B ./build -D "CMAKE_PREFIX_PATH=/path/to/python/prefix"
cmake -S . -B ./build -D "Pytest_ROOT=/path/to/python/prefix"

This is also necessary when installing the configuration in the
`Python user directory
Expand All @@ -61,10 +61,11 @@ Building and testing example project

An example project has been made available to test the configuration.

Ensure that a minimal version of :term:`Boost Python` is available, and
install :term:`Pytest` with its :term:`CMake` configuration as described in the
:ref:`previous section <installing>`. Then build the example::
Ensure that :term:`nanobind` is available, and install :term:`Pytest` with its
:term:`CMake` configuration as described in the :ref:`previous section <installing>`.
Then build the example::

export nanobind_ROOT=$(python -m nanobind --cmake_dir)
cmake -S ./example -B ./build
cmake --build ./build

Expand Down
23 changes: 21 additions & 2 deletions doc/release/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ Release Notes

.. release:: Upcoming

.. change:: new

Added ``INCLUDE_FILE_PATH`` option to the :func:`pytest_discover_tests`
function use the file path to compute the test identifier.

.. seealso:: :ref:`tutorial/function`

.. change:: new

Added ``TRIM_FROM_FULL_NAME`` option to the :func:`pytest_discover_tests`
function trim parts of the full test name generated.

.. seealso:: :ref:`tutorial/function`

.. change:: fixed

Fixed the ``BUNDLE_TESTS`` option to the :func:`pytest_discover_tests`
function which was poorly implemented.

.. change:: changed

Replace Boost.Python with nanobind for the example module.
Expand All @@ -17,7 +36,7 @@ Release Notes

.. change:: new

Added ``STRIP_PARAM_BRACKETS`` argument to the :func:`pytest_discover_tests`
Added ``STRIP_PARAM_BRACKETS`` option to the :func:`pytest_discover_tests`
function to strip square brackets used for :term:`parametrizing tests`.

.. seealso:: :ref:`tutorial/function`
Expand Down Expand Up @@ -160,7 +179,7 @@ Release Notes

.. change:: new

Added ``ENVIRONMENT`` argument to the :func:`pytest_discover_tests`
Added ``ENVIRONMENT`` option to the :func:`pytest_discover_tests`
function to provide custom environment variables during the tests.

.. seealso:: :ref:`tutorial/function`
Expand Down
109 changes: 81 additions & 28 deletions doc/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
Tutorial
********

Once :ref:`integrated in your project <integration>`, the ``Pytest::Pytest``
Once :ref:`integrated into your project <integration>`, the ``Pytest::Pytest``
target and the :func:`pytest_discover_tests` function are available for using.

.. _tutorial/target:

Using the target
================

Let's consider a project which wraps C++ logic with Python bindings. We need to
add a :file:`CMakeLists.txt` configuration file to add Python tests within the
same directory. The :term:`Pytest` command can be easily implemented using the
:term:`add_test` function:
Let's consider a project that wraps C++ logic with Python bindings. We need to
add a :file:`CMakeLists.txt` configuration file to include Python tests within
the same directory. The :term:`Pytest` command can easily be implemented using
the :term:`add_test` function:

.. code-block:: cmake
Expand All @@ -25,7 +25,7 @@ same directory. The :term:`Pytest` command can be easily implemented using the
)
For the tests to run, the :envvar:`PYTHONPATH` environment variable must be
updated to locate the built package library. We can use an expression generator
updated to locate the built package library. We can use a generator expression
to resolve the path of the dependent target directory dynamically:

.. code-block:: cmake
Expand Down Expand Up @@ -53,7 +53,7 @@ location should be provided:
platform. :envvar:`LD_LIBRARY_PATH` is used on Linux,
:envvar:`DYLD_LIBRARY_PATH` on macOS, and :envvar:`PATH` on Windows.

After building the project, the command can then be executed by :term:`CTest`.
After building the project, the tests can then be executed using :term:`CTest`.
If all tests are successful, the output will look as follows:

.. code-block:: console
Expand All @@ -74,7 +74,7 @@ as failed.
Using the function
==================

A :func:`pytest_discover_tests` function is provided to create :term:`CTest`
A :func:`pytest_discover_tests` function is provided to create :term:`CMake`
tests for each Python test collected. Therefore, the configuration added in the
previous section could be replaced by the following:

Expand All @@ -86,65 +86,118 @@ previous section could be replaced by the following:
$<TARGET_FILE_DIR:MyLibrary>
PYTHON_PATH_PREPEND
$<TARGET_FILE_DIR:MyLibrary>
TRIM_FROM_NAME "^test_"
DEPENDS MyLibrary
)
This will create a new **PythonTest** target, dependent on the **MyLibrary**
target.

The expected environment can be defined simply with the ``LIBRARY_PATH_PREPEND``
and ``PYTHON_PATH_PREPEND`` arguments, which both accept multiple values. The
and ``PYTHON_PATH_PREPEND`` options, which both accept multiple values. The
environment variable used to locate shared libraries will be automatically
chosen according to the platform.

Pytest usually requires tests to start with a
A list of dependent targets can be defined with the ``DEPENDS`` option, which
accepts multiple values.

After building the project, running :term:`CTest` will display the tests as
follows:

.. code-block:: console
Start 1: PythonTest.test_greet_world
1/4 Test #1: PythonTest.test_greet_world ........... Passed 0.47 sec
Start 2: PythonTest.test_greet_john
2/4 Test #2: PythonTest.test_greet_john ............ Passed 0.47 sec
Start 3: PythonTest.test_greet_julia
3/4 Test #3: PythonTest.test_greet_julia ........... Passed 0.47 sec
Start 4: PythonTest.test_greet_michael
4/4 Test #4: PythonTest.test_greet_michael ......... Passed 0.54 sec
A fully identified test collected by :term:`Pytest` might look like this:

.. code-block:: console
tests/test_module.py::TestMyClass::test_example
By default, only the class and function name of each :term:`Pytest` test collected
are used to create the :term:`CMake` tests. You can use the ``INCLUDE_FILE_PATH``
option to include the file path within the name:

.. code-block:: cmake
:emphasize-lines: 7
pytest_discover_tests(
PythonTest
LIBRARY_PATH_PREPEND
$<TARGET_FILE_DIR:MyLibrary>
PYTHON_PATH_PREPEND
$<TARGET_FILE_DIR:MyLibrary>
INCLUDE_FILE_PATH
DEPENDS MyLibrary
)
Pytest usually requires the test class and function to start with a
`specific prefix
<https://docs.pytest.org/en/latest/explanation/goodpractices.html>`_,
which can be trimmed using the ``TRIM_FROM_NAME`` argument. The value can use a
`regular expression <https://en.wikipedia.org/wiki/Regular_expression>`_ to
match the part of the test name that should be trimmed.
which can be trimmed using the ``TRIM_FROM_NAME`` or ``TRIM_FROM_FULL_NAME``
options. The value can use a :term:`regular expression` to match the part of
the test name that should be trimmed.

A list of dependent targets can be defined with the ``DEPENDS`` argument, which
accepts multiple values.
The ``TRIM_FROM_FULL_NAME`` option can be used to trim parts of the entire name,
while the ``TRIM_FROM_NAME`` option will be applied to the class, method and
function name of each :term:`Pytest` test collected for convenience.

After building the project, running :term:`CTest` will display the tests as
.. code-block:: cmake
:emphasize-lines: 7
pytest_discover_tests(
PythonTest
LIBRARY_PATH_PREPEND
$<TARGET_FILE_DIR:MyLibrary>
PYTHON_PATH_PREPEND
$<TARGET_FILE_DIR:MyLibrary>
TRIM_FROM_NAME "^(Test|test_)"
INCLUDE_FILE_PATH
DEPENDS MyLibrary
)
After rebuilding the project, running :term:`CTest` will display the tests as
follows:

.. code-block:: console
Start 1: PythonTest.greet_world
1/4 Test #1: PythonTest.greet_world ........... Passed 0.47 sec
1/4 Test #1: PythonTest.greet_world ............... Passed 0.47 sec
Start 2: PythonTest.greet_john
2/4 Test #2: PythonTest.greet_john ............ Passed 0.47 sec
2/4 Test #2: PythonTest.greet_john ................ Passed 0.47 sec
Start 3: PythonTest.greet_julia
3/4 Test #3: PythonTest.greet_julia ........... Passed 0.47 sec
Start 4: PythonTest.greet_michael
4/4 Test #4: PythonTest.greet_michael ......... Passed 0.54 sec
3/4 Test #3: PythonTest.greet_julia ............... Passed 0.47 sec
Start 4: PythonTest.subfolder.greet_michael
4/4 Test #4: PythonTest.subfolder.greet_michael ... Passed 0.54 sec
It is also possible to regroup all tests under one :term:`CTest` test, as
was the case when :ref:`using the target <tutorial/target>`. This can be
useful during development to ensure that the tests run faster, especially
if you use :term:`fixtures <fixture>` with a broader scope.

This can be done by setting the ``BUNDLE_TESTS`` argument to True:
This can be done by setting the ``BUNDLE_TESTS`` option to True:

.. code-block:: cmake
:emphasize-lines: 9
:emphasize-lines: 8
pytest_discover_tests(
PythonTest
LIBRARY_PATH_PREPEND
$<TARGET_FILE_DIR:MyLibrary>
PYTHON_PATH_PREPEND
$<TARGET_FILE_DIR:MyLibrary>
TRIM_FROM_NAME "^test_"
DEPENDS MyLibrary
BUNDLE_TESTS True
)
After re-building the project, running :term:`CTest` will display the tests as
follows:
After rebuilding the project once again, running :term:`CTest` will display the
tests as follows:

.. code-block:: console
Expand All @@ -154,5 +207,5 @@ follows:
.. note::

The :envvar:`BUNDLE_PYTHON_TESTS` environment variable can also set this
argument dynamically.
option dynamically.

3 changes: 1 addition & 2 deletions example/src/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ nanobind_add_module(pyFoo main.cpp)
set_target_properties(pyFoo
PROPERTIES
PREFIX ""
SUFFIX ".so"
OUTPUT_NAME foo
)

if(WIN32)
set_target_properties(pyFoo PROPERTIES SUFFIX ".pyd")
elseif(APPLE)
set_target_properties(pyFoo PROPERTIES SUFFIX ".so")
endif()

target_link_libraries(pyFoo PUBLIC foo)
Expand Down

0 comments on commit bdd7575

Please sign in to comment.