Testing Practices#
Edgegraph follows a strict rule of unit testing and code coverage. *All code* is to be covered by unit testing, with exceptions only made for cases which are well and truly needed (and justification is documented). The brilliant PyTest framework is used to drive unit testing, and Coverage.py provides coverage analysis. pytest-cov links the two together, and pytest-randomly is also employed to ensure order of unit tests does not impact the tests.
Tests are written in the tests/ directory of the project, and are not
bundled with the module to end users. Nonetheless, standards for documentation
and code quality are enforced on all unit tests. The entire directory is
scanned with PyLint on all GitHub pull requests.
Running tests#
From the command line, you can run all tests with a simple pytest command issued from the project root. Ideally, all tests will be executed and pass. PyTest can be integrated with numerous IDEs probably including yours, though configuring that is outside the scope of this documentation (probably found in your IDE docs).
By default, some slower stress tests will be executed as well. These tests are
marked as slow, and can be excluded by passing -m "not slow" as an argument
to PyTest, for example pytest -m "not slow". This flag is set in the
GitHub actions invocation of tests, and therefore, 100% code coverage must be
achieved without slow testing.
Coverage analysis#
The included scripts/ut_cov.sh shell script executes all unit tests and
performs coverage analysis. The invocation used here is identical to that in
the GitHub actions pipeline; therefore, this script accurately matches the
behavior of the pipeline. This is useful for testing changes locally before
pushing to GitHub.
The script places an HTML report in the docs/_build/htmlcov folder; after
running it, open docs/_build/htmlcov/index.html in your browser to see
results in an interactive format showing exactly what lines / branches were
missed.
Writing tests#
Writing unit tests is an essential part of adding, changing, or removing
functionality from EdgeGraph. Organization of the tests closely mirrors
organization of the sourcecode they test, and all tests relevant to any given
module should be in a test subdirectory easily apparent to match the code which
it tests. An extra test subdirectory, tests.integration, is used for
testing activities which combine functionality of multiple sourcecode modules.
The following testing practices are kept:
Unit tests should be kept relatively small where possible (i.e., they should test “a single unit of code.”)
All assertions are provided a message to indicate in plain English what failed, should the assertion fail
All unit tests must provide at least a short docstring to summarize what the test tests.
All test modules must provide at least a short docstring to summarize the overall topic of the tests contained.
PyLint messages may be ignored at the module level, if needed. Justification must be provided in a code comment near to the pylint disable flag. (This is NOT a freebie to write bad code – only ignore messages that are truly unavoidable. W0212 is a common offender.)
For convenience and code cleanliness, test authors may wish to familiarize
themselves with the tests.conftest module. This module contains
PyTest fixtures available to all test modules (automatically, no import
needed!). Commonly-used graph constructors can be found here. See the module
documentation for more info.
Test List#
You can find an API-like summary & description of all unit tests here:
Contains unit, integration, and interactive tests for EdgeGraph. |