【问题标题】:Testing Cognito Authentication in iOS App在 iOS 应用程序中测试 Cognito 身份验证
【发布时间】:2019-03-18 15:41:27
【问题描述】:

我有一个带有 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 的各种响应

我该怎么做?

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

【问题讨论】:

    标签: ios swift aws-sdk amazon-cognito aws-sdk-ios


    【解决方案1】:

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

    你需要做三件事:

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

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

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

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

    【讨论】:

    • 感谢您花时间回答。
    • 不客气。对不起,我不能更具体,这个问题没有得到更多的答案。我希望你设法以某种方式完成 UI 测试。也可能有针对真实登录 API 进行测试的案例,但我通常也会自己模拟它,祝你好运!
    猜你喜欢
    • 2020-12-20
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2019-01-13
    • 1970-01-01
    • 2014-09-30
    • 2016-12-11
    相关资源
    最近更新 更多