CodeReview技巧和规范

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 What-什么是CodeReview? CodeReview,即代码评审,是白盒测试中,静态测试的一种方法,通过阅读代码,提出代码层面的缺陷。 Why-为什么做CodeReview? 测试左移:在测试前就发现代码缺陷。 明确测试范围:根据需求文档和代码,对齐测试范围,防止研发夹带本次需求范围外的代码上线。 提升代码能力:学习研发优秀的编程技术。 深入原理:了解系统内部结构及实现。 发现隐藏缺陷:能发现某些极端场景下的问题或概率性问题。 减少测试研发周期占比:节省用例执行个数,尤其多个同类异常梳理,不用执行类似用例,CodeReview一行代码即可。 Who-谁适合做CodeReview? CodeReview需要三大门槛: ①熟悉编程语言,Java/Python/Go等。 ②熟悉编程规范,《阿里巴巴XXX编码规范》、《华为XXX编码规范》、《京东XXX编码规范》。 ③了解需求、架构和设计,需求文档/架构图/设计文档。 达到门槛才适合做CodeReview。 When-什么时候做CodeReview? 提测前,通过Code Diff Review,自己走读代码或者参与研发代码评审会议均可, 发现功能缺陷时,通过走查代码定位代码原因,并分析是否有关联缺陷。 修复缺陷时,阅读研发commit记录,检查是否引入新缺陷。 上线前,通过merge范围检查是否有夹带代码,为了测试改动的临时代码是否恢复。 Where-在哪里做CodeReview? 线上仓库(如Gitlab),适合于修改点单一,不需要查看上下文信息就能找到缺陷。直接在网页端评审代码且发表comment。 本地仓库(如IDEA),适合于修改点较多,需要查看上下文信息(变量或方法跳转到定义或使用之处)。在本地找到缺陷后在线上发表comment。 How-CodeReview如何上手? 准备:了解需求、架构和设计;学习编程语言;学习代码规范; 实践:坚持CodeReview,记录缺陷,定期总结。如果看代码找缺陷比较困难,可以先从发现功能缺陷后,定位代码原因入手。 常见CR缺陷: 除数为0、整数溢出、精度损失; 可能死循环; 在finally程序块中关闭或者释放资源; 异常未处理或提示不明确(没有catch异常,集合等没有判空和长度为0); 公式计算错误; 字符串对比不能用==,使用equals; 数组可能越界; 传递引用错误; 类型转换错误; 条件范围选择错误; 重点检查项: 一致性检查:是否需求相关;是否和方案设计一致;代码风格、日志规范、异常处理等是否和统一规范一致; 完整性检查:服务层是否包含了所有业务功能;数据层是否包含所有需要的数据和操作; 正确性检查:计算逻辑等业务逻辑是否正确;变量是否被正确定义和使用;代码是否符合制定的标准; 可修改性检查:代码涉及到常量是否易于修改,比如使用配置,定义为常量类等;建议业务方法只有一个出口和一个入口(异常处理除外);重要公共方法是否有交叉注释说明;重要的对外方法修改后影响多个下游接口; 可预测性检查:变量初始化;方法稳定性;代码是否存在死循环;代码无穷递归检查; 健壮性检查:代码是否采取措施避免运行时错误(如数组边界溢出、被零除、值越界、堆栈溢出等) 高可用性检查:是否有预案(降级开发、限流配置、兜底策略);补偿方案是否合理; 结构性检查:程序的每个功能是否都作为一个可辨识的代码块存在; 可理解性检查:是否使用到不明确或不必要的复杂代码;代码中的算法是否符合开发文档中描述的数学模型;每个变量都定义了合法的取值范围; 可验证性检查:代码功能是否便于测试;单元测试覆盖度是否足够; 可追溯性检查:代码是否包括一个修订历史记录,记录中对代码的修改和原因都有记录; 编码规范: 《阿里巴巴Java开发手册》 最新版本:黄山版(2022.2.3发布) https://github.com/alibaba/p3c

java+appium+安卓模拟器实现app自动化Demo

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 环境搭建 据说,很多人都被繁琐的环境搭建给吓到了。 是的,确实,繁琐。 node.js 下载地址: https://nodejs.org/en/download/ cmd 输入 node -v,出现下图说明成功: JDK 下载地址: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 百度一下“配置Java”,配置环境变量。 cmd 输入 java -version,出现下图说明成功: Android SDK 下载地址: https://www.androiddevtools.cn/ 百度一下"配置Android SDK环境变量"。 cmd 输入 adb,出现下图说明成功: Appium Desktop 下载地址: https://github.com/appium/appium-desktop/releases 或 https://testerhome.com/topics/680 Maven 下载地址: http://maven.apache.org/download.cgi 百度一下“ maven环境配置”。 cmd 输入 mvn -version,出现下图说明成功: IntelliJ IDEA 下载地址: http://www.jetbrains.com/idea/ 安卓模拟器 下载地址: https://www.yeshen.com/ 把 Android SDK 目录下 \platform-tool 的 adb.exe 拷贝。 打开 Nox\bin 目录,粘贴替换 adb.exe。 打开模拟器。 ...

Java新一代单元测试框架JUnit5速览

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 为什么学JUnit5 Java技术栈的单元测试框架有两个:JUnit和TestNG,有种说法是TestNG比JUnit更强大,学TestNG就够了,但是当我打开GitHub看到star的时候,犹豫了: JUnit TestNG 相差了足足有3K之多。带着这个困惑,我在网上查阅了一番资料,原来JUnit5相较于JUnit4有了重大升级,已经包含了TestNG的所有功能。为了坚定我学JUnit的想法,我咨询了身边做Java开发的朋友,开发写UT都是用的JUnit。这两个理由足以让我开始对JUnit5的学习。 JUnit5是什么 跟之前的JUnit有所不同,JUnit5由三个子项目的模块组成: JUnit5 = JUnit Platform + JUnit Jupiter + JUnit Vintage JUnit Platform 在JVM上启动测试框架的基础,不仅支持Junit自制的测试引擎,其他测试引擎也都可以接入。提供了从命令行启动平台的Console Launcher,和支持JUnit4环境的JUnit4 based Runner。IDE一般都集成了JUnit Platform,比如IntelliJ IDEA。 JUnit Jupiter JUnit5新特性,结合了新的programming model和extension model,以便于在JUnit5中编写测试和扩展。提供了在平台上运行基于Jupiter测试的TestEngine。 JUnit Vintage 提供了在平台上运行基于JUnit3和JUnit4测试的TestEngine,照顾老的项目。 JUnit5新特性 使用JUnit Jupiter写测试 示例代码: import static org.junit.jupiter.api.Assertions.assertEquals; import example.util.Calculator; import org.junit.jupiter.api.Test; class MyFirstJUnitJupiterTests { private final Calculator calculator = new Calculator(); @Test void addition() { assertEquals(2, calculator.add(1, 1)); } } 注意这个导包的路径org.junit.jupiter.api,Jupiter就是JUnit5的新特性。 ...

JMeter全部组件概览

JMeter是性能测试工具,在使用JMeter变多以后,越来越觉得之所以它能成为当今时代最主流测试工具,是因为它太成熟了,举个小例子,编写GET请求的时候,需要把查询参数,也就是?号后面的请求参数添加进去,JMeter竟然有个Add from Clipboard功能,在浏览器复制以后,点这个按钮就填充好了:

从零开始学mitmproxy抓包工具

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Man In The Middle mitm是Man In The Middle的首字母缩写,意思是位于中间的人,表明mitmproxy是一个代理,可以拦截请求,实现网络抓包。知名的网络抓包工具有Fiddler、Charles、HttpWatch、WireShark、BurpSuite和Postman等,mitmproxy相对来说,没有这么高的知名度,它相比于以上工具的独特优势是,它提供了Python API,可以编写Python代码对网络请求进行流量录制,从而收集接口信息以及转化为接口自动化用例等。mitmproxy官方文档不但有mitmproxy工具使用介绍,还有代理实现原理,对我们学习掌握网络知识有很大帮助。 安装与使用 pip安装 pip install mitmproxy mitmproxy是Python开发的,用pip就能安装成功。官方给出了二进制安装包等方法,我觉得作为一款用Python开发的工具,用pip直接安装是更Pythonic的。 命令启动 可以通过3种命令启动mitmproxy: mitmproxy 控制台 mitmweb 网页 mitmdump 命令行 它们的内容都是一样的,只是UI不一样而已。 手动设置代理 打开以后mitmproxy默认会监听http://localhost:8080,需要设置下代理,把代理服务器设置为这个地址。 Windows可以这样设置: 设置后一定要记得点击保存按钮,否则代理不会生效。 实际上,Charles等网络抓包工具会自动配置代理,而mitmproxy需要手动设置代理,开发团队的解释是因为浏览器版本和配置经常会变化,所以他们建议在网上根据环境搜索方法手动设置。 下载证书 访问http://mitm.it/,如果代理配置没有生效,打开后会是这个界面: 正常的话,会出现证书下载页面: 根据平台选择相应证书安装就OK了。 使用 mitmproxy更其他抓包工具用法类似。 官方用视频演示了mitmproxy如何使用: https://docs.mitmproxy.org/stable/mitmproxytutorial-userinterface/ 并且介绍了5种运行模式: https://docs.mitmproxy.org/stable/concepts-modes/ 读者可以自行阅读下。 mitmproxy工作原理 客户端(本机)连接代理服务器(http://127.0.0.1:8080),代理服务器连接服务器。 客户端给代理服务器发请求,代理服务器把请求发送到服务器。 所有请求经过mitmproxy,就可以实现请求拦截。 对于HTTP来说,直接借助mitmproxy传递请求就可以。而对于HTTPS来说,有个SSL/TLS安全认证,必须安装证书,服务器才会认为mitmproxy的请求是可信任的,请求才会成功传递。 HTTPS的代理过程就要复杂很多,客户端先跟mitmproxy建立连接(12步),然后进行安全认证(36步),最后传递请求(7~8步)。 反向代理 假设在本机使用FastAPI启动了个Mock服务,地址为http://127.0.0.1:5000,通过Postman调接口,怎么使用mitmproxy来拦截请求呢?这就需要用到反向代理。 首先以反向代理模式运行mitmproxy,服务器端口为5000,监听端口为8000: mitmproxy --mode reverse:http://127.0.0.1:5000 --listen-host 127.0.0.1 --listen-port 8000 然后把请求http://127.0.0.1:5000/login里面的5000端口改成8000,访问: http://127.0.0.1:8000/login 就能在mitmproxy看到抓到请求了: 这样就能在本地使用Mock服务来调试拦截请求的Python代码了。 反向代理,不需要在本机手动设置代理。 Python API Python API是mitmproxy的特色功能: ...

一个请求的一生

点进Service,全是接口。点进ServiceImpl,前半段在校验业务规则,后半段调了个stockService.deduct(),又得跳到另一个Service。

中台RPC接口自动化怎么做

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 RPC接口 我所在的部门是技术中台,主要负责toB业务,上游是业务条线,包括PC、APP、小程序等终端,这些端的后台是HTTP接口层,而在HTTP接口层之下,就是技术中台的RPC接口层。 HTTP是一种超文本传输协议,基于TCP/IP来传输文本、图片、音频、视频等数据。数据包的传输能力不是HTTP提供的,而是TCP/IP干的。HTTP的本质是客户端和服务端约定好的一种通信格式,是一种全世界认可的通用范本。 RPC是一种远程调用,也就是进程间通信,既可以用HTTP协议,也可以用自定义协议。RPC的好处是没有HTTP那么多约束,简化了写法,可以根据公司自定义规范,内部统一即可。 所以在公司内部特别流行,比如阿里的Dubbo接口就是一种RPC接口,我们公司用的JSF接口,自研的服务框架,简称杰夫。 谈谈京东的服务框架 https://juejin.cn/post/6948351920088186888 举个例子,本地调用,是调用的本地方法: public User getUserById(Long id) { return userDao.getUserById(id); // 这叫本地调用 } 而RPC远程调用,调用的是另外一个服务的方法: public User getUserById(Long id) { return userConsumer.getUserById(id); // 这是远程调用,逻辑是用户小组的服务实现的。 } 本地调用和远程调用的比较如下图所示: 左边的本地调用,只在应用内部调用。右边的远程调用,会跨应用在应用之间调用。 RPC和HTTP用法区别 HTTP接口在调用时,输入URL,Method,Headers,Body等等等就可以发送请求了。 RPC接口的调用大同小异,输入: JSF地址:方法引用路径,比如com.dongfanger.api.service.ShopProvider。 方法名:方法名称,比如queryShopList。 别名:既可以是分组别名,也可以直连IP地址。 方法入参:JSON串。 等等等,就可以发起请求了。 从用法能看出来,RPC和HTTP接口的结构体是差不多的,但是RPC不需要Method和Headers,精简了许多。 接口自动化 首先需要考虑的是目录结构设计,HTTP可以模块菜单创建用例目录,比如: 一级目录:管理端 二级目录:发票管理 三级目录:发票查询 而RPC是无页面的,一般存在很多业务线,所以可以按照功能域和业务线来组织目录,比如: 一级目录:发票 二级目录:提交申请 三级目录:分销 其次就得考虑技术实现了,公司基建比较完善,无论是HTTP还是JSF接口,都能在接口测试平台上编写自动化用例。虽然是Web平台写用例,但是得益于测试平台的优秀设计和使用体验,用起来很方便,效率也很高。交互方式跟JMeter大同小异,只是在细节上做了很多打磨。 然后就是参数构造了,建议是用流量回放的方式来做,省去手工编写参数的崩溃感。流量用例创建好以后,需要做一些参数化处理和接口关联。这样才能够把多个接口串起来。 对于测试数据,通过预设变量来统一管理,自动化用例也尽可能设计成闭环,增加,修改,查询,删除,用例跑完后产生的数据也跟着清理掉。 最后就是断言了。没有断言的自动化用例,不叫做自动化用例。断言一定要加上,否则定时任务跑出结果后,无法判断到底有没有问题。而断言内容不能只是简单的code200,需要加上业务校验。 中台RPC接口自动化最难处理的是接口依赖问题,链路特别长,依赖特别多。我一般通过Mock来解决这个问题,公司的测试平台也提供了这个功能。 需要注意的是,核心用例定时运行监控起来,而一次性用例要及时维护或清理,防止变成僵尸用例。 最后,我准备基于Vue+FastAPI开发一套新的pytest脚本管理平台,集成流量录制创建用例和Mock等功能,并借鉴公司测试平台的设计,感兴趣的同学可以添加微信cekaigang加群讨论哟。 参考资料: HTTP 的本质?HTTP 和 RPC 的区别? https://www.jianshu.com/p/fe5ccfc5d7bd 谈谈京东的服务框架 https://juejin.cn/post/6948351920088186888