Testing and contributing¶
Running the tests¶
pip install -e ".[test]"
pytest tests/ -q
or, with nothing but the standard library:
python -m unittest discover -s tests -t . -v
The tests are unittest classes so that both runners work. That matters
because most of them need nothing installed: mainprogram --help, the
configuration loader, input.in, the tracking-file reader, the Quantum
ESPRESSO text handling and the whole command dispatcher are checked on a machine
with no pymatgen, no ase and no cluster. Anything that genuinely needs a
scientific package is skipped with a message naming it, rather than erroring.
File |
What it pins |
|---|---|
|
the search order, the deep merge over the packaged default,
|
|
|
|
the QE reader: |
|
tracking files ( |
|
every command’s dispatch, the plot-type loop, exit codes, the help blocks |
|
every module imports, and nothing reads a file at import time |
|
the shims, the entry points, no committed API key, no |
|
one test per defect from the review, each naming the original symptom |
|
the documentation cannot name a command that does not exist, cannot tell
the reader to run the destructive process |
|
the tutorial catalogue, tied to the dispatcher |
The other checks¶
python tools/check_names.py htesp tutorials tests # undefined-name scan
python tools/gen_command_rst.py --check # docs/command.rst is current
python docs/gen_param_block.py --check # the config block in param.rst
python docs/check_docs.py # the documentation checks
python -m unittest tutorials.selftest # the tutorial runner alone
tools/check_names.py is a small standard-library substitute for pyflakes
for machines where ruff cannot be installed. It catches the one class of
defect that bit this package repeatedly: a name used at module or function scope
that is never bound anywhere.
Generated pages¶
Two pages of this documentation are generated and must not be hand-edited.
docs/command.rst comes from htesp/help_text.py – the same constants
mainprogram basicinfo, process-info, epw-info and wt-info print.
Change the help text and regenerate:
python tools/gen_command_rst.py
The full config.json listing in docs/param.rst, between the
.. config-json-start and .. config-json-end comments, comes from
htesp/data/config.json:
python docs/gen_param_block.py
Both have a --check mode that exits non-zero when the file on disk is stale,
and tests/test_docs.py runs the first of them.
Checking the docs¶
docs/check_docs.py is the documentation lint that does not need Sphinx
installed. It checks that
every
.. code-block:: jsonbody parses as JSON and every.. code-block:: pythonbody compiles;every
:ref:and:doc:target exists;no label is defined twice;
every page named in a
toctreeexists, and every page is reachable fromindex.rst;every
mainprogram <name>in the prose is a real command or process, ashtesp/help_text.pylists them;every repository path mentioned in a literal exists in the tree;
no real-looking Materials Project API key has crept back in.
python docs/check_docs.py # report and exit non-zero on problems
python docs/check_docs.py -v # also list what it checked
Build the HTML with Sphinx when it is available:
pip install -e ".[docs]"
cd docs && make html
Conventions¶
A test that pins a fix names the original symptom, in its docstring or in its name. A test that only asserts current behaviour tells a later reader nothing about why it exists; a test that says “process 20 is
clean-scan, and the tutorial used to tell the reader to run it for the partial DOS” tells them everything.tests/helpers.pyhasTempProject, which gives each test a throw-away project directory, makes it current, and clears$HTESP_CONFIG,$MP_API_KEYand the configuration cache. A stale value in a developer’s shell would otherwise defeat the configuration tests.Negative source assertions go through
code_only(), which strips comments and strings. Every fix carries a# FIX(n):comment naming the old pattern, so a naive “the old pattern is gone” check would match the comment itself.Documentation follows the code, not the other way round. If a page is wrong because a command was renamed, fix the help text and regenerate; if it is wrong because the prose is wrong, fix the prose and add the wrong name to
tests/test_docs.pyso it cannot come back.Never commit an API key.
tests/test_packaging.pychecks for one.
Who to contact¶
See Contribution.