Subcategory: test design quality (9 → 10)
Problem
The two Hypothesis strategies both cap generated universes at 8 assets:
src under test via tests/pyhrp/test_algos.py:27 — covariance_matrices:
n_assets = draw(st.integers(min_value=2, max_value=8))
tests/pyhrp/test_dendrogram.py:50 — correlation_matrices, same ceiling
The suite is otherwise excellent — it asserts mathematics rather than implementation
(closed-form two-asset weights at test_algos.py:376, idempotency at :100, the
in-place-mutation contract at :110 and :136, near-singular covariance at :388,
zero-variance splits at :153), runs 200 examples per property, and carries a fuzz
harness at tests/fuzz/fuzz_hrp.py. The ceiling is the one gap.
An 8-asset ceiling means every generated tree has depth ≤ 8, so no property test can
exercise deep-tree behaviour. That is precisely why the recursion-depth ceiling reported
in the companion issue went unnoticed despite 100% statement and branch coverage — a
good illustration that coverage and input-space coverage are different things.
Files / lines
tests/pyhrp/test_algos.py:27 — covariance_matrices, max_value=8
tests/pyhrp/test_dendrogram.py:50 — correlation_matrices, max_value=8
Suggested direction
- Raise
max_value on both strategies to a size that produces non-trivial depth. Both
properties already set deadline=None, so a moderate increase should not destabilise
them; keep max_examples in mind for runtime and tune if the suite slows noticeably.
- Add one explicit large-universe regression test — not property-based — pinning a
chain-degenerate tree at a realistic asset count, so the boundary is asserted at a
fixed, debuggable size rather than left to generation.
- Consider whether
method="single" deserves its own strategy dimension: it is the
linkage most prone to chaining, and therefore the one that produces the deepest trees.
Related
The depth ceiling this would have caught is filed separately as the
_to_cluster / _allocate RecursionError issue.
done when…
Both strategies generate universes large enough to produce trees deeper than 8, and a
named regression test asserts correct behaviour on a chain-degenerate tree at a realistic
asset count. make test still passes at 100% coverage.
Evidence
n_assets = draw(st.integers(min_value=2, max_value=8)) at tests/pyhrp/test_algos.py:27
and the equivalent at tests/pyhrp/test_dendrogram.py:50; 123 tests pass at 100%
statement and branch coverage while a 1200-asset input crashes.
Subcategory: test design quality (9 → 10)
Problem
The two Hypothesis strategies both cap generated universes at 8 assets:
srcunder test viatests/pyhrp/test_algos.py:27—covariance_matrices:n_assets = draw(st.integers(min_value=2, max_value=8))tests/pyhrp/test_dendrogram.py:50—correlation_matrices, same ceilingThe suite is otherwise excellent — it asserts mathematics rather than implementation
(closed-form two-asset weights at
test_algos.py:376, idempotency at:100, thein-place-mutation contract at
:110and:136, near-singular covariance at:388,zero-variance splits at
:153), runs 200 examples per property, and carries a fuzzharness at
tests/fuzz/fuzz_hrp.py. The ceiling is the one gap.An 8-asset ceiling means every generated tree has depth ≤ 8, so no property test can
exercise deep-tree behaviour. That is precisely why the recursion-depth ceiling reported
in the companion issue went unnoticed despite 100% statement and branch coverage — a
good illustration that coverage and input-space coverage are different things.
Files / lines
tests/pyhrp/test_algos.py:27—covariance_matrices,max_value=8tests/pyhrp/test_dendrogram.py:50—correlation_matrices,max_value=8Suggested direction
max_valueon both strategies to a size that produces non-trivial depth. Bothproperties already set
deadline=None, so a moderate increase should not destabilisethem; keep
max_examplesin mind for runtime and tune if the suite slows noticeably.chain-degenerate tree at a realistic asset count, so the boundary is asserted at a
fixed, debuggable size rather than left to generation.
method="single"deserves its own strategy dimension: it is thelinkage most prone to chaining, and therefore the one that produces the deepest trees.
Related
The depth ceiling this would have caught is filed separately as the
_to_cluster/_allocateRecursionErrorissue.done when…
Both strategies generate universes large enough to produce trees deeper than 8, and a
named regression test asserts correct behaviour on a chain-degenerate tree at a realistic
asset count.
make teststill passes at 100% coverage.Evidence
n_assets = draw(st.integers(min_value=2, max_value=8))attests/pyhrp/test_algos.py:27and the equivalent at
tests/pyhrp/test_dendrogram.py:50; 123 tests pass at 100%statement and branch coverage while a 1200-asset input crashes.