Development¶
This page covers how to set up a development environment and run the test suite when contributing to PyKED.
Installing for development¶
Clone the repository and install in editable mode with all developer dependencies:
git clone https://github.com/pr-omethe-us/PyKED
cd PyKED
pip install -e . --group all
Running the tests¶
PyKED uses a two-tier test structure: a fast, fully-mocked default suite and a separate set of live API contract tests that verify the mocks stay accurate.
Default suite¶
All tests in the default suite use mock responses for the Crossref and ORCID external APIs, so they run offline and at full speed:
pytest # run all tests
pytest --cov=pyked # with coverage report
pytest -v # verbose output
Live API contract tests¶
A separate set of tests marked live_api call the real Crossref and ORCID APIs to confirm
that the mock data in tests/_mock_data.py still matches actual responses. These are excluded
from the default run to keep CI reliable:
pytest -m live_api -v
You can also narrow the scope:
pytest -m live_api -v -k "Crossref" # Crossref contract tests only
pytest -m live_api -v -k "Orcid" # ORCID contract tests only
These contract tests run automatically every Monday at 06:00 UTC via GitHub Actions. If the
weekly run fails, the mock data likely needs updating — compare the failure output against the
entries in tests/_mock_data.py and update as needed.
Adding new API-dependent tests¶
If you add a test that loads a ChemKED file with a DOI or author ORCID, the validation layer will call the Crossref and/or ORCID APIs. Rather than hitting the real APIs, extend the mocks:
Add your DOI’s expected response to
CROSSREF_RESPONSESintests/_mock_data.py.Add any ORCID identifiers to
ORCID_RESPONSESin the same file.Apply the appropriate fixture to your test:
mock_crossref_api— patches Crossref onlymock_orcid_api— patches ORCID onlymock_all_apis— patches both (preferred for most cases)
Example:
def test_my_new_feature(self, mock_all_apis):
c = ChemKED(yaml_file="tests/my_new_file.yaml")
assert c.reference.doi == "10.xxxx/my.doi"
The mock data is also what the live contract tests compare against, so adding the entry to
_mock_data.py simultaneously keeps both the unit test mocks and the contract tests correct.