编写 android 测试单元该做的和不该做的事
一个新闻 APP 应该会有以下这些 activity。
- 语言选择 - 当用户第一次打开软件, 他必须至少选择一种语言。选择后,选项保存在共享偏好中,用户跳转到新闻列表 activity。
- 新闻列表 - 当用户来到新闻列表 activity,将发送一个包含语言参数的请求到服务器,并将服务器返回的内容显示在 recycler view 上(包含有新闻列表的 id, news_list)。 如果共享偏好中未存语言参数,或者服务器没有返回一个成功消息, 就会弹出一个错误对话框并且 recycler view 将不可见。如果用户只选择了一种语言,新闻列表 activity 有个 “Change your Language” 的按钮,或者如果用户选择多种语言,则按钮为 “Change your Languages” 。 (我对天发誓这是一个虚构的 APP 软件)
- 新闻细节 - 如同名字所述, 当用户点选新闻列表项时将启动这个 activity。
这个 APP 功能已经足够,,让我们深入研究下为新闻列表 activity 编写的测试用例。 这是我第一次写的代码。
/*
Click on the first news item.
It should open NewsDetailActivity
*/
@Test
public void testClickOnAnyNewsItem() {
onView(allOf(withId(R.id.news_list), isDisplayed())).perform(RecyclerViewActions
.actionOnItemAtPosition(1, click()));
intended(hasComponent(NewsDetailsActivity.class.getName()));
}
/**
* To test the correct text on the button
*/
@Test
public void testChangeLanguageFeature() {
int count = UserPreferenceUtil.getSelectedLanguagesCount();
if (count == 1) {
onView(withText("Choose your Language")).check(matches(isDisplayed()));
} else if (count > 1) {
onView(withText("Choose your Languages")).check(matches(isDisplayed()));
}
?}
仔细想想测试什么
在第一个测试用例 testClickOnAnyNewsItem()
, 如果服务器没有返回成功信息,测试用例将会返回失败,因为 recycler view 是不可见的。但是这个测试用例的目的并非如此。不管该用例为 PASS 还是 FAIL,它的最低要求是 recycler view 总是可见的, 如果因某种原因,recycler view 不可见,那么测试用例不应视为 FAILED。正确的测试代码应该像下面这个样子。
/*
Click on any news item.
It should open NewsDetailActivity
*/
@Test
public void testClickOnAnyNewsItem() {
try {
/*To test this case, we need to have recyclerView present. If we don't have the
recyclerview present either due to the presence of error_screen, then we should consider
this test case successful. The test case should be unsuccesful only when we click on a
news item and it doesn't open NewsDetail activity
*/
ViewInteraction viewInteraction = onView(withId(R.id.news_list));
viewInteraction.check(matches(isDisplayed()));
} catch (NoMatchingViewException e) {
return;
} catch (AssertionFailedError e) {
return;
}
//在这里我们确信,news_list的 recyclerview 对用户是可见的。
onView(allOf(withId(R.id.news_list), isDisplayed())).perform(RecyclerViewActions
.actionOnItemAtPosition(1, click()));
intended(hasComponent(NewsDetailsActivity.class.getName()));
}
}
一个测试用例本身应该是完整的
当我开始测试, 我通常按如下顺序测试 activity:
- 语言选择
- 新闻列表
- 新闻细节
因为我首先测试语言选择 activity,在测试 NewsList activity 之前,总有一种语言已经是选择好了的。但是当我先测试新闻列表 activity 时,测试用例开始返回错误信息。原因很简单 - 没有选择语言,recycler view 不会显示。注意, 测试用例的执行顺序不能影响测试结果。 因此在运行测试用例之前, 语言选项必须是保存在共享偏好中的。在本例中,测试用例独立于语言选择 activity 的测试。
@Rule
public ActivityTestRule activityTestRule =
new ActivityTestRule(TopicsActivity.class, false, false);
/*
Click on any news item.
It should open NewsDetailActivity
*/
@Test
public void testClickOnAnyNewsItem() {
UserPreferenceUtil.saveUserPrimaryLanguage("english");
Intent intent = new Intent();
activityTestRule.launchActivity(intent);
try {
ViewInteraction viewInteraction = onView(withId(R.id.news_list));
viewInteraction.check(matches(isDisplayed()));
} catch (NoMatchingViewException e) {
return;
} catch (AssertionFailedError e) {
return;
}
onView(allOf(withId(R.id.news_list), isDisplayed())).perform(RecyclerViewActions
.actionOnItemAtPosition(1, click()));
intended(hasComponent(NewsDetailsActivity.class.getName()));
?}
在测试用例中避免使用条件代码
现在在第二个测试用例 testChangeLanguageFeature()
中,我们获取到用户选择语言的个数,基于这个数目,我们写了 if-else 条件来进行测试。 但是 if-else 条件应该写在你的代码当中,而不是测试代码里。每一个条件应该单独测试。 因此,在本例中,不是只写一条测试用例,而是要写如下两个测试用例。
/**
* To test the correct text on the button when only one language is selected.
*/
@Test
public void testChangeLanguageFeatureForSingeLanguage() {
//Other initializations
UserPreferenceUtil.saveSelectedLanguagesCount(1);
Intent intent = new Intent();
activityTestRule.launchActivity(intent);
onView(withText("Choose your Language")).check(matches(isDisplayed()));
}
/**
* To test the correct text on the button when more than one language is selected.
*/
@Test
public void testChangeLanguageFeatureForMultipleLanguages() {
//Other initializations
UserPreferenceUtil.saveSelectedLanguagesCount(5); //Write anything greater than 1.
Intent intent = new Intent();
activityTestRule.launchActivity(intent);
onView(withText("Choose your Languages")).check(matches(isDisplayed()));
}
测试用例应该独立于外部因素
在大多数应用中,我们与外部网络或者数据库进行交互。一个测试用例运行时可以向服务器发送一个请求,并获取成功或失败的返回信息。但是不能因从服务器获取到失败信息,就认为测试用例没有通过。这样想这个问题 - 如果测试用例失败,然后我们修改客户端代码,以便测试用例通过。 但是在本例中, 我们要在客户端进行任何更改吗?- NO。
但是你应该也无法完全避免要测试网络请求和响应。由于服务器是一个外部代理,我们可以设想一个场景,发送一些可能导致程序崩溃的错误响应。因此,你写的测试用例应该覆盖所有可能来自服务器的响应,甚至包括服务器决不会发出的响应。这样可以覆盖所有代码,并能保证应用可以处理所有响应,而不会崩溃。
正确的编写测试用例与编写这些测试代码同等重要。
原文发布时间为:2017-02-12
本文来自云栖社区合作伙伴“Linux中国”

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
如何在 Ubuntu 上使用 ADB 备份 Android 数据
备份 Android 系统上的应用数据、文本信息等等是非常乏味的,有时还很昂贵。电子市场的许多应用都承诺可以备份数据,但效果不佳或者需要付昂贵费用。你是否知道有一种更好的方法可以来做这件事,并且在你的电脑上就可以完成? Android 自带一套开发工具。有许多种开发工具,但人们最为感兴趣的项目是 ADB(或者叫做Android 调试桥Android Debug Bridge)。它允许用户通过命令行直接访问任何 Android 设备。有了这个工具,一切皆有可能 - 包括备份整个 Android 设备。在这篇文章中,将讨论如何在 Ubuntu 系统上完成这件事。 注:这篇教程是针对 Ubuntu Linux 系统的。不过, ADB 在 Windows 系统和 Mac 上也是可用的,也可以在这些平台上对 Android 数据进行备份。下载针对 Windows 和 Mac 的 ADB 版本。 安装 ADB 并启用 USB 调试 打开一个终端窗口,然后输入下面的命令来安装 ADB,它将与 Android 进行会话。 sudo apt install adb 在系统上安装好 ADB 工具以后,需要...
- 下一篇
ios 实现在一个APP中调起另一个APP(demo)
有时候会遇到在我们自己的app中调起其他app的业务需求,这里写了一个简单的demo,供参考。 1、首先建立两个工程,工程一,工程二,我这里分别叫做“第一个APP”,“第二个APP”,第一个app调起第二个app。 image.png image.png 2、配置要跳转APP的URL Types 在TestSecondApp中做如下配置: image.png 3、配置第一个APP的info.plist 在TestFirstApp中,选中Info.plist,在info.plist中添加一行: LSApplicationQueriesSchemes,array类型。然后添加一个item,string类型,值为在要跳转的app(第二个app)中设置的apptwo image.png 4、在第一个app中跳转代码 第一个app界面如下: image.png 点击“跳转到第二个app”按钮,在按钮事件中写入如下代码: image.png 注意:跳转url一定要加上“://”,这样才能正确的调起。 5、调试: 首先要把第一个app和第二个app编译运行,然后点击第一个app的按钮,就可以进入第二...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品