如何在Espresso UI测试中实施Jake Wharton的机器人模式?

Oll*_*e C 5 android android-testing android-espresso

杰克·沃顿(Jake Wharton)发表了精彩的演讲,他提出了一些聪明的方法来改善我们的UI测试,方法是从测试中抽象出我们如何执行UI的细节:https//news.realm.io/news/kau-jake-wharton-testing -机器人/

他给出的一个示例是如下所示的测试,其中PaymentRobot对象包含有关如何将付款金额和收件人输入UI的详细信息。将其放在一个地方很有意义,因此当UI不可避免地发生更改时(例如,重命名字段ID或从TextEdit切换到TextInputLayout),它只需要在一个地方进行更新,而无需进行一系列的测试。它还使测试更加简洁和易读。他建议使用Kotlin使它们更整洁。我不使用Kotlin,但仍然想从这种方法中受益。

@Test public void singleFundingSourceSuccess {
    PaymentRobot payment = new PaymentRobot();
    ResultRobot result = payment
        .amount(42_00)
        .recipient("foo@bar.com")
        .send();
    result.isSuccess();
}
Run Code Online (Sandbox Code Playgroud)

他提供了一个关于如何构造Robot类的概述,并带有显式的isSuccess()响应,并返回了下一个屏幕或当前屏幕的状态的另一个Robot:

class PaymentRobot {
    PaymentRobot amount(long amount) { ... }
    PaymentRobot recipient(String recipient) { .. }
    ResultRobot send() { ... }
}

class ResultRobot { 
    ResultRobot isSuccess() { ... }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 机器人如何与活动/片段进行交互,特别是在何处进行实例化?我希望跑步者在测试中会发生这种情况,但是他的例子似乎暗示了其他情况。该方法看起来可能非常有用,但我看不到如何在实践中实现它,无论是针对单个Activity / Fragment还是针对它们的序列。
  • 如何扩展此方法,以便isSuccess()方法可以处理各种情况。例如,如果我们正在测试登录屏幕,则isSuccess()如何处理各种预期结果,例如:身份验证成功,API网络失败和身份验证失败(例如403服务器响应)?理想情况下,应在Retrofit之后模拟API,并使用端到端UI测试来测试每个结果。

除了Jake的概述演讲之外,我找不到任何实现示例。

Bar*_*ski 1

机器人如何与活动/片段交互,具体是在哪里实例化的?我预计这种情况会在跑步者的测试中发生,但他的例子似乎表明情况并非如此。该方法看起来非常有用,但我不知道如何在实践中实现它,无论是对于单个 Activity/Fragment 还是对于它们的序列。

Robot应该是用于测试目的的实用程序类。Fragment它不应该是作为您/或您想要使用的任何内容的一部分包含的生产代码Activity。杰克的比喻非常完美。其Robot行为就像一个人与应用程序的屏幕进行交互。因此,a 公开的 apiRobot应该是特定于屏幕的,无论您的实现是什么。它可以跨多个activitiesfragmentsdialogs等,也可以反映与单个组件的交互。这实际上取决于您的应用程序和您拥有的测试用例。


如何扩展这种方法以便 isSuccess() 方法可以处理各种场景。例如,如果我们正在测试登录屏幕,isSuccess() 如何处理各种预期结果,例如:身份验证成功、API 网络失败和身份验证失败(例如 403 服务器响应)?理想情况下,API 将在 Retrofit 后面进行模拟,并通过端到端 UI 测试来测试每个结果。

您的 APIRobot确实应该指定您的测试内容。不是如何。因此,从使用的角度来看,Robot它不会关心你是否遇到API 网络故障身份验证失败。就是这样。“你怎么就失败了呢”。人类 QA 测试人员 ( === Robot) 不会通过查看 http 流来注意到 api 失败或 http 超时之间的区别。他/她只会看到您的屏幕上写着Failure。他们Robot只会关心那是否是一个SuccessFailure

您可能想要在此处测试的另一件事是您的应用程序是否显示一条消息,通知用户连接错误(无论确切原因是什么)。

class ResultRobot { 
    ResultRobot isSuccess() { ... }
    ResultRobot isFailure() { ... }
    ResultRobot signalsConnectionError() { ... }
}
Run Code Online (Sandbox Code Playgroud)

result.isFailure().signalsConnectionError();
Run Code Online (Sandbox Code Playgroud)