4

我有一个带有 Cognito 身份验证的 iOS 应用,其实现与CognitoYourUserPoolsSample非常相似。最重要的片段在SignInViewController.swift中:

  1. 当用户点击登录时,会添加异步任务:

    var passwordAuthenticationCompletion: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>?
    ...
    @IBAction func signInPressed<...> {
        ...
        let authDetails = AWSCognitoIdentityPasswordAuthenticationDetails(username: self.username.text!, password: self.password.text! )
        self.passwordAuthenticationCompletion?.set(result: authDetails)
        ...
    
  2. 稍后我们会得到成功或错误响应:

    extension SignInViewController: AWSCognitoIdentityPasswordAuthentication {
          public func getDetails<...> {
              DispatchQueue.main.async {
                  // do something in case of success
          ...
    
          public func didCompleteStepWithError<...> {
              DispatchQueue.main.async {
                 // do something in case of failure
          ...
    

我还有一个 UI 测试,填写用户名和密码,点击登录并验证响应:

class MyAppUITests: XCTestCase {
    ...
    func loginTest() {
        let usernameField = <...>
        usernameField.tap()
        usernameField.typeText("user@domain.com")
        ... 
        // same for password field
        // then click Sign In
        <...>.buttons["Sign In"].tap()

目前,此测试针对的是实际的AWS 基础设施,由于许多原因,这并不理想。我想要的是模拟来自 AWS 的各种响应

我怎样才能做到这一点?

我认为最好的办法是嘲笑或刺伤任务队列,但我不知道如何处理。任何方向将不胜感激。如果您以其他方式处理类似任务,我也想听听您的想法,谢谢。

4

1 回答 1

3

好的,我对 AWS iOS 开发工具包以及它是如何实现身份验证流程的不太熟悉,因此请对以下内容持保留态度。我希望这不是一个完整的答案,而是一个一般的“策略”。我在我当前的项目中实现了类似的方法,不仅用于登录,而且实际上是我建立的所有远程连接。

你需要做三件事:

  1. 在您的 UI 测试目标中运行一个小型本地网络服务器。在我当前的项目中,我使用EmbassyAmbassador。将其配置为返回 Cognito(或另一个端点)通常给出的任何响应。我只是curl手动编辑了一个请求并将响应保存在某处,但在我的情况下,我收到了纯数据(而不是,例如,在 webview 中显示的完整登录页面......)。我的猜测是,Cognito 实际上显示了一个登录(网络)视图,并且在成功登录时使用深层链接“返回”到您的应用程序,最终调用您的AWSCognitoIdentityPasswordAuthentication方法(成功或错误)。您可以有测试目标,即如果您知道深层链接的外观(应该可以找到?),则网络服务器直接调用深层链接。

  2. 添加一些机制以在测试期间切换 Cognito 端点。不幸的是,这需要添加生产代码,但如果做得好,应该不会太难。我通过使用我在测试期间设置的启动环境变量来做到这一点(见下文)。除非您的网络服务器支持 https(Embassy 没有开箱即用),否则这也需要以某种方式配置 App Transport Security。最难的部分肯定是弄清楚端点在 SDK 中的哪个位置构建以及如何更改它。快速浏览一下文档让我相信webDomain是它保存的地方,但我看不到它是如何设置的。该属性甚至是只读的,这使事情变得复杂。不过,我假设您可以在项目中的某些配置中更改它?否则,它就像是方法混用的案例......对不起,我不能在这里提供更多的声音指导。

  3. 在您的测试期间,确保将在相关应用程序流程期间访问的真实端点切换到http://localhost/.... 我是通过 using 做到的XCUIApplication().launchEnvironment["somekey"] = "TESTINGKEY",这与我在第二步中的生产代码准备相匹配。在我的情况下,我可以简单地加载不同的端点(具有 localhost 域以及与原始域相同的路径)。根据测试用例(成功登录、无效凭据等)配置您的网络服务器的响应。

我承认这是/是很多工作,但对我来说这是值得的,因为我可以在没有任何网络访问权限的情况下轻松运行整个应用程序流程(其中涉及大量传出请求)。无论如何,我必须自己实现我们的身份验证系统,这让我可以很好地控制使用哪些 URL 以及在哪里使用,从而可以很容易地根据启动环境变量在一个地方存根它们。在我的案例中,最丑陋的部分实际上是仅在我的测试中启用 ATS 异常,为此我不得不使用运行脚本,原因有多种。

于 2018-10-19T08:47:52.840 回答