为什么我们要做单元测试?(二)

引子

当我第一篇博客发布,并被张善友老师的公众号转载之后,在公众号文章和博客园的留言中,许多开发者纷纷表示,单元测试作为企业行为,与实施的技术栈不同,不是开发者个人行为,实施单元测试花费的时间精力过于庞大,与实际效果严重不对等,而且如果过度的采用单元测试,也会增加新的测试点,因为单元测试代码本身就需要进行测试等。

 从这些回复可以看出,程序员要不要编写单元测试这种话题,大概做传统开发时,问程序员要不要写项目文档一样充满争议。正如大家都深刻明白项目文档的重要性,但是一旦程序员需要编写项目文档了,往往会对这个事情产生抵触情绪,这实际上是绝大多数开发者的通病。

单元测试也是这样的矛盾纠结体在长沙.net技术社区就有不少朋友纷纷表示,他们都曾经试图在公司推动单元测试的应用,但是受到了自上而下的反对声,最终迫于压力,只能放弃。 而之所以阻力这么大,其主要原因是编写单元测试会增加额外的时间,因为编写单元测试,不仅仅只是编写一个简单的测试入口,而是一系列步骤,但是领导要求在最短的时间看到效果,并且有的领导还经常改变主意,如果设计了一个优秀的单元测试用例,有时候甚至会因为无法适应需求的变化,而最终腐烂。 

显然,使用单元测试和更高的单元测试的代码覆盖率,大概是一个试金石。过去在长沙还很少有企业会问开发者会不会使用单元测试,但是近年来越来越多的企业会问候选人代码覆盖率的问题,所以作为开发者,可以尝试从单元测试开始,努力提高自己的代码习惯,编写更加高质量的代码。

有哪些公司在要求编写单元测试?

过去,单元测试一直是专业软件公司的首选,有一位原诺基亚核心部门的开发者说为诺基亚内部,对单元测试的要求很高,虽然没有达到百分之百,但也有非常高的要求,在《构建之法》中,邹欣老师介绍了微软的开发实践,也对单元测试覆盖率提出了很高的要求。 当然有的读者或许会嗤之以鼻,这些都是古典软件公司,举这些例子有什么意义呢?中国式IT 公司,哪家都是996,哪里还有什么时间实行单元测试? 

然而,优秀的互联网公司都开始推行devops 作为企业信息化建设过程中的最佳实践标准,持续集成和持续发布都对单元测试有很高的要求,例如在阿里巴巴java 开发者手册中,就明确提出了以下一系列指标,要求开发者务必采用单元测试方法,尽可能的提高代码质量。

  1. 【强制】好的单元测试必须遵守 AIR 原则。

  2. ...此处省略七百字

  3. 【推荐】单元测试的基本目标:语句覆盖率达到 70% ;核心模块的语句覆盖率和分支覆盖率都要达到 100% 

参见原文阿里巴巴Java 开发者手册,由此可见,单元测试已经作为一种行之有效的手段,显然已经成为了中国优秀互联网企业的必然之选。

单元测试中的代码覆盖率有什么用?

代码覆盖率是单元测试的重要衡量指标,反映了单元测试中测试用例对被测代码的覆盖程度,是对代码的测试质量衡量的重要指标。

在十年前,博客园《代码覆盖率浅谈》(参考资料1)一文,深入浅出的介绍了单元测试的四种类型, 包括语句覆盖,判定覆盖,条件覆盖,路径覆盖四种类型,作者指出,单元测试覆盖率结果,有以下作用:

a. 覆盖率数据只能代表你测试过哪些代码,不能代表你是否测试好这些代码。 

b. 不要过于相信覆盖率数据。

c. 不要只拿语句覆盖率(行覆盖率)来考核你的测试人员。 

d. 路径覆盖率 > 判定覆盖 > 语句覆盖 

e. 测试人员不能盲目追求代码覆盖率,而应该想办法设计更多更好的案例,哪怕多设计出来的案例对覆盖率一点影响也没有。 

在软件开发过程中盲目的追求的高代码覆盖率,往往得不偿失,尤其是为了提高代码覆盖率而做的单元测试,往往只会成为累赘。

合理的操作形式应该是基于实际用例出发,设定更多的用例场景,实现基于用户场景驱动的单元测试覆盖,像在阿里巴巴开发者手册中说的,测试人员与开发人员配合,共同完成测试用例覆盖,就是一种不错的应用实践。

当然,即便测试缺位,开发者也完全应该主动的承担更多单元测试的职能,尽可能多的思考用户场景中可能存在的变数。

编写好的单元测试的一些小技巧


技巧一,多看书肯定是不错的

有朋友问,怎么写好单元测试?有什么书推荐么?我很惭愧,我自己的代码单元测试的覆盖率还相当低,可能没办法给出指导,我想多看书肯定是没错的,而编写单元测试的书,还挺多的,例如这一本,《单元测试的艺术》,一看就是基于C#的,可以试一试。 


 而想入单元测试的门,可以看看我后面找到的一系列引文,相信能给你带来方便。 


技巧二,运用测试框架 

1、单元测试框架:XUnit、NUnit、MSTest等.

2、测试运行工具:xunit.runner.visualstudio 。类似如:Resharper的xUnit runner插件。 

3、模拟框架:Moq、RhinoMocks、NSubstitute、FakeItEasy等。  


技巧三,灵活的运用事务回滚或内存数据库,避免单元测试数据污染正常数据

前者是阿里巴巴开发者手册中提到的一种方法,在有的场景下也挺实用的,不过有开发者指出,可以使用模拟内存数据库来解决这个问题更为妥当,例如使用Effort.EF6,通过nuget获取,使得创建一个伪造的、供EF容易使用的内存数据库成为可能。与这类似的,还可以使用HttpSimulator来模拟http 请求。 


技巧四,使用依赖注入和单例模式改良不可测代码

静态类为代码编写带来了许多便利,但是也使得代码测试变得相对困难,而使用单例模式进行改良则使得操作更可控。 

总结

人生苦短,撸码不易。从选择成为开发者的那一天起,我们就被迫承受了许多压力,尤其是技术发展的不确定性,更是如此,你永远也不知道自己当下的选择是否正确,说不定你今天最为熟悉的技术或框架,明天就凉凉了。尤其是现在的各种自媒体,时不时的发几篇文章来输出焦虑,巴不得天天说优胜劣汰才能获得读者的关注一般,让开发者们压力更大。


我觉得,技术是解决问题的方法,而良好的代码习惯则是自身心法,尤其是单元测试,更是一种好习惯,先别总想着担心自己被淘汰,努力的使自己习惯更好,总会获得无穷收获。


参考资料1:《代码覆盖率浅谈》https://www.cnblogs.com/coderzh/archive/2009/03/29/1424344.html?tt_from=copy_link&utm_source=copy_link&utm_medium=toutiao_ios&utm_campaign=client_share.

参考资料2:《代码覆盖率强迫症》https://www.infoq.cn/article/test-coverage-ocd.
参考资料3:《
代码覆盖率 (Code Coverage)从简到繁

https://www.cnblogs.com/jacksundatashare/p/5083352.html.
参考资料4,《
C#单元测试,带你快速入门http://www.cnblogs.com/zhaopei/p/UnitTesting.html?from=singlemessage&isappinstalled=0.

码字不易啊..哈哈smiley_21.png

(本文是作者为社区贡献的内容,赞赏的所有费用都将作为长沙.NET技术社区运营费用,感谢您的关注,让我们一起努力,共同创造长沙.NET技术社区更好的明天)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316394.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P4159 [SCOI2009] 迷路

P4159 [SCOI2009] 迷路 题意: 该有向图有 n 个节点,节点从 1 至 nn 编号,windy 从节点 1 出发,他必须恰好在 t 时刻到达节点 n。 现在给出该有向图(带边权),你能告诉 windy 总共有多少种不同的路径吗? …

程序员修神之路--提高网站的吞吐量

点击上方蓝色字体,关注我们菜菜哥,有个事你还得帮我呀呦西,YY妹子,最近天这么热了,你怎么还穿这么多?苦笑一下.....前几天写了几个接口,领导让提高一下接口吞吐量这是你技术提高的大好机会呀可吞…

一份.NET 容器化的调查小结

小编在上个月在微信公众号“dotnet跨平台” 做了一个针对.NET 容器化的调查:.NET Core 容器化调查,参与人数702人,由于软件定义基础设施方兴未艾,编排和自动化领域kubernetes占据了主体地位,在平时的工作中和身边的同学…

P2148 [SDOI2009]ED

P2148 [SDOI2009]E&D 题意: 有2n堆石子,第2k-1堆和第2k堆是一组,现在两个人轮流操作,每次操作任选一组石子,然后将改组中的一堆石子移走,将另一堆式子分割成两堆,形成新的两堆石子&#x…

扒一扒.NET Core的环境配置提供程序

前言很久之前,在玩Docker的时候顺便扒了扒,最近,终于下定决心花了些时间整理并成文,希望能够给大家一些帮助。目录 .NET Core中的配置ASP.NET Core中的配置扒一扒环境变量提供程序为什么是“__”?“__”如何变成了“&…

[HNOI2016] 序列(线段树 + 莫队 + 倍增)

problem luogu-P3246 心路历程卡常历程问题存疑 一直在想莫队的做法。发现左右指针的移动对应一段左/右端点固定的子序列&#xff0c;然后可以一个数代表一段相同的贡献。 就开始求 lsti,nxtilst_i,nxt_ilsti​,nxti​ 了。 仔细想想需要找到 lstlsti<l≤lstilst_{lst_…

《从零开始学ASP.NET CORE MVC》:ASP.NET Core 中的 Main方法(5)

本文出自《从零开始学ASP.NET CORE MVC》推荐文章&#xff1a;ASP.NET Core Web 项目文件ASP.NET Core 中的 Main方法一个开始专心写字的人在ASP.NET Core项目中&#xff0c;我们有一个名为Program.cs的文件。在这个文件中&#xff0c;我们有一个public static void Main&#…

.NET中的状态机库Stateless

标题&#xff1a;.NET中的状态机库Stateless 作者&#xff1a;Lamond Lu 地址&#xff1a;https://www.cnblogs.com/lwqlun/p/10674018.html[1]介绍什么是状态机和状态模式状态机是一种用来进行对象建模的工具&#xff0c;它是一个有向图形&#xff0c;由一组节点和一组相应的转…

.net core webapi 前后端开发分离后的配置和部署

背景&#xff1a;现在越来越多的企业都采用了在开发上前后端分离&#xff0c;前后端开发上的分离有很多种&#xff0c;那么今天&#xff0c;我来分享一下项目中得的前后端分离。B/S Saas 项目&#xff1a;&#xff08;这个项目可以理解成个人中心&#xff0c;当然不止这么点功…

ASP.NET Core使用Jaeger实现分布式追踪

前言最近我们公司的部分.NET Core的项目接入了Jaeger&#xff0c;也算是稍微完善了一下.NET团队的技术栈。至于为什么选择Jaeger而不是Skywalking&#xff0c;这个问题我只能回答&#xff0c;大佬们说了算。前段时间也在CSharpCorner写过一篇类似的介绍Exploring Distributed T…

长沙开发者技术大会暨.NET技术社区成立大会倒数第13天

待你扬帆起航&#xff0c;一起精彩纷呈&#xff01;长沙开发者技术大会暨.NET技术社区成立大会倒数第13天&#xff01;2019年4月21日期待与你相聚在.NET技术社区&#xff01;我们今天会完成海报制作和报表表单&#xff0c;海报内容初步如下所示&#xff1a;活动信息 长沙开发者…

C#并行编程(1):理解并行

什么是并行并行是指两个或者多个事件在同一时刻发生。在程序运行中&#xff0c;并行指多个CPU核心同时执行不同的任务&#xff1b;对于单核心CPU,严格来说是没有程序并行的。并行是为了提高任务执行效率&#xff0c;更快的获取结果。与并发的区别&#xff1a;并发是指两个或者多…

P2163 [SHOI2007]园丁的烦恼(二维数点模板题)

P2163 [SHOI2007]园丁的烦恼 题意&#xff1a; 在一个二维平面内有一些点&#xff0c;给你一个左上角和右下角的点&#xff0c;问这个范围内有多少点 题解&#xff1a; 二维数点模板题 我们设F(a,b)表示以(0,0)为左下角&#xff0c;(a,b)为右上角的矩阵内有多少点 如图不难…

Orleans MultiClient 多个Silo复合客户端

介绍Orleans.MultiClient 是一个 Orleans 复合客户端&#xff0c;只需要简单配置就可以简单高效连接和请求 Orleans 服务。Orleans.MultiClient 可以轻松连接多个不同服务的 Orleans 服务,在请求 Orleans 时会根据请求的接口自动寻找 Orleans 客户端&#xff0c;使用者无需关心…

ASP.NET Core 进程内(InProcess)托管(6)《从零开始学ASP.NET CORE MVC》:

本文出自《从零开始学ASP.NET CORE MVC》推荐文章&#xff1a;ASP.NET Core 中的 Main方法ASP.NET Core 进程内(InProcess)托管在这个视频中我们将讨论在ASP.NET Core中的进程内(InProcess)托管模型什么是Kestrel服务器当一个 ASP.NET Core 应用程序执行的时候&#xff0c;.NET…

约会安排 HDU - 4553

约会安排 HDU - 4553 题意&#xff1a; 题意又丑又长就不叙述了 题解&#xff1a; 这个题一开始理解错了。。。题目相当于是有三种情况占据时间&#xff0c;分别是学习&#xff0c;女神和屌丝&#xff0c;我们用不同的lazy来表示女神和屌丝&#xff0c;根据优先级去更新状态…

ML.NET机器学习、API容器化与Azure DevOps实践(一):简介

打算使用几篇文章介绍一下.NET下的机器学习框架ML.NET的具体应用&#xff0c;包括一些常用的业务场景、算法的选择、模型的训练以及RESTful API的创建、机器学习服务容器化&#xff0c;以及基于Azure DevOps的容器化部署等等相关的内容。如果你从来没有玩过机器学习&#xff0c…

Picture POJ - 1177(矩形周长并))

Picture POJ - 1177 题目&#xff1a; 多个矩阵相交在一起&#xff0c;问新图形的周长是多少 题解&#xff1a; 参考题解 周长分为两部分&#xff1a;横线和竖线 横线计算方法&#xff1a;现在总区间被覆盖的长度和上一次总区间被覆盖的长度之差的绝对值 那么我们只需要从…

聊一聊C# 8.0中的await foreach

很开心今天能与大家一起聊聊C# 8.0中的新特性-Async Streams,一般人通常看到这个词表情是这样.简单说,其实就是C# 8.0中支持await foreach.或者说,C# 8.0中支持异步返回枚举类型async Task<IEnumerable<T>>.好吧,还不懂?Good,这篇文章就是为你写的,看完这篇文章,你…

ASP.NET Core 实现带认证功能的Web代理服务器

引言最近在公司开发了一个项目&#xff0c;项目部署架构图如下&#xff1a;思路如图中文本所述&#xff0c;公司大数据集群不允许直接访问外网&#xff0c;需要一个网关服务器代理请求&#xff0c;本处服务器A就是边缘代理服务器的作用。通常技术人员最快捷的思路是在服务器A上…