浅谈 Android 开发文化
Hello,亲爱的读者朋友们(希望你们是 Android 开发者,或者正在成为 Androider 的路上…)!
质量从用户反馈很清凉然后我们就只能看 CPU 原来的想法是但是事实上不是这些但是我们可以把数据收集上来,从长远角度来说,我们呢很简单,怎样摆脱这种要辞职的想法,那我能去哪,要干啥,任何团队都有一定的问题,如果他走,我觉得我还可以接受缺一个告警什么叫我们的团队当时是
Android 开发现在陷入了困境(快陷入七年了…)。大部分程序都没有测试功能(单元测试、集成测试和功能测试);也都忽略了编译和 lint 警告;并且代码都看起来像意大利面(但愿是有反应的意大利面…)等等等等。
坏消息:在 Android 开发文化的源头, Google 就直接参与了这一切。
质量为王
是的,Google 以#执行为王著称,但#质量为王其实是更应该先做到的重要事项。
对质量水平不高的代码进行优化,会造成不成熟的优化,而不成熟的优化也被成为万恶之源(虽然并非绝对,但大多情况下是这样的)。
好消息:像 Square、SoundCloud、Twitter 这样的企业和一些开发者正通过发表演讲、撰写博客,让 Android 开发变得更好,感谢他们!此外, Google 似乎终于对提高 Android 应用程序的质量产生兴趣了!近期, Google 参加了 Android 开发峰会(AndroidDevSummit)和一些其他会议,我们看到了一些关于测试的内容,请继续保持!
现在是时候来提高 Android 开发的质量了。
Android 开发文化暨说明文档。
0. Fail fast 机制:尽快宕机,尽早放弃。
为什么这么说呢?— 因为你要在产品到达用户之前找到问题,那么越快、越早的宕机,对你就越有利,其实这也是你该做的。
本文每一项都会遵循这个基本原则。
1. Pull 请求、代码审核和持续集成
项目开发应该在版本控制系统内完成。开发过程应该通过Pull请求(以下全文简称 PRs),并经过代码审核,否则任何代码都不能直接推送到主开发分支上。每次 PR 会应该触发持续集成(以下全文简称 CI)系统,并构建项目。构建应该是可重复的,每一个队伍里的成员都应该可以轻松地构建项目。
Fail early:如果 PR 的构建在 CI 系统中失败了,在修复完成之前,PR 不要进行合并。
2. 代码质量
你的代码应该是坚实的 或者结实的。如何做到这一点,完全取决于你自己。代码质量并不只和 MVP/MVVM/MVC 有关,同时也和 App 中每个组件的每一行代码有关。笔者更倾向使用纯函数和不可变对象。
Fail early:不要成为项目中唯一编写可维护的代码的开发者,确保其他成员也可以写高质量的代码(和他们聊天,一起讨论本文即可激励他们!),从而防止审核时出现糟糕的代码。
3. 静态代码/资源分析
静态代码分析让你在进入生产环境之前找到代码中的问题。同时,也对代码审核大有裨益。比如使用 Android Lint、FindBugs、PMD、SonarQube 和 FB Infer 等工具。
Fail early:在 CI 中运行静态分析,安装配置后,如果项目中出现警告(不仅仅是错误信息),尽早放弃项目。
4. 单元测试
是的!是测试没错!单元测试通常会检查某个函数/对象是否正确地完成它的工作。项目里的测试越多,代码覆盖率越高, App 在发布后的性能,会更好更稳定。事实上,单元测试可以发现大多数愚蠢的 bug。当然,如果你的 App 会进行数据处理的话,单元测试还将帮助你保证代码工作正常。
Android 项目单元测试的简易指南
笔者倾向于在 JVM 上运行单元测试,因为它比在设备/模拟器上运行快得多。
Android 的 Gradle 插件可以运行在JVM上的单元测试。只要把测试加至
test/ java_or_other_lang
即可。你可以从 IDE 运行测试(右键点击测试->运行)或者从
./gradlew test
终端。你很快就会发现,如果在 JVM 运行单元测试,Android SDK 的类会被清除,触发他们时会抛出异常。这固然可悲,但是是可修复的。如果需要 Android SDK 类的话,可以在 Robolectric 测试运行器下运行,Robolectric 提供了大部分实现 Android SDK 类的方法。
JUnit 提供了很棒的测试工具和相当不错的 Rules 概念,但是 JUnit 的断言很不好用。 AssertJ 和 Truth 等工具对断言的支持很好,并且可以在 JUnit (或 TestNG/Spock 等)下运行。
如果你需要检查行为和复制某些对象,你可以使用 Mockito 之类的复制库。
TDD 与否,取决于你,但绝对值得一试!
Fail early: 在 CI 中运行单元测试,如果有一些测试失败了,则尽早放弃。
5. 代码覆盖率
一旦开始编写单元测试,你便需要知道代码覆盖率是否足够好。
像 Jacoco 这样的工具可以帮助你检查测试程序所走的代码路径。如果你测试的代码表现依赖于条件语句,代码覆盖率就尤为重要,因为你需要确保代码执行中的所有可能都得到检查。
你可以通过apply plugin: ‘jacoco’
语句启用 Jacoco。你可以通过jacocoReport
Gradle 任务配置哪些类/包应该被检查。
如果覆盖率不够高,配置代码覆盖工具使之放弃构建项目。如果你刚刚开始在一个已存在的项目中使用单元测试,除了非测试类,一旦测试代码可以覆盖这些类,就将它们从排除列表中删除。这个规则可以保证新代码的覆盖率。根据覆盖报告,你可以使用 jacoco-coverage
插件放弃构建。
Fail early:确保在 CI 环境中检查代码覆盖率,如果代码覆盖率不够高,尽早放弃构建。
6. 功能(UI)测试
没错!更多的测试。功能测试会从用户的角度检查 APP 的功能。功能测试启动应用程序后,会验证某些功能,比如在 UI 界面中加载出的数据是否正确显示。QA 团队进行的大部分工作可以通过功能测试达到自动化,但这并不意味着你不需要 QA 团队。
运行功能测试有两种基本的方法,在 Android Instrumentation 或 UIAutomator 里运行。最主要的区别是,在 Android Instrumentation 里运行功能测试时只能与应用程序交互,并可以接触到程序代码。在 UIAutomator 里进行的测试会运行在系统进程中,并通过Accessibility API(相比于 Android Intrumentation,此方式的功能十分有限)和应用程序进行交互。如果你需要进行应用程序和其他应用间的交互测试 — 可以使用 UIAutomater。但是通常情况下,你可以通过 Android Instrmentation 模拟这类交互并进行测试,而且这种测试无需依赖外部因素。
建议:
- 优先选择 Android Instrumentation 和 Espresso。
- 测试中的页导向架构会帮助你更加方便快捷地编写和维护程序(比如,当你有一个描述应用的屏幕或部分屏幕的 Page 类时)。
- 与后端模拟交互会完全孤立测试程序,进而并行运行测试,但同时也要确保不要共享测试间的状态。推荐 MockWebServer,非常好用。
- 开发者应该编写功能测试,是的,你没看错。
- 教 QA 团队编写功能测试 — 通常 QA 们和开发者想的不一样,并知道需要检查什么样的情况。
- 检查功能测试的代码覆盖率。
Fail early:在 CI 中运行功能测试,如果一些测试失败的话,则放弃构建项目。
7. 集成测试
是的。依旧是测试。通常情况下,集成测试检查应用程序的不同组件如何协同工作,包括:HTTP 层、REST API 层和执行层(RxJava 等)等等。
设想一个使用了一堆其他类的类,它从后端加载数据,然后进行处理并存储在数据库中。虽然你应该先用单元测试覆盖每个类,但是,你也可以用集成测试来覆盖这种成分复杂的测试。
此处,与单元测试最主要区别在于,你并不是在使用模拟环境,而是对象在测试中的真实实现。你可以模拟数据传输(MockWebServer)和数据库状态,然后运行真实代码,看看它们如何工作。
你可以在 Android Instrumentation 或 JVM 的设备/模拟器上运行集成测试,因为在 JVM 上的测试运行更快 — 笔者更喜欢 JVM。
Fail early:在 CI 中运行集成测试,如果有部分测试失败的,则尽早放弃项目。
8. 开发人员设置菜单(又名:调试抽屉)
调试版本中的开发人员设置菜单允许你启用/禁用 Sthetho、LeakCanary 和 TinyDancer 之类的工具,模拟/改变一些应用程序的行为等等。
在应用运行时更改和检查应用程序,而无需改写代码,会为你和 QA 团队节省大量时间。
Fail early: LeakCanary 这样的工具可以帮助你收到真实用户发来的崩溃报告之前,侦测到问题所在。教你的 QA 团队使用类似的工具,在每次发版前进行验收测试。
That's it.
正文完。
请考虑你的开发文化,并和团队成员讨论这个话题,如此一来,你们正在打造的开发流程和产品质量都可能得到显著改善。
QualityMatters app
所以,你是不是想看看遵循以上原则打造的示例应用呢?点击此处下载 Jake Wharton 遵循以上原则打造的 U2020。以下是令一波遵循了以上原则的 QualityMatters app。
希望你能发现一些新意:
- 单元测试;
- 集成测试;
- 功能测试;
- 静态代码分析;
- 代码覆盖率;
- 开发人员设置菜单;
- MVP、RxJava、Dagger 2 和 Retrofit 2 等等。
QualityMatters app 将会一直维护更新下去。
一封致 Google 的公开信
正如之前所说,#质量 > #表现
- 请多发些关于测试的内容!
- 请测试(单元测试、集成测试和功能测试)库和示例应用程序。
- Android 需要的是 Simulator,而不是 Emulator,因为 Robolectric…虽然毋庸置疑,非常有用,但应该有更好的办法。
- Google 与开发社区结合,可以改进 Android 开发的文化氛围。
所以,我们需要 Android 开发文化!
相关阅读:
- Enabling Android Teams: Tests? Ain't Nobody Got Time For That! by Ty Smith
- Android Testing (Android Dev Summit 2015)
- Droidcon NYC 2015 - Debug Builds: A New Hope
- Insights on Scaling Android Development from Cyanogen, Amazon, Twitter, Square, Eventbrite, and more
原文地址:http://artemzin.com/blog/android-development-culture-the-document-qualitymatters/
OneAPM Mobile Insight,监控网络请求及网络错误,提升用户留存。访问 OneAPM 官方网站感受更多应用性能优化体验,想阅读更多技术文章,请访问 OneAPM 官方技术博客。
本文转自 OneAPM 官方博客
浅谈 Android 开发文化的更多相关文章
- 安卓开发_浅谈Android动画(四)
Property动画 概念:属性动画,即通过改变对象属性的动画. 特点:属性动画真正改变了一个UI控件,包括其事件触发焦点的位置 一.重要的动画类及属性值: 1. ValueAnimator 基本属 ...
- 浅谈Android应用性能之内存
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 文/ jaunty [博主导读]在Android开发中,不免会遇到许多OOM现象,一方面可能是由于开 ...
- 浅谈Android五大布局
Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦.组件按照布局的要求依次排列,就组成了用户所看见的界面.Android的五大布局分别是LinearLay ...
- [转]浅谈Android五大布局(一)——LinearLayout、FrameLayout和AbsoulteLayout
Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦.组件按照布局的要求依次排列,就组成了用户所看见的界面.Android的五大布局分别是LinearLay ...
- 浅谈Android Studio3.0更新之路(遇坑必入)
>可以参考官网设置-> 1 2 >> Fantasy_Lin_网友评论原文地址是:简书24K纯帅豆写的我也更新一下出处[删除]Fa 转自脚本之家 浅谈Android Studi ...
- 浅谈android代码保护技术_ 加固
浅谈android代码保护技术_加固 导语 我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk,结果被人反编译了,那心情真心不舒服.虽然我们混淆,做到native层,但 ...
- 浅谈Android应用保护(一):Android应用逆向的基本方法
对于未进行保护的Android应用,有很多方法和思路对其进行逆向分析和攻击.使用一些基本的方法,就可以打破对应用安全非常重要的机密性和完整性,实现获取其内部代码.数据,修改其代码逻辑和机制等操作.这篇 ...
- 浅谈Excel开发:十一 针对64位Excel的插件的开发和部署
自Office 2010版本开始有了32位和64位之分,对Excel来说,32位的Excel和64位的Excel在性能上的主要区别是64位的Excel能够处理2G及2G以上的大数据集. 随着64位操作 ...
- [转]浅谈Android五大布局(二)——RelativeLayout和TableLayout
在浅谈Android五大布局(一)中已经描述了LinearLayout(线性布局).FrameLayout(单帧布局)和AbsoulteLayout(绝对布局)三种布局结构,剩下的两种布局Relati ...
随机推荐
- bubble_sort
冒泡排序法: #include <iostream> #include <algorithm> using namespace std; int main(){ int n; ...
- [转]SharePoint 2010 Download as Zip File Custom Ribbon Action
在SharePoint 2010文档库中,结合单选框,在Ribbon中提供了批量处理文档的功能,比如,批量删除.批量签出.批量签入等,但是,很遗憾,没有提供批量下载,默认的只能一个个下载,当选择多个文 ...
- <video>和<audio>标签
一.<video>基本格式: <video width=" " heigh="" src=""> </vide ...
- php模板引擎
http://baike.baidu.com/link?url=HmXfdJBv3zpCdnZPeaSmZmqDBHlyTBnz9Rmb5it-jf1_NLHfaku6_i8ssUYbnaTQEBD4 ...
- 解决IE浏览器IFrame对象内存不释放问题
最近项目组发现在使用showModalDialog弹出窗体中如果包含IFrame对象,则IFrame对象占用的内存资源在窗体关闭后不会释放.弹出关闭反复多次后,IE浏览器内存占用可超过数百M,严重时I ...
- 02_Jquery_02_元素选择器
[简述] 元素选择器就是通过元素名来查询元素 $("elementName")这里就可以通过元素名来获取jquery元素了. 但与id选择器不同的是,名称相同的元素有很多,所以获取 ...
- Codevs 1172 Hankson 的趣味题 2009年NOIP全国联赛提高组
1172 Hankson 的趣味题 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description Hanks 博 ...
- 【BZOJ3270】【高斯消元】博物馆
Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博物馆.这座博物馆有着特别的样式.它包含由m条走廊连接的n间房间,并且满足可以从任何一 ...
- vim plugin 原理
vim 个性化设置与功能扩展均通过 script 来实现,这种 script 又叫 plugin.plugin 是 vim 的核心与精髓. 最常用的配置文件 vimrc,也是一种 plugin.换句话 ...
- EF 存储过程(下)
本节,我们将学习如何手动添加/修改存储过程,如何使EF能够支持Output类型的参数 > 添加/修改存储过程 有时候,某个SQL语句比较复杂,但是数据库中又没有定义相应的存储过程.这个时候,我们 ...