From c8eb53631f686621d93a8b56395ce66ae3d71825 Mon Sep 17 00:00:00 2001 From: Israel Martinez Date: Tue, 7 May 2024 10:28:51 -0400 Subject: [PATCH] Unit tests in docs --- docs/dev/index.rst | 8 ++++++ docs/dev/unit_tests.rst | 63 +++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 2 ++ 3 files changed, 73 insertions(+) create mode 100644 docs/dev/index.rst create mode 100644 docs/dev/unit_tests.rst diff --git a/docs/dev/index.rst b/docs/dev/index.rst new file mode 100644 index 00000000..7d57e358 --- /dev/null +++ b/docs/dev/index.rst @@ -0,0 +1,8 @@ +For developers +============== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + unit_tests diff --git a/docs/dev/unit_tests.rst b/docs/dev/unit_tests.rst new file mode 100644 index 00000000..d439d520 --- /dev/null +++ b/docs/dev/unit_tests.rst @@ -0,0 +1,63 @@ +Unit tests +---------- + +An unit tests verified that a modules, a class or a method is working as expected. As opposed to integration and functional tests, they should be as specific as possible, attempting to isolate small blocks of code --i.e. one function at a time. The main goals for unit tests are: + + - Confirm that cosipy was succesfully installed. + - Catch pull request that break previous code and prevent maintainer from merging them. + +We are working towards having 100% unit test coverage. That means that all lines of code are run at least by one unit test. New pull request that reduce the coverge percentage should not be merge until this is remedied by adding new tests. + +Running unit tests +^^^^^^^^^^^^^^^^^^ + +Install ``pytest`` and ``pytest-cov`` with:: + + pip pytest pytest-cov + +Go to the root folder of your local working repository, the one containing the folder ``tests``. You need to clone the repository, as opposed to installing cosipy with ``pip``. + +Run:: + + pytest --cov=cosipy --cov-report term --cov-report html:tests/cov + +The last line of the report will tell you how many test failed (if any), how many passed, and how many warnings were generated. + +Open ``tests/cov/index.html`` in a browser and check the coverage. This +is the percentage of lines that were executed during the tests. The goal is to have +a 100% coverage! + +Adding a test +^^^^^^^^^^^^^ + +The pytest library automatically looks inside the ``tests`` folder for function starting with the word ``test`` inside files starting with the word ``test``. Subfolder inside the ``tests`` folder need to contain a file called ``__init__.py`` (can be empty) in order to be picked up. + +Each ``test*`` function constitutes a test. If they are run without any errors or exception, the pytest considers that the test was suscessful, independently of the return value. Use the builtin ``asssert`` keyword to compare a result to an expected value:: + + from cosipy import test_data + from cosipy.response import FullDetectorResponse + + def test_get_effective_area(): + + response_path = test_data.path/"test_full_detector_response.h5" + + with FullDetectorResponse.open(response_path) as response: + + assert response[0].ndim == 6 + +The ``assert`` method will raise an exception if the result from the operation on the right return ``False``. + +For some tests you might need a dataset. When that's the case, add your files to the ``cosipy/test_data`` folder, which the tests can find by calling ``cosipy.test_data.path``, as shown in the example above. Use the smallest file size possible required by your test. Remember that for an unit test you do not need a full-fledge data file. Instead, mock data and small subsets are enough to test the algorithms, even if they don't result in realistic outputs or with good scientific quality. Full-fledge data might be needed for integration and functional test, but those will be handled separetly using data outside the cosipy respository. + + + + + + + + + + + + + diff --git a/docs/index.rst b/docs/index.rst index a753e177..a9a910a5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -34,3 +34,5 @@ The preferred communication channel is the GitHub repository:: if you find a pro tutorials/index tutorials/other_examples api/index + dev/index +