Каков правильный подход к модульному тестированию в iOS?

class RemoveMyDataConsentFormVCTests: XCTestCase {
    var viewController: RemoveMyDataConsentFormVC!

    override func setUp() {
        super.setUp()
        
        let storyboard = UIStoryboard(name: "RemoveMyDataConsentForm", bundle: nil) // Replace "Main" with your storyboard name
        viewController = storyboard.instantiateViewController(withIdentifier: "RemoveMyDataConsentFormVC") as? RemoveMyDataConsentFormVC
        viewController.loadViewIfNeeded()
    }

    override func tearDown() {
        viewController = nil
        super.tearDown()
    }
    
    func testSetupTextFields() {
        if viewController.emailTextField.text == "" {
            viewController.emailTextField.text = nil
        }
                
        XCTAssertNotNil(viewController.emailTextField.text, "Error for email should be hidden")
        XCTAssertTrue((viewController.errorForStates != nil), "Error for email should be hidden")
        XCTAssertTrue((viewController.errorForCountries != nil), "Error for email should be hidden")
        XCTAssertTrue((viewController.errorForLastName != nil), "Error for email should be hidden")
        XCTAssertTrue((viewController.errorForFirstName != nil), "Error for email should be hidden")
    }
}

Выше приведен код моего UIViewController, для которого я написал модульный тест для настройки текстовых полей. Я ищу пример, позволяющий улучшить способ написания модульных тестов с использованием Swift 5.

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Существует два распространенных типа тестов:

  • Мы тестируем поведение пользовательского интерфейса (например, UIViewController подклассы) в UI-тестах. Но когда мы пишем эти тесты, мы обычно не проверяем внутреннее состояние контроллера представления, а скорее проверяем то, что представлено в пользовательском интерфейсе.

    Например, тест пользовательского интерфейса предоставит некоторое значение некоторому элементу управления пользовательского интерфейса (например, текстовому полю), а затем тест пользовательского интерфейса проверит, правильно ли пользовательский интерфейс отразил ошибку. Но мы тестируем не внутренние объекты ошибок, а то, как они были представлены в пользовательском интерфейсе.

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

    Например, можно проверить, что некоторая текстовая строка, предоставленная какой-либо функции «проверки строки», вернула правильный объект ошибки.

С этой целью многие из нас пытаются абстрагировать бизнес-логику от уровня представления (т. е. мы вытаскиваем ее из контроллера представления, например). Разные команды/проекты используют для этого разные методы/терминологию: некоторые используют «модели представления». Некоторые используют «презентационные» объекты. Некоторые используют более абстрактный «контроллер» (не путать с «контроллером представления», специфичным для пользовательского интерфейса) или «сервисные» объекты для инкапсуляции этой бизнес-логики.

Независимо от того, как к этому подойти, идея состоит в том, что по соображениям тестируемости (а также просто для общего хорошего дизайна) мы абстрагируем бизнес-логику от уровня пользовательского интерфейса нашей кодовой базы (т. Е. Мы извлекаем ее из контроллеров представления). Затем мы пишем «модульные тесты» для проверки этих функций/объектов бизнес-логики, полностью отделенных от любого кода пользовательского интерфейса. Затем мы пишем «тесты пользовательского интерфейса», чтобы убедиться, что наш пользовательский интерфейс ведет себя так, как мы ожидали, а не для проверки внутреннего состояния уровня представления.


Посмотрите разницу между модульными тестами и тестами пользовательского интерфейса примерно за 1:33 до WWDC 2023 Исправляйте сбои быстрее с помощью отчетов о тестировании Xcode:

Другие вопросы по теме