如何在Xcode中的UITests之间保持应用程序打开

时间:2015-12-15 15:47:32

标签: xcode-ui-testing

我有一系列的UITests我想作为单独的测试运行,但我不想在每次测试之间重新启动应用程序。如何启动应用程序并使其保持打开状态,以便它不会在测试之间关闭和重新启动。

我尝试在init()中使用XCUIApplication()。launch()但是出错了。

4 个答案:

答案 0 :(得分:6)

setUp()方法中,移除[[[XCUIApplication alloc] init] launch];并将其放入您将要执行的第一个测试中。

例如,

如果你有测试:testUI(),testUIPart2(),testUIPart3()等,它按此顺序运行,将[[[XCUIApplication alloc] init] launch];放入testUI()的第一行,而不是其他地方。< / p>

答案 1 :(得分:4)

改善@James Goe的答案 -

为了避免所有这些重新启动,但保持运行单个测试的能力 - 而不关心它们运行的​​顺序 - 您可以:

class MyTests: XCTestCase {
    static var launched = false

    override func setUp() {
        if (!MyTests.launched) {
            app.launch()
            MyTests.launched = true
        }

(当然,既然你没有重新启动你的应用程序,你必须更关心国家,但这是另一个故事。它肯定更快。)

答案 2 :(得分:1)

这个问题有点老了,但是XCTestCase具有setup()tearDown()的类func,它在第一个测试之前和最后一个测试完成之后执行。如果您将XCUIApplication()创建为一个单例(例如XCUIAppManager),则可以将XCUIAppManager.shared.launchApp()调用放在override class func setup()方法内...这将仅在每个XCTestCase一次启动该应用程序(包含多个测试)

override class func setUp() { // 1.
    super.setUp()
    // This is the setUp() class method.
    // It is called before the first test method begins.
    // Set up any overall initial state here.
}

https://developer.apple.com/documentation/xctest/xctestcase/understanding_setup_and_teardown_for_test_methods

示例应用管理器单例实现:

import XCTest

class XCUIAppManager {
    static let shared = XCUIAppManager()
    let app = XCUIApplication(bundleIdentifier: "com.something.yourAppBundleIdentifierHere")
    private(set) var isLaunched = false

    private init() {}

    func launchApp() {
        app.launch()
        isLaunched = true
    }
}

答案 3 :(得分:0)

这是另一种允许在每次测试中同时启动常见或不常见应用程序的方法。

您可以通过创建自定义XCUIApplication来做到这一点,并在应用启动中包含状态,如下所示。

import XCTest

class MyUIApplication: XCUIApplication {
    private(set) var isLaunched = false
    static let shared = MyUIApplication()

    private override init() {
        super.init()
        
        // add your launch arguments and environment keys
        launchArguments += ["isRunningTests"]
        launchEnvironment["state"] = "InitState"
    }

    func launchIfNeeded(at state: AppState) {
        if !isLaunched {
            launch(at: state)
        }
    }

    func launch(at state: AppState) {
        switch state {
        case .home:
            launchEnvironment["state"] = "InitState"
        ...
        }

        launch()
        isLaunched = true
    }
}

具有上述解决方案的测试用例的示例:

class MyViewControllerTests: XCTestCase {
    let app = VFGUIApplication.shared

    override func setUp() {
        super.setUp()

        app.launchIfNeeded(at: .home)
    }
}

如果您正在与团队合作,并且要确保根据预定义的launchArgumentslaunchEnvironment等正确执行启动,则这特别可取。