def assertDataCloseOrEqual(self, a_data, b_data):
    """Assert two datasets contain nearly equal values.

    Args:
      a_data: a sequence of dicts whose values are
              either strings, lists of strings, numeric types or a pair of
              those.
      b_data: same types as a_data

    Raises:
      AssertionError: if the two datasets are not the same.
    """
    msg = ''
    try:
      sorted_a, sorted_b = self._SortedData(a_data), self._SortedData(b_data)
      self.assertEqual(
          len(sorted_a), len(sorted_b), 'len(%r) != len(%r)' % (a_data, b_data))
      for i, (a_row, b_row) in enumerate(zip(sorted_a, sorted_b)):
        self.assertCountEqual(a_row.keys(), b_row.keys(), msg='Row %d' % i)
        for key in a_row.keys():
          a_value = a_row[key]
          b_value = b_row[key]
          msg = 'Row %d, key %s' % (i, key)
          if isinstance(a_value, tuple):
            self._assertValuesCloseOrEqual(a_value[0], b_value[0], msg=msg)
            self._assertValuesCloseOrEqual(a_value[1], b_value[1], msg=msg)
          else:
            self._assertValuesCloseOrEqual(a_value, b_value, msg=msg)
    except (AssertionError, TypeError) as e:
      message = '{}\nCompared:\n{}\nvs.\n{}'.format(msg, a_data, b_data)
      e.args = ((e.args[0] + ' : ' + message,) + e.args[1:])
      raise e
Assert two datasets contain nearly equal values.

    Args:
      a_data: a sequence of dicts whose values are
              either strings, lists of strings, numeric types or a pair of
              those.
      b_data: same types as a_data

    Raises:
      AssertionError: if the two datasets are not the same.
    
tensorflow_transform/test_case.py