首页 文章 精选 留言 我的

精选列表

搜索[android studio],共10000篇文章
优秀的个人博客,低调大师

编写 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中国”

优秀的个人博客,低调大师

Android应用性能优化最佳实践.2.4 避免过度绘制

2.4 避免过度绘制 过度绘制(Overdraw)是指在屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次重叠的UI结构(如带背景的TextView)中,如果不可见的UI也在做绘制的操作,就会导致某些像素区域被绘制了多次,从而浪费多余的CPU以及GPU资源。 当设计上追求更华丽的视觉效果时,我们很容易陷入采用复杂的多层次重叠视图来实现这种视觉效果的怪圈。这很容易导致大量的性能问题,为了获得最佳性能,必须尽量减少Overdraw情况发生。 我们一般在XML布局和自定义控件中绘制,因此可以看出导致过度绘制的主要原因是: XML布局->控件有重叠且都有设置背景 View自绘-> View.OnDraw里面同一个区域被绘制多次 2.4.1 过度绘制检测工具 要知道是否有过度绘制的情况,可以通过手机设置中的开发者选项,打开Show GPU

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

用户登录
用户注册