Как импортировать мой модуль приложения в файл MyAppUITests?

Это мой простой тестовый пример:

import XCTest
@testable import MyApp //it doesn't work

из-за этого:

введите описание изображения здесь

class TabBarControllerTests: XCTestCase {

    override func setUp() {
        super.setUp()

        let defaults = NSUserDefaults.standardUserDefaults()
        defaults.setObject([], forKey: DBTabBarOrderedIndexesKey) //key is undefined, because of lack of my app module
        defaults.synchronize()

        continueAfterFailure = false
        XCUIApplication().launch()
    }

    func testIsOrderOfTabsSaved() {

        XCUIApplication().tabBars.buttons["Catering"].tap()
        //what next?
    }
}

Как только я коснуюсь UITabBarItem, я изменяю значение DBAppSettings.mode, поэтому здесь я хотел бы получить доступ к моему свойству DBAppSettings.mode, чтобы проверить, действительно ли оно изменено.

Я заметил, что есть одна странная вещь, когда я создаю свое приложение и проверяю, что было построено, там не построено для моей целевой UITest. Это важно?

введите описание изображения здесь

Ответ 1

Это ответ от Apple:

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

Ответ 2

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

Ответ 3

Вместо того, чтобы ваши тесты узнали о вашем приложении, попробуйте включить его и узнайте, что его приложение проверено. Один из способов - использовать свойство launchArguments:

    app = XCUIApplication()
    app.launchArguments.append("TestMode")
    app.launch()

Затем в вашем приложении:

    if NSProcessInfo.processInfo().arguments.contains("TestMode") {
        // I am running in test mode
    }

В вашем случае приложение может затем соответствующим образом установить NSUserDefaults.

Ответ 4

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

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

Ответ 5

Я решил проблему с недоступными символами, вытащив некоторые вещи из моей целевой приложения в две структуры (модель и модель представления), которые затем могу импортировать в свои тесты пользовательского интерфейса.

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

XCTAssertTrue(tables.cells.staticTexts["Cell title I expect to exist"].waitForExistence(timeout: 1))

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

Я также использую аргументы запуска для настройки моего приложения для тестов пользовательского интерфейса, как предложил Майкл: fooobar.com/info/81964/....