打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
单元测试


介绍怎么做单元测试的书很多,这里主要解答:为什么单元测试。

客观来说,单元测试和使用版本控制系统(GIT,SVN)是一样重要的。

为什么单元测试如此重要,但你却感受不到。

首先要知道,代码的终极目标有两个,第一个是实现需求,第二个是提高代码质量和可维护性。
单元测试是为了提高代码质量和可维护性,是实现代码的第二个目标的一种方法。
(注:代码的可维护性是指增加一个新功能,或改变现有功能的成本,成本越低,可维护性即越高。)

—————————————————场景1:Hello World—————————————————
任何一个伟大的程序员都是从最简单的代码开始写起的,假设你的第一个程序是Hello World,任何一个语言实现这个程序都只需要不到5行代码。


这个程序需要单元测试吗?,我们看看这个程序是否实现了软件的两个目标:
1.需求很简单,输出Hello World,这个程序完全满足需求。
2.只有5行代码的“软件”无论是代码质量,还是可维护性,都相当高,你想要把Hello改成Hi真的很轻松。
既然我们已经实现了代码的目标,要不要使用单元测试是无所谓的,同样这么简单的代码也没人会使用GIT或SVN。
代码量:5行

—————————————————场景2:简单计算器—————————————————
接下来你写了一个相对更复杂的程序,一个简单计算器。
这个程序实现了数字的加减乘除,整个程序共写了大概50行代码。


这个程序需要单元测试吗?
1.需求是对数字进行加减乘除,这个程序满足了需求。
2.你的代码风格很好(你已经了解到代码风格很重要),你使用了缩进,良好的变量命名,逻辑也清晰,代码的质量和可维护性仍然相当高,如果你想增加一个“求x的平方”功能,你轻而易举就可以做到。
这个时候让你去写单元测试,你仍然会觉得那纯粹是浪费时间。
代码量:50行

—————————————————场景3:图书管理系统————————————————
你想要做一个真正的实用系统,给学校开发一个图书管理系统。
你相信这个系统的代码量比起计算器会很多(可能会有1000行)。
你从书上看到有这样一些方法可以简化你的开发工作:
1.工具库(类似你家里的工具箱),使用工具库带来的好处是非常明显的,假如你要实现“返回一个数字数组中的最大值”,你只需要使用某个工具库的Max()函数,只需要1行代码,而不是10行代码自己实现。
2.MVC框架,虽然比起工具库更复杂,需要花更多时间学习,但MVC框架带来的好处也非常明显,轻而易举调用数据库(Model),实现简单的UI界面(View),实现了类似“书名为空的书不允许添加到数据库”的一些逻辑(Controller)。
你最终很好的实现了这个系统,基于MVC模型,你的代码被很好的分割成了很多小的独立的模块:4个Controller,2个Model,4个View。并且在工具库的帮助下,代码量得到了缩减,每个模块大概只有50行代码(等同于一个简单计算器的代码量)。


这个系统需要单元测试吗?
1.你实现了对图书的添加、删除、修改、借阅,你很好的满足了需求(校长表扬了你)。
2.得益于框架与库的使用,你的代码被很好的模块化了,每个模块都像一个“简单计算器”那样简单,增加新功能,或修改现有功能似乎也没有什么大麻烦,虽然会出现一些小bug,但很快就修复了,代码质量和可维护性都比较高。
既然你又实现了代码的目标——“完成需求,高代码质量和可维护性”,那好像也没“单元测试”什么事,毕竟写它要浪费额外的功夫,而且也没感觉到有多少好处。
代码量:500行

————————————————场景3:大型库存管理系统———————————————
你被一家IT公司雇佣了,你通过了面试,进入了一个即将开启的项目——为一家大的电商公司做一个库存管理系统。
项目初期一切都很顺利,技术上和你做过的图书管理系统差不多。
首先你了解了客户的需求,然后根据他们的需求,使用你已经掌握的MVC框架和一些库,实现了他们的需求。你写了30个Controller, 50个Model,50个View,每个模块的代码都达到了大概150行,总代码达到了惊人的20000行!
你觉得自己很了不起,能hold住这么多代码,这完全是得益于你的高智商,以及工作努力。客户很满意,老板也很满意,你的自我感觉也很不错。

并且你发现了比单元测试更好的东西,面向对象编程(OOP),或函数式编程(FP),无论是哪一种,你发现你可以把一个模块里的150行堆砌在一起的代码再提取成1个对象的15种方法,或者15个独立的函数(具体怎么提取,你得看相关的书籍),OOP或FP像MVC模型一样,成功的把你的代码分割成了更小的组成部分,每个方法或函数里代码都只有10行左右,你几乎回到了“Hello World”时代。

你需要单元测试吗?(你能保证你的系统没有BUG吗?)

这个复杂系统是由1950个函数和方法组成,如果想要确定系统整体没有BUG,就等同于确定组成这个系统的1950个函数和方法没有BUG。
而单元测试就是做这个事情的,显而易见,如果你写了单元测试,并且每个函数都通过了,你就可以骄傲的说:这个系统没有BUG!(当然这是代码的角度,而非功能和产品的角度)



-——————————————————-—结论—————————————————————

虽然,从绝对的角度说,单元测试很重要,但是,从相对的角度来讲,小的代码量,简单固定的需求,个人开发,一锤子买卖等等都会让单元测试显得不那么重要,并且你一直开发的很舒服,这就是为什么有的人感受不到单元测试的重要性(这种情况下的确也许不用写单元测试)。记住,单元测试的威力更多不是体现在新代码的编写上,而是对已有代码的更改。但程序员的智慧是有限的,系统的复杂度却是无限的,随着更大挑战的到来,当系统的复杂度超过了你的逻辑,记忆能力,你必须依靠别的工具来帮助你减少问题。(宇宙中最复杂的系统就是宇宙本身了,假设宇宙是上帝写的系统,上帝可能太聪明了,所以可能没写单元测试,虽然你也是你软件系统的创建者,但你不是上帝)

如果你现在在做一个较大的项目,这个项目的需求很多,所以你一直在开发,你遇到了这样的痛苦状况:1.客户总能在使用中找出BUG,2.每次代码的改动,都会导致一些意想不到的BUG出现。这个时候,单元测试可以挽救你。

-——————————————————-—问答—————————————————————
即使我看了单元测试的书,也一头雾水,不知道怎么测试我的系统:

这种情况可能是你代码本身导致的,首先你要写具有“可测性”的代码,这意味着你不能写面向过程的,流水式的,几百行逻辑堆一起的代码(也叫意大利面代码,就像一盘意大利面一样搅在一起的代码。),你要学一些模块化技巧,面向对象函数式编程理念,还有很多其它具体方法,比如能用本地变量,就不要用全局变量等等,让你的代码具有可测性,这些知识的学习应该放在单元测试之前。

单元测试代码比功能代码也多,这样成本很高:

事实上单元测试代码都是异常简单的一些“断言”代码,断言就是判断一个函数或对象的一个方法所产生的结果是否等于你期望的那个结果,这样的代码看起来很多,但事实上书写的成本很低。(因为我们开发软件的大部分时间用在了思考上,而不是敲代码上,单元测试的代码逻辑很简单,不需要太多思考)。

不是有UI界面吗,点来点去就可以测试了啊:

你完全可以这样做,直到你觉得这么枯燥的事情真的应该交给电脑去做,或者功能越来越多,你只点击你认为影响到的功能,但总会有那些你认为不会影响到的功能也被影响了,你又懒得全部点一遍,单元测试是在你每次改完代码后自动执行,获得反馈只要几秒,并且会把所有功能跑一遍。

我们项目有专职测试人员啊,写单元测试的必要还大吗:

单元测试是检查代码粒度的bug(一般是以函数和对象的方法为粒度),你可以依赖测试人员,但如果你不想在修改自己一个月前写的代码时自己把自己弄到吐血(或者把别人弄到吐血),最好在当初就写好测试代码,这个工作的责任完全属于程序员。外国已经有很多资深程序员论证了,不论你的单元测试代码质量有多高,覆盖面有多全,单单是你去做这一件事,就可以很大程度的提高你的功能代码的质量,以及大幅减少BUG的存在。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
软件测试笔试题汇总
架构之路(一):目标
CSDN技术中心 开发75条(写的不错)
程序员为什么不写单元测试
公司内部培训的一些收获
普通软件项目开发过程规范(三)—— 执行阶段
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服