区分 UI 测试的首次启动

Posted

技术标签:

【中文标题】区分 UI 测试的首次启动【英文标题】:Distinguishing first launch on UI Tests 【发布时间】:2017-12-06 13:16:36 【问题描述】:

我想使用 Fastlane Snapshot 为我的应用生成屏幕截图。但是应用程序在第一次启动和之后启动时的行为是不同的。 我如何设法获得一致的行为以获取屏幕截图? (这个问题也与我认为的任何 UI 测试所需的一致性有关)

【问题讨论】:

【参考方案1】:

您应该使用UserDefaults 类来保存应用中的数据,以便您可以在测试中存根数据。

如果我们假设您用来查看它是否是第一次启动的 Bool 键是 isFirstTime,为了在您的 UI 测试中存根它,您应该在值 YES 或 @ 之后将它传递给 launchArguments 987654328@(用于布尔值)。请注意,我在键之前添加了- 符号,这是它的工作方式:

class FirstTimeLaunchTest: XCTestCase 

    let app = XCUIApplication()

    override func setUp() 
        super.setUp()
        continueAfterFailure = false

        app.launchArguments += ["-isFirstTime", "YES"]
        app.launch()
    

    func testWelcomeScreenShown() 
        XCTAssert(app.navigationBars["Welcome"].exists)
    

对于您希望首先跳过的测试,请使用此类:

class LaterLaunchesTest: XCTestCase 

    let app = XCUIApplication()

    override func setUp() 
        super.setUp()
        continueAfterFailure = false

        app.launchArguments += ["-isFirstTime", "NO"]
        app.launch()
    

    func testMainAppScreenShown() 
        XCTAssert(app.navigationBars["My App"].exists)
    

一个注意:如果您使用SwiftyUserDefaults 库,此解决方案将不起作用。当前版本的库中存在一个问题,将YESNO 字符串转换为truefalse 无法按预期工作。有一个PR解决了这个问题(即被拒绝),但是要解决这个问题,你可以看看this answer的解决方案#2和#3。

【讨论】:

决定是否首次启动的不一定是启动参数,而是应用程序是否已安装在模拟器上。例如,我有一个“位置权限”警报,它将弹出并需要与之交互。如果我理解正确,我将不得不在实际运行时模拟“第一次未运行”的应用程序。 没有办法知道你的应用程序之前是否安装在模拟器上。此外,您的问题不好,因为您没有描述第一次和每次运行应用程序时有什么区别。但是,根据您的评论,由于您在用户第一次启动应用程序时询问位置,据我所知,无法多次模拟显示系统对话框。我试图为此找到解决方案,但没有运气。如果你愿意,如果你使用UserDefaults,你可以试试这两个测试。将launchArguments 添加到应用程序是一种在UI 测试中存根UserDefaults 数据的方法。

以上是关于区分 UI 测试的首次启动的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 如何区分 UI 和单元测试,以及如何在这种具体情况下使用它们?

如何使用 XCTest UI 测试区分 iOS 13 中的标题和静态文本

如何设置 iOS 应用程序的首次启动

检测iOS应用程序的首次启动[重复]

仅为 AppDelegate.m iOS 中的首次启动设置特定方向

检测应用程序的首次运行