From d2c33b69be8b5d706878d3d5ce57579d28b2f13f Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 14 Sep 2026 23:20:11 -0700 Subject: [PATCH] fix: count NumPy testing assertions in Python test quality --- desloppify/languages/python/test_coverage.py | 1 + .../detectors/coverage/test_test_coverage.py | 27 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/desloppify/languages/python/test_coverage.py b/desloppify/languages/python/test_coverage.py index 8b7710cb0..36e44b8fd 100644 --- a/desloppify/languages/python/test_coverage.py +++ b/desloppify/languages/python/test_coverage.py @@ -24,6 +24,7 @@ r"^\s*assert\s+", r"self\.assert\w+\(", r"pytest\.raises\(", + r"\b(?:np|numpy)\.testing\.assert_\w+\s*\(", r"\.assert_called", r"\.assert_not_called", ] diff --git a/desloppify/tests/detectors/coverage/test_test_coverage.py b/desloppify/tests/detectors/coverage/test_test_coverage.py index 984dd11e6..d12334e10 100644 --- a/desloppify/tests/detectors/coverage/test_test_coverage.py +++ b/desloppify/tests/detectors/coverage/test_test_coverage.py @@ -424,6 +424,32 @@ def test_no_directly_tested(self): class TestAnalyzeTestQuality: + @pytest.mark.parametrize("module", ["np", "numpy"]) + def test_python_numpy_testing_assertions(self, tmp_path, module): + content = ( + "def test_values():\n" + f" {module}.testing.assert_allclose(actual, expected)\n" + f" {module}.testing.assert_array_equal(actual, expected)\n" + "\n" + "def test_bounds():\n" + f" {module}.testing.assert_array_less(actual, upper_bound)\n" + ) + tf = _write_file(tmp_path, "test_arrays.py", content) + result = analyze_test_quality({tf}, "python") + assert result[tf]["assertions"] == 3 + assert result[tf]["test_functions"] == 2 + assert result[tf]["quality"] not in {"assertion_free", "smoke"} + + def test_python_numpy_assertion_references_and_comments_do_not_count(self, tmp_path): + content = ( + "def test_values():\n" + " helper = np.testing.assert_allclose\n" + " # np.testing.assert_array_equal(actual, expected)\n" + ) + tf = _write_file(tmp_path, "test_references.py", content) + result = analyze_test_quality({tf}, "python") + assert result[tf]["assertions"] == 0 + # Python test function counting uses MULTILINE and should count all test defs. def test_python_thorough(self, tmp_path): @@ -971,4 +997,3 @@ def test_naming_convention_mapping(self, tmp_path): if e["detail"]["kind"] in ("untested_module", "untested_critical") ] assert untested == [] -