现状
我正在编写一个时间表查看应用程序,要实现的第一个功能是选择要查看时间表的类(class)。
用户从列表中选择他们的类(class)名称,然后被带到另一个屏幕以进一步指定他们当前所在类(class)的年份、组别等。选择类(class)和编辑类(class)详细信息的屏幕是如下:
目标
灵感来自 Google I/O 17 talk on Test-Driven Development on Android , 我想写的是一个 UI 测试用例来测试这个功能。具体来说,我希望我的测试能够确认,如果用户单击其中一个类(class)名称,他们将被带到“编辑类(class)详细信息”屏幕,并且类(class)标题位于顶部,例如“会计和财务”与在列表中单击的那个相匹配。
问题
测试,使用Espresso ,对于选择标题为“会计与金融”的类(class)并查看下一个屏幕上是否显示正确标题的特定情况,看起来(大致)如下所示:
@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
类(class)列表将在运行时使用来自 HTTP 请求或 SQLite 数据库的结果填充,并且无法事先知道该列表是否包含“会计和财务” ' 或其他东西(我不希望测试失败只是因为应用程序运行时特定类(class)不在列表中)。
考虑到这一点,我不能将类(class)名称硬编码到测试中。请注意,我不是要编写单元测试,我只是模拟获取类(class)列表的依赖性,以确保“会计与金融”在列表中(并且可能只是隔离ChooseCourseActivity
类,捕获其 Intent
)。
在我上面链接的视频中,演示者通过 UI 测试告诉我们笔记应用程序的添加笔记功能,测试如下:
- 点击“添加备注”按钮
- 输入笔记的标题和描述
- 点击“保存笔记”按钮
- 验证列表中是否包含带有第 2 步详细信息的新笔记
在那种情况下,硬编码用于查找 View 的文本(标题和描述)效果很好,因为测试中的代码确定 View 的内容,即笔记列表中的笔记。在我的例子中, View 的内容将由 HTTP 响应或数据库查询决定
问题
- 如何在实现选择类(class)功能之前为它编写适当的 UI 测试?
- 视频中用于测试笔记应用程序的方法是否根本不适用于我的功能(因为我无法硬编码要从列表中选择的类(class)标题)?
- 我是否只是误解了 UI 测试并且应该是在模拟依赖项(即使视频中的演讲者没有)?
编辑:这个问题的最佳解决方案似乎是所谓的“密封测试”和this blog描述了如何将它应用到 android UI。
最佳答案
您可以通过几种不同的方式对此进行测试,我在我的应用中结合使用了所有这些方式。
1) 您可以按照您的建议模拟您的网络/数据库层。
2) 您可以在测试中调用您的 API 以获取您的“预期”数据集,然后验证它是否正确显示在您的 UI 中。
3) 您可以 stub 您的网络层以允许您注入(inject)已知数据而不依赖于您的网络端点。尤其是改造可以很容易地做到这一点。
4) 您可以使用不会经常更改的已知测试数据集针对实时端点进行测试。
我倾向于将 Espresso 用于 UI 级别测试和全面的回归测试。在 UI 级别测试中,我将网络/设备持久层 stub ,并使用我在测试期间注入(inject)的数据集测试客户端。对于回归测试,我关心测试与我的 API 的集成,对于那些我使用已知不变数据的测试帐户。
关于android - 如何编写在运行时确定 View 内容的 Android UI 测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44806049/