Consolidate the test harness and add coverage measurement #62
No reviewers
Labels
No labels
area/deployment
area/governance
area/metadata
area/pipeline
area/search
type/data
type/design
type/implementation
type/testing
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Arkive/arkive!62
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feature/issue-60-test-harness-consolidation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
src/arkive/metadata_validation.py, keepingpipeline/validate/validate_records.pyas a thin CLI wrapper so the documented command still works.tests/support.pywith the shared helpers, removing thespec_from_file_locationbootstrap from three test modules, the four borrowedvariantbindings, and the hand-rolledDATA_DIRsave-and-restore.coverage.pywith branch coverage enabled, documented as a command indocs/development.mdwith no percentage embedded there.The audit
The validator began at 89% statement and branch coverage: 38 uncovered statements and 30 partial branches.
Every one proved to be reachable behaviour with no regression test. No dead code was found. The one genuinely unreachable rule this project has had was the evidence check removed under Issue #44, and it was already gone.
Verdicts by group, using the four categories agreed on this issue:
source_id,document_id,rights_idderived_fromreferencing unknown document; document derived from itselfrejection_reason_load_jsonreturningNonefor a vanished fileResult:
src/arkive/metadata_validation.pyis now at 100% statement and branch coverage.Repository total is 95%. The remainder is
file_integrity.pyat 85% andpdf_text.pyat 90%, recorded here as the baseline rather than audited — this issue's criterion covers validator branches, and those modules deserve their own pass rather than a drive-by.Baseline figures
Recorded here rather than in
docs/development.md, since a percentage in stable documentation is stale the moment it is written.Acceptance criteria
spec_from_file_locationwhere a normal import is possible — every test module now importsarkive.metadata_validation, directly or throughtests/support.py. No file-path loading remains anywhere intests/.variant = AcquisitionContractTests.variantbindings are replaced byValidatorTestCase.fixture_variant.support.core_store()andValidatorTestCase.use_core_store()both usemock.patch.object, which restores on exception.branch = trueandshow_missing = trueinpyproject.toml; command documented indocs/development.md.docs/development.mddocuments how to run coverage and deliberately carries no percentage.AGENTS.mdanddocs/development.mddescribe the actual commands — both updated, including the validator's new location and the wrapper's role.unittestremains canonical; no pytest, no pytest-cov.Verification
git diff --checkpython pipeline/validate/validate_records.py— PASS, committed corpus unchangedpython -m unittest discover -s tests -v— 208 tests passingpython -m ruff check src pipeline testspython -m ruff format --check src pipeline testspython -m pip checkpython -m coverage run -m unittest discover -s teststhenreportPoints for reviewer attention
The documented command is tested as a subprocess. The real risk in this refactor is that
pipeline/validate/validate_records.pyquietly stops being runnable while every import-based test still passes.DocumentedCommandTeststherefore invokes it withsubprocess.runexactly as the docs instruct, covering the corpus run,--help, and the missing-path exit code.One limitation introduced, and deliberately not solved.
REPO_ROOTis still derived from__file__, which is correct for a source checkout and for the documented editable install but would not be for a non-editable install, wheremeta/schemaswould need shipping as package data. There is no such distribution yet and[project.scripts]is still empty, so solving it now would be speculative. It is recorded as a comment at the constant.The
_load_jsonmissing-file branch is tested directly, calling the private helper. It is reachable only if a record disappears between discovery and loading, which cannot be produced reliably through the public interface. Calling the helper seemed better than leaving a defensive path unexercised or deleting a guard that protects against a real race.file_integrity.pyandpdf_text.pywere not audited. Their figures are recorded as the baseline. Both are worth a pass, but folding them in here would have widened the change well past this issue.Linked issue
Closes #60
Thanks for the work on this PR. I reviewed the refactor and the test/coverage changes in detail. The overall direction looks good, and I think this is very close to being ready to merge, but there are a few things I would like corrected first.
The main blocker is the current coverage configuration.
Issue #60 explicitly calls for coverage measurement across
src/,pipeline/, and the validator. The PR currently configures coverage with:At first glance that looks correct, but
pipeline/validate/is not currently a regular Python package: it containsvalidate_records.pywithout an__init__.py.Because of that, coverage.py does not automatically discover that file as an unexecuted source file when building the report. The coverage output shown in this PR confirms the problem: the report lists the modules under
src/arkive, but there is no entry for:So although
pipelineis present in the coverage configuration, the compatibility CLI wrapper is currently disappearing from the coverage report entirely.There is also another related detail. The new CLI tests correctly execute the wrapper through
subprocess.run(). I agree with that design because it tests the actual documented command instead of merely importingmain().However, a normal coverage run does not automatically collect execution from spawned Python subprocesses. So at the moment we have:
That means the acceptance goal of actually measuring the
pipeline/code is not yet satisfied.Please adjust the coverage configuration so
pipeline/validate/validate_records.pyis visibly included in the report. Coverage supports namespace-package source discovery throughinclude_namespace_packages = true, which should at minimum prevent this file from silently disappearing.Ideally, please also configure subprocess coverage so that the CLI subprocess tests actually contribute coverage for the wrapper. Current coverage.py supports subprocess collection through its subprocess patching/configuration, combined with parallel data files and
coverage combine.The goal is that after the fix, the coverage report should visibly contain something similar to:
and its executed lines/branches should reflect the CLI tests.
Please do not simply leave the existing
source = ["src/arkive", "pipeline"]configuration and considerpipelinecovered—the current report demonstrates that it is not actually being measured.There are also two smaller cleanup items I noticed.
First,
src/arkive/metadata_validation.pywas added with executable mode100755. Now that it is a normal library module and does not have a shebang, it should normally be100644. Please remove the executable bit.Second, the CHANGELOG currently describes the validator audit as finding:
The numbers in the PR appear to actually represent 38 uncovered statements plus 30 partial branches. Those are coverage metrics, not necessarily 38 separate behaviours. Please reword that entry so it accurately describes what was found rather than equating uncovered statements with independent behaviours.
Aside from these points, the implementation looks good from my review:
src/arkive/metadata_validation.pyis the right architectural direction;spec_from_file_locationloading with normal package imports is a clear improvement;pipeline/validate/validate_records.pyas a thin compatibility CLI wrapper preserves the existing documented workflow;So I am not asking for a redesign. This looks like a small final rework before merge.
Requested changes
pipeline/validate/validate_records.py.src/arkive/metadata_validation.py.38 uncovered statements / 30 partial branches.pipelinewrapper.Once those points are addressed, I expect this PR to be ready for merge without another substantial round of changes.