【问题标题】:Is it possible to open a screen directly in XCUITest?是否可以直接在 XCUITest 中打开屏幕?
【发布时间】:2018-08-07 18:54:46
【问题描述】:

比方说,我有 3 个屏幕,

  1. 登录
  2. 忘记密码
  3. 帮助屏幕

默认情况下,登录屏幕会在应用启动时打开。单击“忘记密码”按钮会显示“忘记密码”屏幕,单击“帮助”链接会打开“帮助”屏幕。

我可以不通过使用XCUITest点击按钮的过程直接打开忘记密码屏幕吗?

我建议的内容与传递 adb 意图以直接打开视图相同。

【问题讨论】:

    标签: swift testing xcode-ui-testing xcuitest


    【解决方案1】:

    据我所知,您不能使用 XCUITest 框架直接进入第二个屏幕。无论如何,documentation 表示:

    UI 测试以与用户在不访问您应用的内部方法、函数和变量的情况下执行相同的方式来测试您应用的 UI。这使您的测试能够以与用户相同的方式查看应用程序,从而暴露用户遇到的 UI 问题。

    这意味着如果您的应用的用户不能直接到达第二个屏幕,为什么您的 UI 可以测试。

    我知道在运行测试时等待进入第二个屏幕非常耗时,但您可以绕过为每个测试编写它。要只编写一次,请在 XCTestCase 类中编写一个函数,在其中实现调用第二个屏幕并在 setUp() 方法中调用该函数。然后,每次运行测试时都会调用跳过第一个屏幕的过程,因为每次运行测试之前都会调用setUp() 方法。

    编辑

    阅读您的评论后,我可以想到一个 hacky 解决方案。您可以使用 Launch Environment 和/或 Launch Arguments 从测试中与您的应用程序进行通信。因此,在您的 XCTestCase 类中,设置参数和环境:

    class ForgotPasswordUITest: XCTestCase {
        let app = XCUIApplication()
    
        override func setUp() {
            app.launchArguments += ["UI-TESTING"]
            app.launchEnvironment["pageToGo"] = "forgotPassword"
            app.launch()
        }
    }
    

    然后,在您的 ViewController 中,编写这些计算属性:

    var isUiTestingEnabled: Bool {
        get {
            return ProcessInfo.processInfo.arguments.contains("UI-TESTING")
        }
    }
    
    var shouldShowForgotPassword: Bool {
        get {
            return ProcessInfo.processInfo.environment["pageToGo"] == "forgotPassword"
        }
    }
    
    var shouldShowHelpScreen: Bool {
        get {
            return ProcessInfo.processInfo.environment["pageToGo"] == "helpScreen"
        }
    }
    

    viewDidLoad() 方法中,你可以有这样的东西:

        if isUiTestingEnabled {
            if shouldShowForgotPassword {
                let storyboard = UIStoryboard(name: "Main", bundle: nil)
                let secondViewController = storyboard.instantiateViewController(withIdentifier: "ForgotPasswordViewController")
                self.present(secondViewController, animated: true, completion: nil)
            } else if shouldShowHelpScreen {
                let storyboard = UIStoryboard(name: "Main", bundle: nil)
                let secondViewController = storyboard.instantiateViewController(withIdentifier: "HelpScreenViewController")
                self.present(secondViewController, animated: true, completion: nil)
            }
        }
    

    注意:这是一个非常肮脏的 hack,不推荐使用这种方式编写 UI 测试。

    【讨论】:

    • @logoman 这是一个很好的答案。我完全同意你的看法。但是在某些时候,您已经测试了流程并且实际上不需要一遍又一遍地进行测试。从而加快测试速度。我赞成您的回答,但我会等待更多答案。即使有一种 hacky 的方式来做到这一点。
    • @Vinayaka,我编辑了我的答案,添加了一个 hacky 解决方案。
    • @lagoman 使用启动参数和/或启动环境从 UI 测试到应用程序进行通信是一个巧妙的解决方案,很好。不过,我对采用它持怀疑态度,正如你所说的那样,它有点像黑客攻击。让我担心的是我们必须编写额外的代码来建立这种关系。我不喜欢用仅用于测试的代码“污染”生产代码。与软件开发一样,这是一个权衡问题。 UI 测试套件更快的运行时间是否值得额外的代码来维护?这取决于项目:)
    • @mokagio,同意:)
    • @lagoman 我认为您可以直接进入屏幕的解决方案是完美的,因为除了使用 environment/launch 参数之外我没有看到任何其他方法。
    猜你喜欢
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多