`
zfanxu
  • 浏览: 126123 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

[转]如何控制单元测试的粒度?

TDD 
阅读更多

单元测试的粒度问题一直是软件开发社区面临的现实问题,最近,陈皓针对StackOverflow上的老问题做了总结,并发表了自己的看法,读者在随后的评论中也进行了讨论。

John Nolan在《How deep are your unit tests?》中问道:

TDD需要花时间写测试,而我们一般多少会写一些代码,而第一个测试是测试我的构造函数有没有把这个类的变量都设置对了,这会不会太过分了?那么,我们写单元测试的这个单元的粒度到底是什么样的?并且,是不是我们的测试测试得多了点?

最佳答案是:

老板为我的代码付报酬,而不是测试,所以,我对此的价值观是——测试越少越好,少到你对你的代码质量达到了某种自信(我觉得这种的自信标准应该要高于业内的标准,当然,这种自信也可能是种自大)。如果我的编码生涯中不会犯这种典型的错误(如:在构造函数中设了个错误的值),那我就不会测试它。我倾向于去对那些有意义的错误做测试,所以,我对一些比较复杂的条件逻辑会异常地小心。当在一个团队中,我会非常小心的测试那些会让团队容易出错的代码。

最让人意外的是,这个答案是由XP和TDD的创造者Kent Beck给出的! 难怪有人评论说:

只是要地球人都不会觉得Kent Beck会这么说啊!我们有大堆程序员在忠实的追求着100%的代码测试覆盖率,因为这些程序员觉得Kent Beck也会这么干!我告诉过很多人,你在你的XP的书里说过,你并不总是支持“宗教信仰式的Test First”,但是今天Kent这么说,我还是很惊讶!

陈皓则是非常同意Kent的回答:“怎么合适怎么搞,爱怎么测试就怎么测试,只要自己和团队有信心就可以了。没有必要就一定要写测试,一定要测试先行。”

其他排名靠前的答案包括:

Dominic Rodger

为可能会出错的地方和边界情况编写单元测试。另外,单元测试应该跟着缺陷报告走,在修补缺陷之前编写好单元测试。开发人员就会对代码充满自信:一是bug已经修补,二是bug不会重现。

kitofr

关于TDD最大的误解之一就是第一个字母——测试(T)。这也是BDD出现的原因。因为大家没有真正理解第一个D(驱动)的重要性。我们总是倾向于对测试关注更多,而对设计的驱动关注太少。我想这是一个模糊的回答,但是你应该考虑如何驱动你的代码,而不是测试什么,这是覆盖率工具该做的事情。设计是一个很大而且问题更多的问题。

最后,陈皓表达了自己的观点:

  • 目前的国内教育模式让我们习惯于标准答案,习惯于教条,从而不会思考!敏捷开发中的若干东西似乎都成了软件开发中对某种标准答案的教条,实在是悲哀!
  • 软件开发是一种脑力劳动,是一种知识密集型的工作,就像艺术作品一样,创作过程和成品是没有标准答案的。
  • 软件的质量不是测试出来的,而是设计和维护出来的。就像工匠们在一点一点地雕琢他们的作品一样。

许多读者在原文的评论中表达了自己的看法

  • 对于要做多细,我的经验就是:当我不在的时候,如果同事打电话说有Bug,询问是否会是我的问题,而我可以很自信的回答No的时候,就可以啦! 所以最享受的就是大家加班,而我在放心玩乐的时刻。这让我想起了一件事情,有位同行朋友学车,一开始总想让师傅告诉他,需要“打点方向”的时候到底是多少度? 需要“加点油”的时候到底是加到每小时多少公里? 后来知道了,没人会告诉你,你得自己Do!
  • 其实我觉得在现今大型企业的团队中, 开发人员的职责就是开发和保证代码正确的实现 至于测试则基本是交给测试的人员来做,而测试人员又拿着测试的工资,他们不会考虑开发人员的水平,而是循规蹈矩的去完成整个测试流程。
  • 关于StackOverflow上出现的大量排斥TDD的观点,我尝试这样来解释:占主流群体的底层程序员在没有监督的情况下缺乏责任心只求应付工作......到了工作岗位上也是如此,领导在不在大不一样。总结下来就是,大多数人在没有监督的情况下容易慵懒应付。这应该是人的天性。后来工厂出现的流水线,应该就是对付这种情况的。把工作流程标准化、流水线化,让整个流水线上的人都没机会偷懒。我想这也是TDD的目标之一。如果没有足够的测试用例,你怎么确认某个模块是功能完整的无明显缺陷的?如果原作者离职了,后来的维护者修改了先前的代码,又如何保证不影响以前的功能?要知道,你修改一个新bug,很可能会把以前的多个旧bug放出来,有经验的开发者应该明白我说的什么意思。于是软件越来越难于维护,维护者也越来越排斥修改代码,一潭死水无人敢碰,软件提前寿终正寝。我最终的结论就是,TDD要由项目管理者推动实施,而不能征求下面程序员的意见,——他们虽然人数众多,但就像面对老师的学生一样,总是要求玩耍而不是学习,这对项目本身是无益的。
  • 说白了还是看你怎么用,TDD也只不过是个方法罢了,工具而已,又不是思想或者本质之类的。我个人开发就很不TDD,即使需要写测试也是针对公开的接口或者某些特定的调用去做测试程序,这样的好处是达到测试代码的目的,同时又有了一个测试程序。缺点是这个测试程序不带好集成到发布过程。但换言之,好的程序员写的代码自然质量较高,差的程序员有没有单元测试一样差,甚至于无法保证差的程序员写的测试单元没有BUG,如果有BUG那不是更悲剧?
分享到:
评论

相关推荐

    pytest学习.doc

    3、能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试(pytest+requests); 4、pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium...

    Pytest官方文档翻译.pdf

    3、能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试(pytest+requests); 4、pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium...

    logger-js:一个简单的模块,用于登录到具有细粒度控制和可扩展性的控制台

    您可以在闲暇时运行单元测试。 我已经在以下方面以 100% 的通过率对其进行了测试: Chrome合金 火狐 Internet Explorer 9+ † 苹果浏览器 † 请注意 Internet Explorer 8 可以工作,但前提是控制台打开。 否则,它...

    Pytest测试框架基本使用方法详解

    3、能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试(pytest+requests); 4、pytest具有很多第三方插件,并且可以自定义扩展 如pytest-selenium(集成...

    laravel-repositories:[ABANDONED] Rinvex Repository是Active Repository的一种简单,直观,智能的实现,它具有Laravel极其灵活的粒度缓存系统,用于抽象数据层,使应用程序的维护更加灵活

    最大化可通过自动化进行测试的代码量,并隔离客户端对象和域模型以支持单元测试。 将行为与相关数据相关联。 例如,计算字段或在实体中的数据元素之间强制执行复杂的关系或业务规则。 快速示例(TL; DR) Rinve

    arduino_ci:来自Ruby gem的Arduino库的单元测试和持续集成(CI)

    无需硬件即可针对库运行单元测试提供了一个模拟系统,可以对硬件输入(包括系统时钟)进行细粒度控制验证库中包含的任何示例草图的编译可以使用不同的硬件选项测试各种arduino板将library.properties中的条目与...

    葡萄树:一个高效的访问控制库,支持细粒度的控件

    运行单元测试 克隆此仓库。 > git clone git@bitbucket.org:surfingcrab/vines.git > cd vines > composer install 通过导入“ config”目录下的“ vines_schema.sql”文件,创建数据库并生成模式。 使用诸如...

    java8看不到源码-qemu-java:QEmu和KVM的Java客户端:执行、管理和QApi

    脚本无法全面测试故障模式:磁盘、CPU、网络、机架、端口,因为它们无法以细粒度的方式控制模拟环境。 该软件包允许对复杂网络拓扑的组装和操作进行自动化,控制应用程序和底层 VM 的整个生命周期,以及以编程方式...

    DataGear数据可视化分析平台

    (不执行单元测试编译,无需预先配置单元测试环境) mvn clean package -DskipTests 运行: cd datagear-webappembd/target/datagear-[version] (Linux环境) ./startup.sh (windows环境) startup.bat 调试: 1...

    node_acl:节点应用程序的访问控制列表

    NODE ACL-节点的访问控制列表该模块提供了受Zend_ACL启发的简约ACL实现。... 具有良好的单元测试覆盖范围的可靠实施。安装使用npm: npm install acl文献资料例子通过要求acl模块并使用有效的后端实例对

    aclify:节点访问控制列表(ACL)

    具有良好的单元测试覆盖范围的稳健实施。 严格打字 文献资料 专卖店 Aclify提供了多种存储数据的可能性: 记忆 雷迪斯 MongoDB 例子 通过要求acl模块并使用有效的商店实例实例化它来创建acl模块: 从进口 import...

    CISCO交换机配置AAA、802.1X以及VACL

    请求者和验证者都拥有端口访问实体(PAE)单元,请求者的PAE负责对验证信息请求做出响应,验证者的PAE负责与请求者之间的通信,代理授予通过验证服务器验证的证书,并且控制端口的授权状态。 验证服务器:提供向...

    OTN原理、发展白皮书

    而基于WSS的ROADM,可以在所有方向提供波长粒度的信道,远程可重配置所有直通端口和上下端口,适宜于实现多方向的环间互联和构建Mesh网络。 二、华为OTN设备OptiX OSN 8800和OptiX OSN 6800 OptiX OSN 6800 智能光...

    Vulkan Programming Guide

    作为交换,Vulkan提供对设备的更多控制,一个干净的线程模型,以及比它取代的API更高的性能。 此外,Vulkan被设计为不仅仅是一个图形API。它可以用于异构设备,如图形处理单元(GPU),数字信号处理器(DSP)和固定...

    shargs:arg shargs是用于构建命令行参数解析器的库

    广泛记录并经过良好测试(800多个单元和集成测试)。 零运行时相关性的模块化库布局。 安装 打包安装(推荐): npm install --save shargs 作为模块安装: npm install --save shargs-core # core functions ...

    jquery-ooyala:Ooyala Javascript Player API的现成的,易于使用的,可扩展的包装器

    用于与Ooyala播放器的高级和低级接口访问播放器的全局OO对象以及基础Ooyala播放器本身的机制可订阅的类似于jquery的界面,用于订阅玩家事件对插件的自动初始化逻辑的细粒度控制企业级使用构建全套单元测试100%的...

    聊天机器人系统设计方案.pdf

    ⽐如它能帮助我们找到没有依赖关系的软件模块或⼦系统,以便独⽴开发和测试,同时进⼀步根据依赖关系确定开发和测试软件模块 的先后次序。 依赖视图展现了软件模块之间的依赖关系。⽐如⼀个软件模块A调⽤了另⼀个...

    Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐)--随书源代码

    CruiseYoung提供的带有详细书签的电子书籍目录 ... 该资料是《Oracle SQL高级编程》的源代码 对应的书籍资料见: Oracle SQL高级编程(资深Oracle专家... 15.3 单元测试 418 15.4 回归测试 422 15.5 模式修改 422 15.6...

Global site tag (gtag.js) - Google Analytics