From f1e0ffe387ba43ef7e21526976a388d6fa15dde2 Mon Sep 17 00:00:00 2001 From: Shurong Cao <170531907+CAOShurong@users.noreply.github.com> Date: Wed, 9 Sep 2026 22:27:08 +0800 Subject: [PATCH] docs: document model fixture discovery and snapshot recreation workflow --- tests/_data/snapshots/README.md | 57 +++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/tests/_data/snapshots/README.md b/tests/_data/snapshots/README.md index f97432444..b79bfc6be 100644 --- a/tests/_data/snapshots/README.md +++ b/tests/_data/snapshots/README.md @@ -1,13 +1,52 @@ -# TEST FIXTURES +# Test Fixtures & Snapshot Workflow -## RE-CREATION +This directory contains serialized test snapshots (in JSON and XML formats) used to verify serialization and deserialization across supported CycloneDX schema versions. -Some assets here can be (re-)created automatically, by setting the env var `CDX_TEST_RECREATE_SNAPSHOTS=1`. -It might also help to set `PYTHONHASHSEED=0`! -As a shortcut just run: +## How Model Fixtures Are Discovered -```shell -CDX_TEST_RECREATE_SNAPSHOTS=1 poetry run tox -e py -``` +Model factories are declared in [`tests/_data/models.py`](../models.py) and discovered dynamically at test runtime: -The files will be written as is, which might not be human-readable. feel free to reformat the files manually. +1. **Factory Discovery**: + - Any function named `get_bom_*()` is automatically discovered via `inspect.getmembers(sys.modules[__name__], isfunction)`. + - Valid factories are categorized into `all_get_bom_funct_valid`, `all_get_bom_funct_valid_immut`, and `all_get_bom_funct_valid_reversible_migrate`. + - Factories suffixed with `_invalid` are collected into `all_get_bom_funct_invalid`. These represent intentionally malformed or non-compliant models tested against error-handling and schema validation failure paths. + +2. **Schema Version Constraints**: + - If a factory function name contains a version tag (e.g. `get_bom_v1_5_*`), `is_valid_for_schema_version()` checks it against `_LIMIT_GET_BOM_BY_VERSION_REGEX` (`^get_bom_(?Pv(?P1)_(?P[0-6]))?(.*)$`). + - Such factories are only executed against schema versions equal to or greater than the specified version. + +3. **Snapshot Naming**: + - Snapshot filenames are generated by `mksname(purpose, sv, f)` in [`tests/__init__.py`](../../__init__.py): + ```text + -.[.bin] + ``` + For example: `get_bom_with_licenses-1.5.json.bin` or `get_bom_with_services_simple-1.4.xml.bin`. + +4. **Incomplete Dependency Graphs**: + - Functions in `all_get_bom_funct_with_incomplete_deps` return BOMs where dependency graphs are deliberately incomplete. + - These test that serialization properly repairs or normalizes hanging references before outputting. + +--- + +## Re-creation Workflow + +When adding a new model factory or intentionally updating serialization output, snapshots must be regenerated: + +1. **Regenerate Snapshots**: + Set `CDX_TEST_RECREATE_SNAPSHOTS=1` and `PYTHONHASHSEED=0` to ensure deterministic output: + ```shell + CDX_TEST_RECREATE_SNAPSHOTS=1 PYTHONHASHSEED=0 poetry run tox -e py + ``` + Or target specific test files: + ```shell + CDX_TEST_RECREATE_SNAPSHOTS=1 PYTHONHASHSEED=0 poetry run pytest tests/test_output_json.py tests/test_output_xml.py + ``` + +2. **Review Diff**: + Inspect `git diff tests/_data/snapshots/` to confirm that **only** the intended snapshots were created or modified. Discard accidental changes with `git checkout tests/_data/snapshots/`. + +3. **Verify with Snapshot Re-creation Disabled**: + Always rerun tests without `CDX_TEST_RECREATE_SNAPSHOTS` to verify that serialization matches the recorded snapshots and that deserialization tests (`test_deserialize_json.py`, `test_deserialize_xml.py`) pass cleanly: + ```shell + poetry run tox -e py + ```