Android实战——单元测试从吹水到实践

news/2024/5/20 15:12:21/文章来源:https://blog.csdn.net/willway_wang/article/details/127518413

目录

  • 1.单元测试到底需要不需要了?
    • 开发时间紧张,不需要做单元测试了吧?
    • 开发经验丰富,不需要做单元测试了吧?
    • 或许存在一种”自动化“的测试,就不需要做单元测试了吧?
  • 2.单元测试的好处
    • 单元测试可以有效地降低程序出现 bug 的概率
    • 单元测试允许在任何时候重构,而不必担心破坏现有的代码
    • 单元测试具有回归性
    • 单元测试可以优化我们的代码
  • 3.如何开始进行单元测试?
    • 需要掌握一些单元测试的技术,框架
    • 需要多看看官网上的文档以及代码
    • 需要在项目里面实践

1.单元测试到底需要不需要了?

单元测试简单来说就是开发人员对自己所编写的代码进行测试。

开发时间紧张,不需要做单元测试了吧?

有的会说:还要写代码啊,我哪有时间啊,业务代码我都写不完,还写测试代码啊。

但是,静下来想一想我们的项目周期一般来说时间是比较充裕的,周期一般来说比较长。

开发经验丰富,不需要做单元测试了吧?

有的人可能会说:我从事开发都好几年了,都没有做过单元测试,不一样过来了吗?所以,觉得不做单元测试,也可以活得很好,很开心啊。几年的开发经验,编码功力在,对自己的代码还是很有信心的,单元测试这种简单的玩意儿完全不必要。

但是,我们都知道在 Android 开发领域有一个叫 Jake Wharton 的人,他是 OkHttp,Retrofit,RxJava 等多个著名开源库的主要开发者,曾经入职 Google,据说推动了 Jetpack 这套组件的出现。这样一个人的开发年限想必要比多数人要长,开发经验以及编码功力要比多数人深厚,这点应该是没有异议的。那么,这样一个大佬想必最有资格不做单元测试了。

我们打开 Retrofit 这个开源库,可以看到大佬认真做的单元测试:
在这里插入图片描述

或许存在一种”自动化“的测试,就不需要做单元测试了吧?

有的人可能会想:Android 都已经发展十几年了,想必会有一种"自动化"的测试,会”自动“地去完成我的每一行代码的测试,而我不用去做任何单元测试的代码编写工作。

假如存在这么一种"自动化"的测试,那么 Google 为什么没有推荐给广大的开发者呢?为什么 Android Studio 默认工程模板里面还要去保留 androidTest 和 test 这两个目录呢?根本就不存在的。如果还是心存侥幸,不太甘心,可以打开 Google 的官方文档网站,里面有一个讲解测试的部分(实际上,如果打算看下来这个测试部分的文档,完全没有必要继续阅读本文了),可以看看有没有说这种"自动化"的单元测试。

到这里,小结一下:单元测试并没有过时,还是需要的。

2.单元测试的好处

说一下单元测试的好处,这样大家在单元测试的路上就更有目标,更有劲头了。

单元测试可以有效地降低程序出现 bug 的概率

单单看这一点就足够激动人心了。作为开发人员,哪个不希望自己的 bug 少一点?哪个不希望别人说自己的代码 bug 少?作为公司,交付稳定的代码,自然会增加客户满意度,培养出忠诚的客户。

自己维护的老项目,大多数情况下是没有新需求的,维护的内容主要就是修改客户反馈的问题,有一段时间平均每天都有至少 5 个问题轰炸过来。有些问题,客户有图有日志,确实就是编码上有问题。假如有单元测试的加持与保证,相信有部分 bug,在开发阶段就已经被干掉了,是不会让客户有机会发现的。

不敢奢望自己的代码一点问题都没有,也不去比较谁的代码 bug 多或者少,通过单元测试哪怕可以降低一点点 bug,那么这都是很有意义的一件事情。实际上,随着单元测试覆盖范围的增加,bug 出现的概率也会随之减少的。

单元测试允许在任何时候重构,而不必担心破坏现有的代码

单元测试对某个函数的各种输入输出都进行了测试;如果在重构的时候,改变了这个函数的实现,只需要重新跑一下这个函数的单元测试,就可以确定重构有没有带来问题。

需要说明的是,有的重构可能会破坏掉之前写的单元测试,这时就需要重新编写新的单元测试了。但是,如果重构破坏了很多单元测试的话,可能整个代码架构设计就是有问题的了。

单元测试具有回归性

在针对一个函数或类写好单元测试代码之后,可以随时随地地快速运行测试。也就是说,单元测试作为一种代码的形式,可以使用很多次。

单元测试可以优化我们的代码

看到这点,可能会说单元测试代码只是用来测试业务代码而已,怎么可能优化业务代码呢?这一定是在吹牛,是在放卫星。

真的不是的。

一个我们不愿意面对却是不争的事实是,并不是什么代码都可以直接拿来单元测试的,或者说,只有那些职责清晰,隔离明确的代码才可以很好地进行单元测试。

也就是说,如果要方便顺畅地编写单元测试,首先就要把代码重构成那种好的代码。什么是好的代码呢?满足设计模式七大原则,这点可以参考 Google 的 App Architecture。

这里并不是说我们写的代码就不好,只是按照我们的思维习惯,确实容易写出耦合的代码。只要参考优秀的架构,重新跟着改造一下,就更好了。

3.如何开始进行单元测试?

看到这里,一定想着开始进行单元测试了。但是,不禁会想单元测试怎么做呢?我该怎么开始进行单元测试呢?

不用担心,在单元测试的路上,已经有太多的前辈们走过了。我们并不需要筚路蓝缕,以启山林。

需要掌握一些单元测试的技术,框架

  • JUnit:用于构建测试框架,断言;
  • Mockito,mockk:用于 mock 的库,mockk 是为 Kotlin 而生的 mock 库,这个比较强大;不太推荐大家使用 powermock,easymock,它们俩更新慢,有兼容问题。
  • Hamcrest,Truth:提供强大的匹配器,Hamcrest 用得比较多,Truth 是 Google 出品,应该也很好用的(自己还没有用过)。在进行断言的时候,不仅仅总是判断是否相等,常常需要各种匹配,这两个框架可以满足。
  • Robolectric:如果代码里面有 framework 依赖,但是又想跑单元测试,这个框架可以帮到你。

这些东西的学习略显枯燥,但是不要忘记了 ”磨刀不误砍柴工“。

参考博客:

https://blog.csdn.net/qq_17766199/category_9270906.html?spm=1001.2014.3001.5482

这些文章写得比较早了,但是不少内容并不过时,可以参考学习一下。

各个框架的官网非常值得浏览,这上面的东西一定是最新的,同时也会有一些教程:

Hamcrest:http://hamcrest.org/JavaHamcrest/tutorial

mockk:https://mockk.io/

Robolectric:https://robolectric.org/

需要多看看官网上的文档以及代码

官网测试文档地址:https://developer.android.google.cn/training/testing。官方文档永远都是我们的指明灯,Google 会收集并吸收全世界优秀的开发思想,架构,并体现在文档里面,所以时常来看看这里的更新是很有好处的。
在这里插入图片描述
官网上的测试部分有两个 codelab,提供了手把手的单元测试教学,具有很强的实操性,非常具有学习价值
https://developers.google.cn/codelabs/advanced-android-kotlin-training-testing-basics#0

https://developers.google.cn/codelabs/advanced-android-kotlin-training-testing-test-doubles#0

从两个 codelab 里面学习到一些东西,这里也写一下:

把 iovue 的数据源封装在接口之下,也就是说,从 hmi 角度看 iovue,iovue 不过是检测,下载,安装,查询这几个接口的实现而已,hmi 层不再关心 iovue 内部是如何实现的,只关心这些接口会得到哪些情形的数据即可。这样,我们完全可以构建出一个实现了这些接口的假的 iovue 了,它就可以向 hmi 返回与真正的 iovue 一样的数据了,极大地方便了单元测试。其实,这就是应用了设计模式的依赖倒置原则(dependence inversion principle),也叫面向接口编程,通俗来说,就是增加了一个隔离层而已。

codelab 提供了一些测试的最佳实现,例如如何使用 Android Studio 生成测试类,如何在 Android Studio 里面查看测试结果,如何测试获得 LiveData 的可观察数据,如何命名一个测试,如何设计自己的测试(Given,When,Then 三大步),如何测试使用了协程的代码(如果是使用了 RxJava,可以参考 https://weilu.blog.csdn.net/article/details/78989664)。

需要在项目里面实践

这点觉得有点多余,但是还是啰嗦啰嗦。

单元测试是要写代码的,刚开始写单元测试可能会很累,想放弃,”万事开头难“,请坚持下去,坚持把从博客,官网,codelab 里面学习到的东西尽可能地应用起来;就这样一周或者两周后,就可以感受到写单元测试的快乐了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_218369.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【附源码】计算机毕业设计SSM校园拍卖平台

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

React 状态管理器,我是这样选的

前言 我们的前端团队在一直深度使用 React ,从最早的 CRA ,到后来切换到 umijs ,从 1.x、2.x、3.x 再到现在的 4.x,其中有一点不变的,就是我们一直在使用基于 react-redux 思想的 dva 作为状态管理工具。 在状态共享这…

(附源码)计算机毕业设计SSM跨移动平台的新闻阅读应用

(附源码)计算机毕业设计SSM跨移动平台的新闻阅读应用 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目…

DM-DM DBLINK使用配置

简单介绍 DM-DM DBLINK支持3种连接方式创建,分别是:dmmal、dpi、odbc。 其中dpi、odbc属于第三方接口,dmmal属于原生接口。dpi类型dblink为新版本新添加支持,以前版本中不支持。 环境说明 (1)数据库版本…

2023届C/C++软件开发工程师校招面试常问知识点复盘Part 7

目录46、C类的成员变量初始化顺序及拓展47、强制转换类型操作符号48、const 成员函数–常成员函数与常量对象49、volatile关键字50、赫夫曼树51、前缀树46、C类的成员变量初始化顺序及拓展 注意: 1、const成员或者引用必须在成员变量初始化列表中初始化,…

git的基础指令操作

git的下载地址:https://git-scm.com/download 安装好git后 在桌面上右键即可以看到两个git的快捷方式。 需要先对git进行基本的配置,即需要配置用户名和用户邮箱 1. 打开Git Bash 2. 设置用户信息 git confifig --global user.name “zqy” git confi…

权限项目 1_搭建环境

硅谷通用权限系统:搭建环境 一、项目介绍 1、介绍 权限管理是所有后台系统都会涉及的一个重要组成部分,而权限管理的核心流程是相似的,如果每个后台单独开发一套权限管理系统,就是重复造轮子,是人力的极大浪费&…

第 1 章之:二叉树特性

声明:文章为博主原创,转载请联系博主。文章若有错误和疏漏之处,还望大家不吝赐教! 第一章:数据结构与算法基础--------------------------- 本章重点内容为&#xff1…

基于麻雀算法二维oust图像分割算法研究附matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

期刊|认知科学领域期刊《Trends in Cognitive Sciences》

Hello,大家好! 这里是壹脑云科研圈,我是Ns~ 今天我们介绍的是爱思维尔(Elsevier)旗下细胞出版社(cell press)发行的关于认知科学领域的期刊:Trends in Cognitive Sciences。 1 期刊简介 基本…

mysql之给字符串加索引

文章目录前言长字段加索引前缀索引对覆盖索引的影响合理的使用前缀索引总结前言 之前的文章介绍了主键索引和唯一索引的区别,也介绍了主键索引和唯一索引在不同业务场景下的区别。今天我们继续介绍,普通索引怎么合理的使用。 长字段加索引 这里我们就…

Spring6.0全新发布,快来看看

Spring6.0全新发布,快来看看 Spring Framework 6.0 发布了首个 RC 版本。 翻译后页面(有点好笑): On behalf of the team and everyone who has contributed, I am pleased to announce that Spring Framework is available now.6.0.0-RC2 Spring Frame…

零信任如何给为企业的数字资源保驾护航?

零信任安全最早由著名研究机构Forrester的首席分析师约翰.金德维格在2010年提出。 零信任安全针对传统边界安全架构思想进行了重新评估和审视,并对安全架构思路给出了新的建议。 零信任模型是什么 零信任是一种基于严格身份验证的网络安全架构。、 在该架构下&am…

【SpringBoot笔记12】SpringBoot框架实现文件上传和文件下载

这篇文章,主要介绍如何使用SpringBoot框架实现文件上传和文件下载。 目录 一、SpringBoot文件上传 1.1、引入依赖 1.2、编写文件上传页面 1.3、编写文件上传代码 (1)MultipartFile对象 (2)ResourceUtils工具类 …

音频拼接在一起怎么做?这篇文章来告诉你

随着互联网的发展,很多优质歌曲都纷纷地呈现在大家眼前,而将不同的音乐合并在一起,并且放入视频里,也是别有一番风味,那么许多人会好奇音频如何拼接在一起呢?下面就为大家分享两个好用的方法,只要一点时间…

【C++】使用对象自动管理指针(用到运算符重载)

文章目录1. 首先设计整型类&#xff1a;class Int普通指针2. 设计一个Object类&#xff0c;并设计Int类型的指针。那如何获取Int类型的值呢&#xff1f;1. 首先设计整型类&#xff1a;class Int class Int { private:int value; public:Int(int x 0) :value(x){cout <<…

Springbootg整合validation整合

坚持年年写博客&#xff0c;不能断了&#xff0c;所以粘贴平时写的一份笔记吧 一、简介 校验参数在以前基本都是使用大量的if/else&#xff0c;稍微方便一点的可以使用反射自定义注解的形式&#xff0c;但是复用性不是很好&#xff0c;并且每个人对于的自定义注解有着自己的使…

Java基础-任务执行服务

今天小编带领大家一起来探索Java中的任务执行服务 关于任务执行服务&#xff0c;我们介绍了&#xff1a; 任务执行服务的基本概念。 主要实现方式&#xff1a;线程池。 定时任务。 &#xff08;1&#xff09;基本概念 任务执行服务大大简化了执行异步任务所需的开发&…

算法 - 最少交换次数来组合所有的 1 II

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 2134. 最少交换次数来组合所有的 1 II - 力扣&#xff08;LeetCode&#xff09; 题目描述 交换定义为选中一个数组中的两个 互不相同 的位置并交换二者的值。 环形数组是一个数组&#xff0c;可以认为 第…

第五章:乱序执行

1.概念 指令在执行时常常因为一些限制而等待。例如&#xff0c;MEM单元访问的数据不在cache中,需要从外部存储器中取&#xff0c;这个过程通常需要几十、几百个Cycle&#xff0c;如果是顺序执行的内核,后面的指令都要等待&#xff0c;而如果处理器足够智能&#xff0c;就可以先…