Repository navigation
Combine near-duplicate test functions into parametrized tests - #74
Merged
Merged
Conversation
Test functions that ran the same code with different inputs and expected results are now one test with `pytest.mark.parametrize`, in 15 of the 22 test files. Each case keeps its own test ID (named after the original test or its comment), so the same cases still run and are reported separately: 108 test functions become 40 parametrized tests with 109 cases (the old invalid-unit-names test in test_class_ground_motion.py had two checks, which are now two cases). - Where the cases call different methods of the same kind (e.g., the four ground-motion filters, `get_HH_x_param()`/`get_H4_x_param()`, or `get_f0_BH()`/`get_f0_RO()`), the unbound method is the parameter - Boolean parameters are keyword-only (FBT001), as in CONTRIBUTING.md - The expected-failure cases that matched against an empty string (`match=''`, which pytest warns always passes) now use no `match` - The HH case of the multi-layer list-operations test now checks `n_layer` after deleting a layer, like the MKZ case did, instead of checking `len()` twice Tests with different assertions or setup are left as they are, and so are the sequential checks inside one test function. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C1a5vwxyeL4atk9tYUUEoQ
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C1a5vwxyeL4atk9tYUUEoQ
- Name the combined HH/H4 and HH/MKZ tests after both models, e.g., `test_HH_x_or_H4_x_fit_single_layer` and `test_HH_MKZ_param_multi_layer__can_initiate_object_from_file`, and `test_f0` as `test_f0_BH_or_f0_RO` - Name the cases of `test_construct_curves`, `test_param_serialize`, and `test_serialize_to_2D_array` after the original test functions (e.g., `from_HH_G_parameters`) - Move a comment in test_helper_hh_model.py into the `pytest.param()` that it describes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C1a5vwxyeL4atk9tYUUEoQ
- Leave out optional arguments in the cases that used to leave them out, so that their defaults are tested again: `dt` in the ground motion loading tests, and `OCR_upper_limit` in `test_calc_OCR`. The cases now pass a `kwargs` dict, like `test_class_svm.py` does - Pass callables (`lambda gm: gm.pga_in_g`, and lambdas that call `get_curve_matrix()` with the keyword argument) instead of attribute and keyword names as strings - Combine the differential-evolution and DEAP multi-layer fitting tests into `test_HH_x_or_H4_x_fit_multi_layer`. The DEAP cases still pass when DEAP is not installed, as before; an `ImportError` in the differential-evolution cases is no longer swallowed - Share one `multi_layer_case` fixture among the 4 HH/MKZ multi-layer parameter tests, instead of repeating the case list. The list operations test now deletes layer 3 in both cases (it was 6 for MKZ) - Rename `test_param_multi_layer__test_list_operations` to `test_HH_MKZ_param_multi_layer__list_operations`, and `test_calc_damping_from_stress_strain__case_3` to `..._initial_damping_almost_0`, after what it tests (its siblings' IDs are no longer numbered) - Pass a copy, not a view, of the module-level `DATA_5_COLUMNS` array in the `incorrect_number_of_columns` case Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016MPgzyHE9jy5vP7heBxZhA
This was referenced Oct 11, 2026
Open
Open
This was referenced Oct 11, 2026
jsh9
pushed a commit
that referenced
this pull request
Oct 11, 2026
#74 was squash-merged into main, so main's files are identical to the branch's old base. Every conflict is resolved with this branch's version. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W7fK8T2pPLf3tPCnMCKL1T
jsh9
pushed a commit
that referenced
this pull request
Oct 11, 2026
#74 was squash-merged into main, so main's files are identical to the branch's old base. Every conflict is resolved with this branch's version. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W7fK8T2pPLf3tPCnMCKL1T
jsh9
pushed a commit
that referenced
this pull request
Oct 11, 2026
#74 was squash-merged into main, so main's files are identical to the branch's old base. Every conflict is resolved with this branch's version. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W7fK8T2pPLf3tPCnMCKL1T
jsh9
pushed a commit
that referenced
this pull request
Oct 11, 2026
#74 was squash-merged into main, so main's files are identical to the branch's old base. Every conflict is resolved with this branch's version. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W7fK8T2pPLf3tPCnMCKL1T
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR combines test functions that ran the same code with different inputs and expected results into parametrized tests (
pytest.mark.parametrize).Summary
In 15 of the 22 test files, 108 test functions become 39 parametrized tests with 109 cases. Every case still runs and is reported as its own test. Each test ID comes from the original test name or its comment, e.g.
test_truncate[on_the_boundary_of_a_layer]ortest_filter[band_pass].The one extra case comes from
test_loading_data__test_invalid_unit_names(ground motion). It had two checks, and they are now two cases oftest_loading_data__invalid_input.One more test is renamed, not combined:
test_calc_damping_from_stress_strain__case_3is nowtest_calc_damping_from_stress_strain__initial_damping_almost_0, after what it tests, because its two former siblings no longer have numbered IDs.I compared the collected test IDs before and after: every removed test maps to exactly one new case (the renamed test maps to its new name), and the case count per file is the same (except the +1 above). All 241 tests pass, and
pre-commit run -apasses.What was combined
test_class_Vs_profile.pyformat__case_*→test_Vs_profile_format; 5truncate__case_*→test_truncate; 2add_halfspace;f0_BH/f0_ROtest_class_curves.pyget_curve_matrixtest_class_parameters.pyconstruct_curves; 2param_serialize; 2serialize_to_2D_arraytest_class_ground_motion.pytest_class_site_factors.pytest_class_svm.pyVs_captests; 2 valid and 3 invalidget_discretized_profileteststest_helper_site_response.pycalc_z1,calc_GGmax_from_stress_strain,calc_damping_from_stress_strain(cases 1–2),fit_all_damping_curvesexceptions,align_two_time_arraysnormal casestest_helper_hh_calibration.pycalc_OCR,calc_K0, 4optimization_kernelcasestest_helper_hh_model.py,test_helper_mkz_model.pyserialize/deserializefailure teststest_class_batch_simulation.pyinitcases 1–3test_class_damping_calibration.pyget_HH_x_param/get_H4_x_paramtest_class_hh_calibration.pyTmaxteststest_class_site_effect_adjustment.pytest_helper_simulations.pylineartestsNotes for review
get_HH_x_param()/get_H4_x_param(),get_f0_BH()/get_f0_RO()), the parameter is the unbound method (e.g.GM.highpass), not a method name passed togetattr.*), following CONTRIBUTING.md, because muff reports FBT001 on boolean test arguments too.match=''now have nomatch. This is equivalent, and pytest no longer warns that an empty string always matches (13 warnings → 6).len()twice. It now also checksn_layer, like the MKZ case.len()andn_layerafterwards.test_linearnow also labels the plot's y-axis, like the elastic case did.get_GGmax/get_dampingtests, which build their objects with different classes and deserializers. Checks inside a single test function (e.g.test_is_int,test_range_check,test_query_Vs_given_thk) are also left alone, because this PR only combines separate test functions. Turning those into parametrized cases could be a follow-up.CHANGELOG.mdhas a new entry, and the example notebooks were re-run (second commit), as CONTRIBUTING.md requires.🤖 Generated with Claude Code
https://claude.ai/code/session_01C1a5vwxyeL4atk9tYUUEoQ
Generated by Claude Code