def test_tqdm_progress_bar_totals(tmp_path, num_dl):
    """Test that the progress finishes with the correct total steps processed."""

    class CustomModel(BoringModel):
        def _get_dataloaders(self):
            dls = [DataLoader(RandomDataset(32, 64)), DataLoader(RandomDataset(32, 64))]
            return dls[0] if num_dl == 1 else dls

        def val_dataloader(self):
            return self._get_dataloaders()

        def test_dataloader(self):
            return self._get_dataloaders()

        def predict_dataloader(self):
            return self._get_dataloaders()

        def validation_step(self, batch, batch_idx, dataloader_idx=0):
            return

        def test_step(self, batch, batch_idx, dataloader_idx=0):
            return

        def predict_step(self, batch, batch_idx, dataloader_idx=0):
            return

    model = CustomModel()

    # check the sanity dataloaders
    num_sanity_val_steps = 4
    trainer = Trainer(
        default_root_dir=tmp_path, max_epochs=1, limit_train_batches=0, num_sanity_val_steps=num_sanity_val_steps
    )
    pbar = trainer.progress_bar_callback
    with mock.patch("lightning.pytorch.callbacks.progress.tqdm_progress.Tqdm", MockTqdm):
        trainer.fit(model)

    expected_sanity_steps = [num_sanity_val_steps] * num_dl
    assert not pbar.val_progress_bar.leave
    assert trainer.num_sanity_val_batches == expected_sanity_steps
    assert pbar.val_progress_bar.total_values == expected_sanity_steps
    assert pbar.val_progress_bar.n_values == list(range(num_sanity_val_steps + 1)) * num_dl
    assert pbar.val_progress_bar.descriptions == [f"Sanity Checking DataLoader {i}: " for i in range(num_dl)]

    # fit
    trainer = Trainer(default_root_dir=tmp_path, max_epochs=1)
    pbar = trainer.progress_bar_callback
    with mock.patch("lightning.pytorch.callbacks.progress.tqdm_progress.Tqdm", MockTqdm):
        trainer.fit(model)

    n = trainer.num_training_batches
    m = trainer.num_val_batches
    assert len(trainer.train_dataloader) == n
    # train progress bar should have reached the end
    assert pbar.train_progress_bar.total == n
    assert pbar.train_progress_bar.n == n
    assert pbar.train_progress_bar.leave

    # check val progress bar total
    assert pbar.val_progress_bar.total_values == m
    assert pbar.val_progress_bar.n_values == list(range(m[0] + 1)) * num_dl
    assert pbar.val_progress_bar.descriptions == [f"Validation DataLoader {i}: " for i in range(num_dl)]
    assert not pbar.val_progress_bar.leave

    # validate
    with mock.patch("lightning.pytorch.callbacks.progress.tqdm_progress.Tqdm", MockTqdm):
        trainer.validate(model)
    assert trainer.num_val_batches == m
    assert pbar.val_progress_bar.total_values == m
    assert pbar.val_progress_bar.n_values == list(range(m[0] + 1)) * num_dl
    assert pbar.val_progress_bar.descriptions == [f"Validation DataLoader {i}: " for i in range(num_dl)]

    # test
    with mock.patch("lightning.pytorch.callbacks.progress.tqdm_progress.Tqdm", MockTqdm):
        trainer.test(model)
    assert pbar.test_progress_bar.leave
    k = trainer.num_test_batches
    assert pbar.test_progress_bar.total_values == k
    assert pbar.test_progress_bar.n_values == list(range(k[0] + 1)) * num_dl
    assert pbar.test_progress_bar.descriptions == [f"Testing DataLoader {i}: " for i in range(num_dl)]
    assert pbar.test_progress_bar.leave

    # predict
    with mock.patch("lightning.pytorch.callbacks.progress.tqdm_progress.Tqdm", MockTqdm):
        trainer.predict(model)
    assert pbar.predict_progress_bar.leave
    k = trainer.num_predict_batches
    assert pbar.predict_progress_bar.total_values == k
    assert pbar.predict_progress_bar.n_values == list(range(k[0] + 1)) * num_dl
    assert pbar.predict_progress_bar.descriptions == [f"Predicting DataLoader {i}: " for i in range(num_dl)]
    assert pbar.predict_progress_bar.leave
Test that the progress finishes with the correct total steps processed.
tests/tests_pytorch/callbacks/progress/test_tqdm_progress_bar.py