Модульный тест, когда rootViewController представляет представление?

Я пытаюсь выполнить модульное тестирование функции, которая представляет представление вне viewController:

public func presentInOwnWindow(animated: Bool, completion: (() -> Void)?) {
        let alertWindow = UIWindow(frame: UIScreen.main.bounds)
        alertWindow.rootViewController = UIViewController()
        alertWindow.windowLevel = UIWindowLevelAlert + 1;
        alertWindow.makeKeyAndVisible()
    alertWindow.rootViewController?.present(self, animated: animated, completion: completion)
    }

пока все, что я могу думать о том, как проводить модульное тестирование, выглядит так:

  func test_presentInOwnWindow () {

       let presented = sut.presentInOwnWindow(animated: true) {}

        XCTAssertNotNil(presented)
    }

Я попытался передать bool для блока завершения:

завершение: ((Bool) -> Пустота)

но поскольку он вызывает завершение для:

rootViewController?. присутствует

Я получаю сообщение об ошибке:

Не удается преобразовать значение типа '((Bool) -> Void)?' к ожидаемому типу аргумента '(() -> Void)?'

Любая идея, как правильно протестировать функцию?


person SwiftyJD    schedule 16.02.2018    source источник


Ответы (2)


Код модульного тестирования, который имеет побочные эффекты, может быть невероятно сложным, особенно если побочные эффекты связаны с аппаратным обеспечением, таким как экран устройства. По этой причине компоненты пользовательского интерфейса не подходят для модульного тестирования, поскольку они обычно включают операции с графическим процессором.

Теперь, если вы действительно хотите протестировать компонент, вы можете пойти двумя путями:

  • вы пишете снэпшоты-тесты
  • вы извлекаете всю бизнес-логику в специальные классы и тестируете их.

Вывод: выполните модульное тестирование бизнес-кода и позвольте QA протестировать пользовательский интерфейс, который ведет себя так, как ожидалось.

person Cristik    schedule 17.02.2018

Несколько вариантов, чтобы попробовать:

  1. Прокрутите present(_, animated, completion) UIViewController, чтобы зафиксировать то, что было представлено. Я делаю это для UIAlertControllers https://qualitycoding.org/testing-uialertcontroller/, но это потому, что UIAlertControllers так распространены. Это может не стоить проблем для вашего пользовательского окна.
  2. Не уверен, что это сработает. makeKeyAndVisible и present, вероятно, не дают немедленного эффекта. Вместо этого они планируют работу. Таким образом, вы можете попробовать прокачать цикл запуска с помощью RunLoop.current.run(until: Date()). Это работает для активации текстовых полей, но я не знаю, сработает ли это для вас.
  3. Точно так же попробуйте добавить XCTestExpectation и waitForExpectations с небольшим тайм-аутом. Как я заметил в https://qualitycoding.org/asynchronous-tests/, не делайте любые утверждения в вашем обработчике ожиданий. Вместо этого зафиксируйте нужную информацию и fulfill ожидания. Затем настаивайте на том, что вы захватили.
  4. Измените код, который вы написали, чтобы упростить его тестирование. Замените последнюю строку, вызвав блок, сохраненный в свойстве в SUT. Для проверки замените этот блок. Блок test может вызывать обработчик завершения, что дает вам возможность протестировать обработчики.
  5. Протестируйте этот код вручную. Затем издевайтесь над ним, чтобы ваши тесты проверяли, вызывается ли этот метод (но на самом деле не вызывают его).
person Jon Reid    schedule 17.02.2018