code: def test_attack_comparator_with_preproc(self) -> None:
      model = BasicModel_MultiLayer()
      text_inp = ["abc", "zyd", "ghi"]
      attack_comp = AttackComparator(
          forward_func=model,
          metric=tuple_metric,
          preproc_fn=text_preproc_fn,
      )
      attack_comp.add_attack(
          SamplePerturb().perturb,
          name="Sequence Column Perturb",
          num_attempts=5,
          apply_before_preproc=False,
      )
      attack_comp.add_attack(
          string_perturb,
          name="StringPerturb",
          apply_before_preproc=True,
      )
      batch_results = attack_comp.evaluate(
          text_inp, target=0, named_tuple=True, perturbations_per_eval=3
      )
      expected_first_results = {
          "Original": (0.0, 1280.0),
          "Sequence Column Perturb": {
              "mean": (0.0, 847.2),
              "max": (0.0, 892.0),
              "min": (0.0, 792.0),
          },
          "StringPerturb": {"mean": (0.0, 1156.0)},
      }
      self._compare_results(batch_results, expected_first_results)
  
      expected_summary_results = {
          "Original": {"mean": (0.0, 1280.0)},
          "Sequence Column Perturb Mean Attempt": {
              "mean": (0.0, 847.2)
          },
          "Sequence Column Perturb Min Attempt": {"mean": (0.0, 792.0)},
          "Sequence Column Perturb Max Attempt": {"mean": (0.0, 892.0)},
          "StringPerturb": {"mean": (0.0, 1156.0)},
      }
      self._compare_results(
          attack_comp.summary(), expected_summary_results
      )
  
imports: import collections
  from typing import List
  import torch
  from captum.robust import AttackComparator, FGSM
  from tests.helpers.basic import assertTensorAlmostEqual, BaseTest
  from tests.helpers.basic_models import BasicModel, BasicModel_MultiLayer
  from torch import Tensor
label_desc: Use image node_id 2 for calling the Test obj's underlying member method code with example usage: obj.test_attack_comparator_with_preproc() without return types