| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 开发测试 -> 谈一谈单元测试 -> 正文阅读 |
|
[开发测试]谈一谈单元测试 |
写在前面 对于我们开发人员来说,单元测试一定不会陌生,但在各种原因下会被忽视,尤其是在我接触到的项目中,提测阶段发现各种各样的问题,我觉得有必要聊一下单元测试。 为了写而写的单元测试没什么价值,但一个好的单元测试带来的收益是非常客观的。问题是怎么去写好单元测试?怎么去驱动写好单元测试? 一 我们的现状现状一:多个项目完全没有单元测试。 现状二:开发人员没有写单元测试的习惯,或者由于赶业务记录而没有时间去写。 现状三:单元测试写成了集成测试,比如容器、数据库,导致单元测试运行时间长,失去了意义。 现状四:太依赖集成测试。 以上是我在aone找的两个项目的测试情况,基本不考虑单元测试就合并发布,形同虚设。 站在开发的角度讲,导致以上问题的原因大概有以下几点: 1、开发成本 对于系统初期,可能要花很多时间去写新业务,对于老系统又太过庞大,无法下手。 2、维护成本 每修改相关的类,或者重构一次代码,我们就要去修改相应的单元测试。 3、ROI 投入产出是不是正收益?可能无论是管理者还是我们开发自己都回质疑这个问题,所以有时候没有强有力的动力。 二 怎么解决说来说去都是成本的问题,所以我们怎么去解决成本呢? 那么,我们一切从最开始说起:开发的成本 一个单元测试的传统写法,包含以下几个方面:
一个简单的测试还好,但如果是一逻辑复杂,且入参数据复杂的时候,那写起来其实挺头痛的。怎么解放我们程序员的双手? “工欲善其事必先利其器” 我们以最大的努力降低我们的开发成本,这就涉及到我们测试框架和工具的选择问题 1 测试框架选择 首先第一个问题就是junit4和junit5的选择,【从junit4到junit5】 我觉得最便利的一个好处就是可以参数化测试,并且基于参数化测试我们可以更加灵活的配置我们的参数。 效果如下:
更好的是,junit5提供了扩展,比如我们常用的json格式。这里我们使用json文件作为输入:
2 mock框架 然后就是其他mock类的框架了 Mockito: 语法特别优雅,对于容器类的模拟比较合适,且对于返回值为空的函数调用也提供比较好的断言。缺点是不能模拟静态方法(3.4.x以上版本已支持) EasyMock: 使用方法类似,但是更严格 PowerMock: 可以作为Mockito的一个补充,比如要测试静态方法,不过不支持junit5 Spock: 基于Groovy语言的单元测试框架 3 数据库层 这里主要介绍一下H2数据库,其基于内存来作为对于关系型数据库的模拟,运行完成自动释放,达到隔离的目的。 主要配置:ddl文件路径、dml文件路径。这里不作详述。 但对于要不要集成数据库,很难去定义,它的作用主要是用来验证sql语法的问题,但是相对来说较重,建议可以用于轻量级的集成测试。 三 Junit5和Mockito后面讲到的自动生成使用的框架和业界使用最多的都是MocKito,所以这里重点介绍一下,包括使用时遇到的问题。 1 使用方法 分别单独引入依赖,推荐引入最新版
junit5的使用方法这里就不多做介绍,主要说一下这个ArgumentsProvider接口,实现它就可以自定义参数化类,类似于自带的ValueSource、EnumSource等。 2 Mockito 主要注解介绍 先问为什么,为什么需要Mockito 因为:现在的java项目几乎离不开spring框架,而其最为著名的就是IOC,所有的bean用容器来管理,所以这给我们单元测试带来一个问题,如果要对bean做单元测试,就需要启动容器,那么带来的时间的开销将会很大。所以Mockito给我门带来了一系列的解决方法,让我们可以轻松的对bean 进行测试。 假设我们要对上面的A.func()进行单元测试。 @InjectMocks注解 表示需要注入bean的类,有两种
@Mock 表示要mock的数据,也就是不真实执行其方法内容,只按照我们的规则执行,或者返回,比如使用when().thenReturn()语法。 当然也可以,执行真实方法,则需要when().thenCallRealMethod()方式。 @Spy 表示所有方法都走真实方式,比如有些工具类,转换类,我们也写成了bean的形式(严格来说这种需要写成静态工具类)。
3 Mockito和junit5常见问题 mock静态方法 mockito3.4以后开始支持,之前的版本可以使用PowerMock辅助使用 Mockito版本和java版本兼容问题 报错如下
原因是2.17.0及之前的版本与java8是兼容的 但2.18之后需要使用java11,为了在java8中使用Mockito,则需要引入另一个包 Jupiter-api版本兼容问题
第一个问题是因为junit5中api、engine、params版本不一致导致的。 第二个问题是因为jupiter-api版本太低的问题,5.7.0以后的版本才支持。 四 测试代码自动生成选好了框架,我们还是没有解决我们的问题,“怎么节约开发成本?” ,这一节我们来谈这个问题,这也是我主要想表达的。 对于写单元测试,一直以来是比较头痛的事情,要组装各种各样的数据,可能还没跑成功,就被一堆“xxxx不能为null”的报错搞烦了。因此我们有理由去设想,有没有办法去解决这件事情。 1 业界和集团方案调研 在做这个事情之前,肯定是要调研有没有现成的框架。答案是有,但很遗憾,没有找到完全契合我想要的效果,我们来看一下这些插件:
如上,testExtend一共调用了testService的4个方法,我们对比下各个插件生成的代码。 TestMe
1、生成的代码基本符合逻辑,包括需要mock的bean的逻辑都生成了。 2、但它把最重要的一环,也就是数据省略了,只是单纯的用了构造函数的形式。这显然对于我们DDD模型不适应。 3、另外他没用用到junit5的一些特性,比如参数化测试。 4、对于testExtend的方法,它只识别了3个方法。没有识别父类的调用。 JunitGenerate 只能生成基础的框架代码,对于我想mock的逻辑、以及测试方法都没有生成,用处不大。
Squaretest 生成的方法非常丰富,且一个非常厉害的一点,它能生成多个分支,比如代码逻辑中有if条件,它能生成两个测试,从而走不通的分支。 但是,最大的缺点是“收费软件,不开源”,这就决定了我们没法用它,除非是特别需要。另外测试用过程中还发现了一些其他问题,比如对于继承,重载之类的问题,它解决的也不是很好,往往识别不了需要调用的方法。 虽然无法使用,但还是可以借鉴。 五 打造代码自动生成最佳方案既然市场上的插件都不是特别合适,就决定写一个适合自己项目的插件(暂时命名JCode5)。有兴趣的也可以自己试试。 1 插件安装 idea插件市场下载,搜索JCode5 2 插件使用 插件有三个功能
定位到需要测试的类,快捷键或菜单定位到generater,如下,选择JCode5. 生成测试类 目前支持三个选项,后续会逐渐完善 另外两个功能类似,直接尝试使用一下就行。 生成的结果---类+json数据
如上除了生成基本的代码,另外会生成测试数据,它会将该方法所需要的测试数据全都生成在一个json文件当中,完全实现 “数据和代码的分离” 如testExtend.json:
补充判定语句 这一块前期考虑对于不同的方法有不同的校验,所以目前想的还是开发者自己去写验证代码。 注意事项 在自动生成完代码之后,虽然可以运行,但如我们前面提到的,为了写单元测试而写的单元测试是没什么价值的,我们的最终目的是为了写一个好的测试。代码自动生成,但它终究能力有限,所以还是需要我们自己再去验证,比如
3 插件实现介绍 主要的实现思路,参考了dubbo的SPI的源码,也就是自动实现自适应SPI那部分,简单点说就是反射获取代码逻辑,然后生成测试代码。 4 后期规划 1、mock数据可定制,目前的想法是
2、自动分支测试,这一块的想法目前主要针对if来做,需要一定的时间。 3、其他 六 写在最后对于代码自动生成,还是有很多东西可以做的,但有些问题还尚待解决,希望能尽最大努力解放我们的双手,也能提高我们单元测试的质量。 已在我们项目中使用此模式增加135个测试用例(除去mock的单模块达到70%):速度比集成测试(pandora、spring等)提升一个等级。代码的覆盖率相对可观。 作者 | 有尘 本文为阿里云原创内容,未经允许不得转载。 |
|
开发测试 最新文章 |
pytest系列——allure之生成测试报告(Wind |
某大厂软件测试岗一面笔试题+二面问答题面试 |
iperf 学习笔记 |
关于Python中使用selenium八大定位方法 |
【软件测试】为什么提升不了?8年测试总结再 |
软件测试复习 |
PHP笔记-Smarty模板引擎的使用 |
C++Test使用入门 |
【Java】单元测试 |
Net core 3.x 获取客户端地址 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/18 2:43:39- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |