XCTAsertThrows останавливается в точке останова

Я пишу тестовый метод, в котором я хочу, чтобы SUT выдавал исключение при определенных условиях. Код выглядит следующим образом:

- (void) testCantStartTwice
{
    XCTAssertThrows([self.sut start], @"");
}

Теперь все хорошо, и тест проходит. Однако у меня Xcode установил точку останова исключения для всех исключений ObjC, что очень полезно при тестировании приложения в отладчике. Как и вы сейчас, теперь, когда я запускаю свой набор тестов с помощью ⌘U, теперь он останавливается на этом тесте и выглядит так, будто он терпит неудачу, даже если он говорит «Тест прошел успешно».

Можно ли сделать так, чтобы точка останова не останавливалась на этом тесте?

Спасибо и всего наилучшего


person Pierluigi Cifani    schedule 25.02.2014    source источник


Ответы (3)


К сожалению, кажется невозможным, чтобы точки останова исключений игнорировали все, что заключено в XCTAssertThrows (или теперь XCTAssertThrowsError).

Обходной путь 1: работа с точками останова или сценарием вокруг них

Когда вы выполняете эти тесты, вы можете сделать следующее:

  • Отключите точку останова исключения.
  • Нажимайте Run каждый раз, когда он достигает одной из ваших точек останова.

Оба не идеальны, так как вы будете выполнять некоторую ручную работу.

Здесь есть предложения по отключения точек останова для утверждений Swift XCTAssertThrowsError. Я не тестировал их.

Обходной путь 2: вместо этого верните Result<T, Error>

Мой оригинальный метод выглядел так:

struct Truck {
  static func makeTruck(numberOfWheels: Int) throws -> Self {
    if numberOfWheels < 4 {
      throw TruckError.tooFewWheels
    }

    // ...

    return .init()
  }
}

// Code example:
let truck: Truck? = try? Truck.makeTruck(numberOfWheels: 1)

// Test example:
XCTAssertThrowsError(try Truck.makeTruck(numberOfWheels: 1))

Чтобы обойти эту проблему с точками останова, я создал дублирующую внутреннюю функцию, которую легче тестировать (поскольку она не вызовет проблемы с точкой останова), возвращая Result вместо Error.

struct Truck {
  static func _makeTruck(numberOfWheels: Int) -> Result<Truck, Error> {
    if numberOfWheels < 4 {
      return .failure(TruckError.tooFewWheels)
    }

    // ...

    return .success(.init())
  }

  static func makeTruck(numberOfWheels: Int) throws -> Self {
    switch _makeTruck(numberOfWheels: numberOfWheels) {
    case .failure(let error):
      throw error
    case .success(let value):
      return value
    }
  }
}

// Code example:
let truck: Truck? = try? Truck.makeTruck(numberOfWheels: 1)

// Test example:
XCTAssertEquals(Truck._makeTruck(numberOfWheels: 1), .error(TruckError.tooFewWheels))

Обходной путь 3: вместо этого верните T?

Наконец, если у вас есть более простой вариант использования, и сбой вашей функции вполне очевиден (например, существует только один тип ошибки, которую она может вернуть), рассмотрите возможность возврата необязательного параметра вместо необходимости сложности типа Result:

struct Truck {
  static func makeTruck(numberOfWheels: Int) -> Truck? {
    if numberOfWheels < 4 {
      return nil
    }

    // ...

    return .init()
  }
}

// Code example:
let truck: Truck? = Truck.makeTruck(numberOfWheels: 1)

// Test example:
XCTAssertNil(Truck.makeTruck(numberOfWheels: 1))
person Senseful    schedule 07.11.2020

Возможно, вы могли бы использовать точку останова при сбое теста вместо точки останова исключения при тестировании. В видеоролике wwdc 2013, посвященном модульному тестированию, описан довольно хороший рабочий процесс проверки ошибок тестирования. В нем по существу говорилось:

  1. Установите контрольную точку сбоя теста, которая позволит вам проверить условия, вызвавшие сбой.
  2. При необходимости установите точку останова вручную ранее в тесте и запустите его повторно, чтобы вы могли пройти операторы, ведущие к сбою, как обычно.

На самом деле это не прямой ответ, но, насколько я знаю, я не думаю, что есть способ создать исключения для точки останова исключения. Надеюсь, поможет

person RyanM    schedule 11.04.2014
comment
Райан, спасибо за ответ! Это хорошее решение, однако точка останова исключения действительно полезна при выполнении приложения на симе или устройстве. В идеале должен быть набор точек останова при запуске и набор точек останова при тестировании, есть ли способ настроить это так? - person Pierluigi Cifani; 13.04.2014

У меня была такая же проблема, и я искал решение в течение 2 часов. Наверное, мы ничего не можем с этим поделать.

person Arkadiusz    schedule 26.02.2014