IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 你还在为不写单元测试找理由吗? -> 正文阅读

[开发测试]你还在为不写单元测试找理由吗?

一、写在前面的话

作为编程从业人员,单元测试早已不是生僻的、不为人知、不受重视的概念。
但是与此同时,实际情况下,除了开源SDK基本上会标配单元测试外,在真正的项目开发中,单元测试的实践程度低之又低。
这里面的原因非常非常多,笔者听到的最多的不写单元测试的原因就是 —— 没时间
但是没时间是否能和'可有可无'画等号?是否能和'不重要'画等号?
也就是说,假设给到足够充足的时间,是否单元测试就能够顺利实施?覆盖率就能达到100%?
笔者后面会针对这些问题阐述笔者自己的理解:

二、不考虑时间的情况下,到底有没有必要搞单元测试?

假设有这样一个场景,你编写了一个"支付时金额计算"的函数,里面牵扯有一些打折、金额抹零的计算。
此时在正常的逻辑中你已跑通无误,但真实场景较为复杂,此时便自身简单功能验证(或不验证)便直接给测试人员进行验收。
此时基于以下2个现状 外加 无单元测试 的情况下:

①、测试人员只是软件的另一层保障,而不是唯一的保障;
②、绝大多数测试人员均停留在‘点点点’的层面(没有贬低测试人员的意思,但现状确实是)

我们最终上线的软件存在隐患的概率非常大。
假设真正上线后,出现了实际的金额计算bug,导致运维事故、甚至顾客投诉的出现,
此时假设公司层面将责任100%划分给了测试人员,那笔者也就不多评价了。
绝大多数情况下,只要公司是明智的,其实编写者本身负有绝大多数的责任。

就好比,如果食品出了食安事故,此时质监部门确有责任,但食品加工厂负有更多的责任。

也就是说,出于自身技术工作素养,我们应该对软件质量应有足够的把控,
不能依托于 测试人员来发现问题,更不能依托于上线后侥幸不出问题。
此时幻想下这个场景:你告诉领导,我2天可以做完,但是3天可以最大程度保质保量完成。
相信只要是有些产品意识的领导,相信都愿意等那一天。或者说,不等的话难道等着上线后试试看吗?
此时,单元测试就是 开发人员 的一项利器。

三、明确了必要性后,单元测试实践真正的阻力是什么?

都说没时间,那么给你时间,你真的能写好单元测试吗?覆盖率能够达到100%吗?
根据笔者听到的同行业朋友们的答复,以及应聘者们的答复,基本都是否定的答复。
也就是说,在笔者的认知里:没时间 = 找借口
或者说单元测试函数的编写,以及被测函数的编写,是存在一定技术难度的
笔者在这里重点分享一个 概念:

可测函数

笔者听到很多想尝试写单元测试的朋友的疑问都是,看着官方Demo挺简单(比如计算个加法、减法),都能看懂会写。 但是回到自己项目里发现,完全无从下手,例如以下Demo

const sdk = require("三方依赖");
const db = require("数据库连接或Model");
const otherServices=require("其他函数或业务文件");
module.exports = function(){
    //do sth.
    return;
}
复制代码

此时,一旦想对这个函数进行测试,会发现单元测试的脚本一旦引入这个被测文件,立即报错。
一方面数据库的连接信息报错,另一方面未知的其他业务js的引入报错。
也就是说,这个函数无法被测试,原因为 —— 外部依赖太多
这里笔者引入一个老生常谈的概念 —— 反转依赖

依赖反转/依赖倒置

百度百科:在面向对象编程领域中,依赖反转原则(Dependency inversion principle,DIP)是指一种特定的解耦(传统的依赖关系创建在高层次上,而具体的策略设置则应用在低层次的模块上)形式,使得高层次的模块不依赖于低层次的模块的实现细节,依赖关系被颠倒(反转),从而使得低层次模块依赖于高层次模块的需求抽象。

例如以下简单的Demo程序

const SuccessBusiness=require("成功回调的处理");
const ErrorBusiness=require("失败的回调处理");
module.exports = function(){
    // ★ 此处为主逻辑,经过某些计算/处理后,最终执行以下2个逻辑中的一个 ★
    SuccessBusiness(); //或 ErrorBusiness();
    return;
}
复制代码

也就是说,针对上述Demo程序最需要被测试的核心逻辑是 ★部分的逻辑,但是却不得不引入2个主逻辑无关的依赖函数,而2个依赖函数在这个函数中的作用仅仅是: ——在正确的时间点被触发
因此正向的依赖会导致测试用例寸步难行,改变就只能通过依赖反转,这并不是过于高深的理论,大家日常开发一定见过,例如以下Demo:

module.exports = function({onSuccess,onError}}){
    // ★ 此处为主逻辑,经过某些计算/处理后,最终执行以下2个逻辑中的一个。
    onSuccess(); //或 onError();
    return;
}
复制代码

改造到此,已经是测试用例非常喜欢的函数形式了。

  • 通过传入不同的参数,来验证★号部分的主逻辑
  • Mock入参中的onSuccess和onError函数
  • 通过判断2个Mock函数被执行的次数,来验证执行成功与否。

也就是说:单元测试的顺利推进,可能更多的是对原始主逻辑编码的高标准要求。

四、最后再说两句

其实,如果说单元测试是为了不出错,也过于狭义了,单元测试还有很多更深远的意义,例如
需求完成度:代码层面是否覆盖了全部的需求
重构:"优化代码的时候产生了降级问题"这个是非常常见的现象,而有了单元测试,简直是重构的福音,开发者可随意改,只要原始N条单元测试依然可跑通。

否则永远是在试探,谁也不知道误碰了哪里。这里笔者也推荐一番TDD测试驱动开发,感兴趣的朋友们可以自行学习。

最后,笔者想再次强调下代码测试对于开发人员的重要性,如果开发人员对自己的产出无法有硬性的质量保障,而是依靠感觉和经验,其实是不合格的。

至于测试工作对于研发而言,有哪些可以做的工作,笔者后续会持续分享,例如大中小测试、自动化测试、压力测试等概念。
欢迎留言、提问和指正!😊😊😊😊😊

如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!


最后基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等配套学习资源在下方公众号免费获取~

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-03-17 22:30:22  更:2022-03-17 22:31:13 
 
开发: 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 0:17:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码