软件代码与质量管理(更新版)(二)

简介: 软件代码与质量管理(更新版)(二)

发者学习笔记【阿里云DevOps助理工程师认证(ACA)课程软件代码与质量管理(更新版)(二)

课程地址:https://edu.aliyun.com/course/3112069/lesson/18999


软件代码与质量管理(更新版)(二)


二、代码规约

下面第二部分我们学习代码规约。代码规约大致分成这么几个部分,大家看蓝色的这部分主要是命名和常量和格式这一方面。还有一些是语言层面的上的,比如像 OOP 的规约集合处理和并发,这个和语言的相关性比较大,另一些叫控制语句和注释,还有一些不太好归类的,归到其他类别里。

图片182.png

范例

首先第一个命名规约,我们在变量命名的时候是不允许下划线,美元符号出现在变量的开头或者结尾。

【命名命名规约-1】_name,_name,Object,name,nameObject,name_,name.Object$,

因为其实在 Java 里,编译器是可以通过编译的,这些现在大家看到的这几个变量都是一个合法的 Java 变量。


为什么我们在代码规范里面不允许出现这样的变量

首先是因为下划线在一些特殊的环境下是有特殊的意义的,比如编译器会用到的特殊变量名字,或者是操作系统的内核里面特殊的一些变量名字会用下划线作开头或者结尾。 美元符号是另一回事,因为在脚本语言里面,比如像在 shell 里面或在 Pearl 里面,美元符号是保留字,它代表着变量,所以我们也不建议在 Java 变量里面用美元符号,这样会导致混淆。


第二个命名规约,就是不允许用拼音和英文的混合,或者是用中文,或者是用拼音。所有的变量都应该使用标准的英文。DaZhePromotion[打折]/ getPingfenByName()[评分]/int 变量=3为什么呢?是因为拼音会产生歧义,因为英文单词它本身就是一个单词,大家知道是什么拼音可能写的时候命名这个变量时,并没有想的那么周到,这个拼音有可能变成一个其他的拼音法,所以我们在命名变量的时候不允许使用拼音。


第三个命名规约就是我们希望大家使用匈牙利命名法,forcecode / UserDo / HTMLDto / XMLService / TCPUDPDeal / TAPromotion

,可以看到这个像第二个 user do 这种就是匈牙利命名法,但是特殊的这些变量像DO,DTO,我们希望大家使用的是全大写的。

下面大家来看这几条语句最终的结果是什么?大家看到结果有可能很出乎大家的意料,第一行的结果是true,然后后面两行的结果是false。

图片183.png

关于这个问题是我们要求所有的相同类型的包装对象类之间的值的比较,都要用 equals 的方法,因为 Java 里面它有一些预先的优化。大家也看到这几个比较的值,有的时候是true,有的时候是false,具体的原因大家可以去了解,因为它有一些 cache 导致的这几个值是有可能会出乎你的意料,所以大家在用包装类对象之间进行值比较的时候,都统一的使用 equals 的方法。

大家看这两个浮点数,大家觉得 a = b 还是 a 不等于b?

图片184.png

 

结论是 a 不等于b,就说明浮点数的 1. 0 -0. 9 并不等于 0. 9 -0. 8。原因是因为在计算机内部,浮点数的表示的方法是有一些特殊性的,它和我们数学上的表达方式不一样,它是不精确的,所以要求浮点数之间的等值判断不能用双等号来比较,并且浮点数的包装数据类型也不能用 equals 来判断。 浮点数判等我们是要判断它们俩相减的数值小于一个数,一个特定的比较小的数,我们就认为他们相等,千万不要判断他们是不是真的相等,因为他们真的不等。在计算机内部的表示方式上面。

图片185.png

 

下面我们来介绍阿里巴巴代码规约扫描工具,我们这个工具叫做P3C,大家看这幅图。 P3C 是一架著名的反潜机,它的型号叫做P3C,我们也希望我们的代码规约扫描工具,像这一架反潜机一样,它结合本地和线上的这些扫描的方式,我们希望它能检测到尽可能多的问题,也就是核潜艇。所以达到各个击破以点到面这么一个目的。

图片186.png

 

首先我们这个扫描工具,它提供了一个 IDE 的插件,在 Eclipse 里面或者是 idea 里面都有支持,它可以在本地进行扫描。然后在云效的自动化测试平台上面,我们也有卡点,也可以在云效的自动化流水线上进行扫描。同时我们代码规约也要求做 code review 的阶段也要人工,大家来检查代码规约的合规性。

 

三、单元测试基础

首先我们要给单元测试一个定义,单元测试是我们对一个代码单元的一个测试,一般情况下一个单元我们是指的是一段函数,当然在 c 或者 Java 里面有比函数更小的单元,就比如被很多大括号括起来的一个block。一般情况下,我们做单元测试的时候,针对的单元就是一个函数或者一个方法,同时一个单元测试用例是用于判断某一个特定条件下的函数的行为,而不是很多个场景。我们单元测试一定要缩小范围。一个单元测试用例判断的是一个函数的某一个特定场景下的行为。先给大家解释单元测试的规模代价平方定律,它是定位修复一个 bug 所需的代价正比于目标代码规模的平方,大概 20 行代码在开发阶段发现一个bug,定位和修复的时间可能只需要 10 分钟,在我的实际使用过程中可能 10 分钟都不需要,因为你的行数非常少,一旦发现有问题,你脑袋里面立刻就能反映出来在它什么地方,二百行就是另一个事情。 如果二百行的代码在别人调用时发现问题,定位和修复的时间可能需要一小时,代码评审又需要一小时。在我的实践经验中,两个小时是不够的,因为可能这两个小时是纯粹花在代码上的时间,但是在别人发现了你的问题,这中间沟通的时间一定会超过两个小时。

图片187.png 

单元测试的知识的测试框架,不同的语言有不同的测试框架,像 C + + 有著名的 CPP unit, Java 有 j unit 和 test NG,这两个是最常用的到。 net 有 x unit,其他更加现代的语言,比如像go,rust,它都是在语言层面,准库就支持单元测试,所以单元测试的框架在我们实践经验中是非常重要的,它甚至可以说决定你单元测试的效率。如果你的单元测试的工具并不完善,单元测试想做完善几乎是不可能的任务。


mock 工具是什么作用?

首先,我们是需要用 Java Dynamic proxy API 创建一个被测试对象的代理类,也就是 mock 的目标对象。我们要 mock 哪一个对象,我就去定义它一个代理类。然后这个对象具备 mock handler 的实现。 第二步,我们要针对 mark 对象拦截我们需要调用的所有的方法,当然不调用的方法我就不拦截,这就是 mock 的很大的一部分作用。我要 mock 一个对象,这个对象有可能有很多个方法,那我只去拦截我这次测试关心的方法,然后我记录这个调用方法,并替换为自定义的返回内容。第三步就是我们去调用这个 mock 对象,然后去调用我们目标的方法。在测试框架中,它会通过 mock 对象调用这个依赖的方法获取我们在上一步中自定义的响应。我们就可以在下一步验证 mock 对象调用已经完成,我们就可以验证我们被测函数或者被测方法的行为是否符合预期,这就是 mock 。

 图片188.png

下面我们来介绍单元测试的 air 原则。我们希望单元测试就像空气一样,虽然我们感觉不到它的存在,但是还是必不可少的。我们来看这三个字母分别代表什么含义。 a 代表Automatic,就是单元测试我要自动化,有几个方面的要求,一个是我可以用机器来判断单元测试是成功还是失败,这是自动化的一部分。另一个就是单元测试执行的一定要快,因为你只有做到自动化,才能让单元测试执行的快,而且你只有做到自动化,只有做到了它快,才能让它变得像空气一样,感觉不到它的存在。如果一个单元测试要跑 5 分钟,都需要在那等,就不是说像空气一样感觉不到它的存在。 第二个 i 代independent,就是单元测试的用例之间是不能有依赖关系的。如果单元测试的用例之间有依赖关系,它就失去了它的独立性。我们某一个方法,如果说我某一天 refactor ,这个方法不需要,那它的单元测试用例也会被删掉,依赖于这些用例的单元测试就会break,这样我单元测试的独立性就失去,就会有连带的连锁反应,这样就不好。 r 代表的是repeatable,意思是我不论是在什么地点,什么时间来运行这一个单元测试,它的结果都是一样,这个提出几个要求,一是单元测试不能对环境有依赖,比如我在测试机上,在开发机上、在构建的机器上,单元测试结果都应该是一样的。 其次单元测试不能对时间有依赖,比如我今天测试成功了,明天测试就失败,这样也是不行的。


下面总结就是要像空气一样,在测试质量保障上一定是非常关键的,在宏观上来看,它具有 AIR 这 3 个特点。


下面我们学习单元测试的b、c、d、 e 原则,这个是指的是我们测的是哪些方面?首先来学习 b 原则,它指的是border,我们要测的是边界,为什么要测这些循环边界特殊取值、特殊时间点等,是因为在边界上面是最容易出错的地方,所以我们要着重的来测试。 第二个原则是 C, correct 正确的输入,我们要得到预期的结果,这个有一个专用的名词叫做 success path,正常通路。然后单元测试,它是一个典型的白盒测试,所以我们一定要和文档和设计文档结合来编写单元测试。 e 这个原则是和 c 相对应的,就是错误的输入信息,我们也要测,并且得到预期的结果,这个叫 failure path, 正,就是说正向的流程和负向的流程都要测到,不能偏分。


下面我们总结单元测试中有哪些不好的方式,大家看到的这个例子是第一个不好的,就是测试场景过于集中,我们说单元测试是要针对某一个单元在某一个场景下的行为,为什么我们只测某一个场景,是因为我需要单元测试比较简单,如果某一个单元测试用已失败,我希望立刻能定位到代码的某一行去。但如果像现在这个用例里,它有六个场景在这里面,那我们这一个单元测试失败,我没有办法直接定位到我的代码行数里面,这样就会导致我单元测试失败,我还要先去调试单元测试用例,这个就失去单元测试简单的这个意义所在。所以单元测试的场景不能过于集中,每一个用例代表了一个场景。

图片189.png

 第二个就是单元测试不能依赖于环境,如果依赖于环境,就会导致你的单元测试不稳定。然后第三个就是单元测试缺少断言。什么叫缺少断言?就是我们可能是打 log 或者是在屏幕打印,然后用人眼人肉的来观察这个单元测试到底是成功还是失败,这样就会导致它不自动化,单元测试的效率就会降低,然后也需要人工干预也会有不稳定性存在。最后一个就是用力之间存在依赖,这个刚才我也强independent,我们需要它独立,不能之间存在依赖。

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
相关文章
|
5月前
|
存储 算法 开发工具
文档管理软件版本控制算法的代码例子
提供一个基本的示例,展示如何使用Python中的字典数据结构来模拟一个简单的版本控制系统。
480 0
|
1月前
嵌入式软件开发要注意这七中错误事项
嵌入式软件开发要注意这七中错误事项
12 0
|
1月前
|
关系型数据库 数据库 数据安全/隐私保护
已知日程表软件用户手册
已知日程表软件用户手册
|
9月前
|
JavaScript 算法 Linux
硬件工程师物料清单BOM对比工具
硬件工程师物料清单BOM对比工具
176 1
硬件工程师物料清单BOM对比工具
|
6月前
|
运维
软件需求说明书应包括的内容
软件需求说明书应包括的内容
|
6月前
|
人工智能 数据安全/隐私保护 计算机视觉
软件丨最终的笔记软件
上次发现了钉钉出了个人版,试了下其实确实挺合适个人使用的,不过也有不少限制!
|
7月前
|
Devops 开发工具 git
软件代码与质量管理(更新版)(一)
软件代码与质量管理(更新版)(一)
85 0
|
7月前
|
移动开发 JavaScript Java
开发拍卖软件源码选择公司要点和推荐
随着在线拍卖市场的不断增长,越来越多的企业和创业者考虑进入这个潜力巨大的市场,开发拍卖APP。在着手开发之前,必须仔细考虑所需的功能,并选择适合项目需求的拍卖APP源码。本文将讨论选择和开发拍卖APP源码的关键要点,并介绍一款备受推荐的拍卖APP源码,即"东莞梦幻网络科技"的拍卖直播系统源码,这是一个快速启动的解决方案。
|
9月前
|
监控 安全 测试技术
嵌入式软件测试笔记10 | 嵌入式软件测试中如何进行安全性分析?
嵌入式软件测试笔记10 | 嵌入式软件测试中如何进行安全性分析?
131 0
|
10月前
|
测试技术
嵌入式软件测试笔记8 | 嵌入式软件测试中可测性审查如何开展?
嵌入式软件测试笔记8 | 嵌入式软件测试中可测性审查如何开展?
64 0

热门文章

最新文章