如何编写在运行时确定视图内容的 Android UI 测试?
Posted
技术标签:
【中文标题】如何编写在运行时确定视图内容的 Android UI 测试?【英文标题】:How to write an Android UI test where the contents of views are determined at runtime? 【发布时间】:2017-06-28 14:55:50 【问题描述】:情况
我正在编写一个时间表查看应用程序,要实现的第一个功能是选择要查看时间表的课程。
用户从列表中选择他们的课程名称,然后转到另一个屏幕,以进一步指定他们当前所在课程的年份、组等。选择课程和编辑课程详细信息的屏幕是如下:
目标
受Google I/O 17 talk on Test-Driven Development on android的启发,我想写一个UI测试用例来测试这个功能。具体来说,我希望我的测试确认如果用户单击其中一个课程名称,他们将被带到“编辑课程详细信息”屏幕,并且课程标题位于顶部,例如'Accounting and Finance' 匹配列表中被点击的那个。
问题
使用Espresso 的测试针对选择标题为“会计与金融”的课程并查看下一个屏幕上是否显示正确标题的特定情况,看起来(大致)如下所示:
@Test
public void chooseCourse()
onView(withId(R.id.rv_course_list))
.perform(RecyclerViewActions.actionOnItemAtPosition(
/*Somehow find position of Accounting and Finance*/,
click())
);
onView(withId(R.id.course_title))
.check(matches(withText("Accounting and Finance")))
.check(matches(isDisplayed()));
我的问题是RecyclerView
课程列表将在运行时使用来自 HTTP 请求或 SQLite 数据库的结果进行填充,并且无法事先知道该列表是否包含“会计和财务”或其他内容(我不希望测试因为应用程序运行时列表中没有特定课程而失败)。
考虑到这一点,我无法将课程名称硬编码到测试中。请注意,我不是在尝试编写单元测试,我只是模拟获取课程列表的依赖关系,以确保“会计和财务”在列表中(并且可能只是隔离ChooseCourseActivity
类,捕获其 Intent
s)。
在我上面链接的视频中,演示者向我们介绍了一个笔记应用程序的添加笔记功能的 UI 测试,测试如下:
-
点击“添加注释”按钮
输入备注的标题和说明
点击“保存笔记”按钮
验证列表中是否包含包含步骤 2 详细信息的新注释
在这种情况下,硬编码用于查找视图的文本(标题和描述)效果很好,因为测试中的代码确定视图的内容,即注释列表中的注释。就我而言,视图的内容将由 HTTP 响应或数据库查询确定
问题
如何在实现选择课程功能之前为它编写足够的 UI 测试? 视频中用于测试笔记应用程序的方法是否根本不适用于我的功能(因为我无法硬编码要从列表中选择的课程名称)? 我是否只是误解了 UI 测试并且应该模拟依赖项(即使视频中的演讲者没有)?编辑:这个问题的最佳解决方案似乎是所谓的“密封测试”,this blog 描述了如何将其应用于 android UI。
【问题讨论】:
【参考方案1】:您可以通过几种不同的方式对此进行测试,我在我的应用程序中使用了所有这些方式的组合。
1) 您可以按照您的建议模拟您的网络/数据库层。
2) 您可以在测试中调用 API 以获取“预期”数据集,然后验证它是否正确显示在您的 UI 中。
3) 您可以存根您的网络层以允许您注入已知数据而不依赖于您的网络端点。尤其是改造让这件事变得非常容易。
4) 您可以使用不会经常更改的已知测试数据集针对实时端点进行测试。
我倾向于将 Espresso 用于 UI 级别测试和全面回归测试。在 UI 级别测试中,我将网络/设备持久层排除在外,并使用我在测试期间注入的数据集来测试客户端。对于回归测试,我关心的是测试与我的 API 的集成以及那些我使用已知数据不变的测试帐户的测试。
【讨论】:
我认为结合使用选项 1 和 2 将涵盖它。谢谢。以上是关于如何编写在运行时确定视图内容的 Android UI 测试?的主要内容,如果未能解决你的问题,请参考以下文章