Skip to content

tests: remove duplicate and dead test cases#8896

Merged
ericspod merged 4 commits into
Project-MONAI:devfrom
aymuos15:cleanup/redundant-tests
Jun 22, 2026
Merged

tests: remove duplicate and dead test cases#8896
ericspod merged 4 commits into
Project-MONAI:devfrom
aymuos15:cleanup/redundant-tests

Conversation

@aymuos15

@aymuos15 aymuos15 commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Description

Test-only cleanup. Removes byte-identical duplicate cases and one permanently-skipped test. No production code or test logic changes.

Changes

Duplicate within-file parametrized cases (identical entries that asserted the same thing twice, so removal changes nothing covered):

  • tests/losses/test_unified_focal_loss.py: both TEST_CASES entries were identical
  • tests/inferers/test_sliding_window_inference.py: duplicate 3D small roi case
  • tests/losses/test_dice_loss.py: sigmoid case repeated
  • tests/losses/test_generalized_dice_loss.py: sigmoid case repeated
  • tests/transforms/utility/test_apply_transform_to_pointsd.py: duplicate entry

Dead test removed:

  • tests/apps/test_download_url_yandex.py: removed test_verify and its now-unused YANDEX_MODEL_URL. It was permanently @unittest.skip-ed ("data source unstable") and hits an external Yandex URL, so it never runs in CI. The error path stays covered by test_verify_error.

Types of changes

  • Non-breaking change (test-only cleanup)
  • In-line documentation / comments updated as needed
  • All tests passing locally

aymuos15 added 2 commits June 3, 2026 16:18
Several parametrized test lists contained byte-identical entries that
asserted the same thing twice, contributing no extra coverage:

- losses/test_unified_focal_loss.py: both TEST_CASES entries identical
- inferers/test_sliding_window_inference.py: duplicate 3D small-roi case
- losses/test_dice_loss.py: sigmoid case repeated
- losses/test_generalized_dice_loss.py: sigmoid case repeated
- transforms/utility/test_apply_transform_to_pointsd.py: duplicate entry

Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk>
apps/test_download_url_yandex.py: remove test_verify, which depends on an
unstable external Yandex URL and is permanently @unittest.skip-ed, so it
never runs in CI. The error path remains covered by test_verify_error.

Note: test_smartcachedataset::test_set_data was left skipped on purpose.
Issue Project-MONAI#5660 (the smartcache thread hanging for hours on CI) was closed as
stale with no fix, so the intermittent hang risk likely remains.

Signed-off-by: Soumya Snigdha Kundu <soumya_snigdha.kundu@kcl.ac.uk>
@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR removes test coverage across five test modules. The changes eliminate one unreliable Yandex download test and its constant; prune one 3D sliding-window inference scenario; remove single parameterized cases from GeneralizedDiceLoss, UnifiedFocalLoss, and point-transform coordinate tests. All changes are deletions from test data or test methods with no alterations to core logic.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately and concisely summarizes the main change: removing duplicate and dead test cases.
Description check ✅ Passed Description covers the purpose, specific changes, and types of changes checked; aligned well with template requirements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/losses/test_unified_focal_loss.py (1)

22-30: ⚡ Quick win

Test coverage now minimal after duplicate removal.

Only one test case remains, covering perfect prediction (loss = 0.0). Loss functions need diverse scenarios: imperfect predictions, non-zero loss values, parameter variations (weight, gamma, delta), edge cases.

Suggested additional test cases
TEST_CASES = [
    [  # shape: (2, 1, 2, 2), (2, 1, 2, 2) - perfect prediction
        {
            "y_pred": torch.tensor([[[[1.0, 0], [0, 1.0]]], [[[1.0, 0], [0, 1.0]]]]),
            "y_true": torch.tensor([[[[1.0, 0], [0, 1.0]]], [[[1.0, 0], [0, 1.0]]]]),
        },
        0.0,
    ],
    [  # imperfect prediction - partial mismatch
        {
            "y_pred": torch.tensor([[[[0.8, 0.2], [0.3, 0.9]]], [[[0.7, 0.1], [0.2, 0.85]]]]),
            "y_true": torch.tensor([[[[1.0, 0], [0, 1.0]]], [[[1.0, 0], [0, 1.0]]]]),
        },
        # expected_val would need to be calculated based on loss formula
    ],
    # Add cases for different weight, gamma, delta parameters
]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/losses/test_unified_focal_loss.py` around lines 22 - 30, Replace the
single perfect-prediction entry in TEST_CASES with multiple diverse cases: keep
the existing perfect case, add at least one imperfect-prediction case (modify
y_pred vs y_true to produce non-zero loss), add edge cases (all-zeros/constant
predictions, class-imbalance patterns), and add cases that exercise different
loss parameters (pass explicit weight, gamma, delta variations to the
UnifiedFocalLoss call). Ensure each new case in TEST_CASES references the same
keys ("y_pred", "y_true") and provides either a precomputed expected value (for
deterministic settings) or mark it for approximate/asserted range checks when
exact numeric values are complex; use the symbols TEST_CASES, y_pred, y_true and
the loss parameters weight/gamma/delta to locate where to modify tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/losses/test_unified_focal_loss.py`:
- Around line 22-30: Replace the single perfect-prediction entry in TEST_CASES
with multiple diverse cases: keep the existing perfect case, add at least one
imperfect-prediction case (modify y_pred vs y_true to produce non-zero loss),
add edge cases (all-zeros/constant predictions, class-imbalance patterns), and
add cases that exercise different loss parameters (pass explicit weight, gamma,
delta variations to the UnifiedFocalLoss call). Ensure each new case in
TEST_CASES references the same keys ("y_pred", "y_true") and provides either a
precomputed expected value (for deterministic settings) or mark it for
approximate/asserted range checks when exact numeric values are complex; use the
symbols TEST_CASES, y_pred, y_true and the loss parameters weight/gamma/delta to
locate where to modify tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: caf5c6f5-2344-48f2-8ab8-c2030b22206b

📥 Commits

Reviewing files that changed from the base of the PR and between 013bda0 and 9fefa78.

📒 Files selected for processing (6)
  • tests/apps/test_download_url_yandex.py
  • tests/inferers/test_sliding_window_inference.py
  • tests/losses/test_dice_loss.py
  • tests/losses/test_generalized_dice_loss.py
  • tests/losses/test_unified_focal_loss.py
  • tests/transforms/utility/test_apply_transform_to_pointsd.py
💤 Files with no reviewable changes (5)
  • tests/inferers/test_sliding_window_inference.py
  • tests/transforms/utility/test_apply_transform_to_pointsd.py
  • tests/apps/test_download_url_yandex.py
  • tests/losses/test_generalized_dice_loss.py
  • tests/losses/test_dice_loss.py

@ericspod

Copy link
Copy Markdown
Member

@coderabbitai where else in the unit tests are there duplicate test cases like those removed in this PR?

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
python3 - <<'EOF'
import ast
import os
import sys
from pathlib import Path

def find_duplicates_in_list(elements):
    seen = []
    dupes = []
    for i, el in enumerate(elements):
        key = ast.dump(el)
        for j, (prev_key, prev_idx) in enumerate(seen):
            if key == prev_key:
                dupes.append((prev_idx, i))
                break
        else:
            seen.append((key, i))
    return dupes

results = []

for path in Path("tests").rglob("*.py"):
    try:
        src = path.read_text(errors="replace")
        tree = ast.parse(src, filename=str(path))
    except SyntaxError:
        continue

    for node in ast.walk(tree):
        if not isinstance(node, ast.Assign):
            continue
        for target in node.targets:
            if not isinstance(target, ast.Name):
                continue
            name = target.id
            if "TEST" not in name.upper() and "CASES" not in name.upper() and "PARAMS" not in name.upper():
                continue
            val = node.value
            if not isinstance(val, ast.List):
                continue
            elems = val.elts
            if len(elems) < 2:
                continue
            dupes = find_duplicates_in_list(elems)
            if dupes:
                results.append((str(path), name, dupes))

for fpath, varname, dupes in sorted(results):
    for (i, j) in dupes:
        print(f"{fpath}  {varname}  indices {i} and {j} are identical")

if not results:
    print("No duplicates found.")
EOF

Length of output: 16409



@ericspod Here's the full list of files with byte-identical duplicate entries in their test case lists:

apps/

  • tests/apps/deepgrow/test_deepgrow_dataset.pyTEST_CASE_4, TEST_CASE_5
  • tests/apps/detection/utils/test_detector_utils.pyTEST_CASE_3
  • tests/apps/pathology/transforms/post/test_generate_succinct_contour.pyTEST_CASE_1
  • tests/apps/pathology/transforms/post/test_generate_succinct_contourd.pyTEST_CASE_1

bundle/

  • tests/bundle/test_bundle_ckpt_export.pyTEST_CASE_1
  • tests/bundle/test_bundle_trt_export.pyTEST_CASE_1, TEST_CASE_2

data/

  • tests/data/test_arraydataset.pyTEST_CASE_1/2/3, test_labels
  • tests/data/test_lmdbdataset.pyTEST_CASE_3
  • tests/data/test_nrrd_reader.pyTEST_CASE_1 through TEST_CASE_8 (indices 0 and 2 identical in each)
  • tests/data/test_persistentdataset.pyTEST_CASE_4/5/6/7
  • tests/data/test_pil_reader.pyTEST_CASE_1 through TEST_CASE_6
  • tests/data/utils/test_decollate.pytest_case

handlers/

  • tests/handlers/test_handler_checkpoint_saver.pyTEST_CASE_1 through TEST_CASE_8 (many cross-index duplicates — likely worth a separate look; the list entries may be intentional combinations of primitives)
  • tests/handlers/test_handler_hausdorff_distance.pyTEST_SAMPLE_2, TEST_SAMPLE_4
  • tests/handlers/test_handler_surface_distance.pyTEST_SAMPLE_2, TEST_SAMPLE_4

inferers/

  • tests/inferers/test_patch_inferer.py — 9 different TEST_CASE_* variables (indices 0 and 3 identical in each)

metrics/

  • tests/metrics/test_calibration_metric.pyTEST_VALUE_1B1C

networks/

  • tests/networks/blocks/test_mlp.py, test_se_blocks.py, test_selfattention.pytest_case
  • tests/networks/layers/test_savitzky_golay_filter.pyTEST_CASE_1D_REP, TEST_CASE_SINGLE_VALUE_REP
  • tests/networks/nets/test_ahnet.py — 5 cases
  • tests/networks/nets/test_autoencoder.pyTEST_CASE_0/1/2
  • tests/networks/nets/test_autoencoderkl.pyCASES_ATTENTION
  • tests/networks/nets/test_cell_sam_wrapper.py, test_fullyconnectednet.py, test_spade_autoencoderkl.py, test_varautoencoder.py, test_vnet.py, test_voxelmorph.py
  • tests/networks/test_save_state.pyTEST_CASE_6, TEST_CASE_10

transforms/

  • tests/transforms/test_border_pad.py, test_border_padd.py
  • tests/transforms/test_center_spatial_crop.py
  • tests/transforms/test_cucim_dict_transform.py, test_cucim_transform.py (and rand variants)
  • tests/transforms/test_fill_holes.py, test_fill_holesd.py — 8 cases each
  • tests/transforms/test_load_image.py — 5 cases
  • tests/transforms/test_rand_torchio.py, test_rand_torchiod.py, test_torchio.py, test_torchiod.py
  • tests/transforms/test_savitzky_golay_smooth.py, test_savitzky_golay_smoothd.py
  • tests/transforms/test_spatial_padd.py

The test_handler_checkpoint_saver.py cases are likely combining shared primitive values intentionally (not pure parametrize duplicates), so worth manually verifying those. The rest look like straightforward cleanup candidates similar to this PR.

@ericspod ericspod left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @aymuos15 thanks for the cleanup, I'm going to merge now but from the Coderabbit response there may be other similar places that can be improved in #8942.

@ericspod ericspod merged commit 31419ab into Project-MONAI:dev Jun 22, 2026
21 checks passed
@aymuos15

Copy link
Copy Markdown
Contributor Author

I'll make a follow up PR for this, Thank you for pointing that out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants