by JOKER on 2013/05/05

最近状态不是很好,负能量堆到积爆表,静下心来看书写点东西才是出路。给瞎折腾的这两年,做个总结吧。

一些practice和总结

充分单元测试能帮助项目快速推进。看起来单元测试会增加开发时间,但事实上大多数时候它不但会缩短当前功能开发到release的时间,还能为后续的功能的开发做铺垫。

单元测试覆盖率必须保证绝大部分业务逻辑被覆盖。实践起来就是,除了一些异常分支,覆盖所有可以覆盖的代码。这样单元测试才能起到哨兵的作用,在写新逻辑和重构代码的时候,保证一旦旧代码的正确性被破坏,单元测试马上fail预警。如果单元测试的覆盖率不够,是无法被依赖的。单元测试的作用得在覆盖率达到一个比较高的值的时候才能完全展现。

单元测试有助于提高代码质量。由于需要考虑代码的可测试性,有利于促成依赖注入(DI)、控制反转的设计。控制代码之间的耦合程度。站在开发者的角度来说,test case有助于提高开发者的编码和设计能力。一点经验是慎用单件(Singleton)。单件其实就是OO世界的全局变量,所有使用单件的代码都会和它强耦合,在测试的时候难以隔离。项目中遇到很多复杂繁重的单件,需要大量时间初始化,严重拖累了test case的执行效率。

用循序渐进的方法处理遗留代码,小规模重构,低痛低风险;持续重构,零修碎补。我刚进入项目的时候,项目有大概两万行的遗留代码,里面有比较多晦涩的业务逻辑,代码风格和结构都有一些问题,测试覆盖率不到30%。没时间完全重写,只能循序渐进,每开发一个新功能,重构一个老模块并补充test case,大概用了半年重构了大部分代码、补充test case。并且每次新feature开发都会分出一部分时间对之前的代码进行重构。

童子军军规:走的时候要比来的时候干净。破窗效应:一扇窗户被打破不修理,很快会有越来越多的窗户被打破(Bob大叔《Clean Code》)。这两条的想达到的效果是促进良性循环、避免恶性循环。我具体的实践是:

  • 保证每次代码提交test case覆盖率只能提高不能降低
  • Fix原有代码中所有的编译warning、findbugs、checkstyle warning,并保证commit新代码不引入新的warning

通过坚持这两个原则,半年后项目代码质量有明显提高,test case覆盖率从30%提升到85%,sonar的Rules compliance从80%提升到95%,代码重复率从10%降低到0%。而代码质量的提升对开发效率的帮助也是明显的,bug定位、添加新feature变得容易,功能测试发现的bug数和消耗的时间都有减少。

重视工具:流程固化在工具中,自动化所有重复工作。公司层面的实践是:有一个专门的team负责内部工具,并且这个team里都是最优秀的人;对于小型创业公司就是买适合自己的工具。流程是痛苦的,好的工具可以消灭或者减轻这些痛苦。目前的项目在这方面做的很不好,流程的实施,依赖人的职业性对抗人性的弱点,带来的后果是时间的浪费、人的疲惫以及生产效率降低。

尽量创造两人协作的环境。一个人孤独的做事对人对事的要求都太高(人要长时间自我驱动,事要靠谱),而三个人协作很难达到三倍的效率(沟通成本指数上升),但是两人协作却可以达到两倍的效率。两人协作可以既保证概念完整性又保证效率,父母抚养小孩是典型的例子(《设计原本》中文版P56 第六章 阐述了这个观点)。在复杂的项目里,很难把人数控制在两人,但也可以创造局部的两人合作。Two is the magic number

测试金字塔

测试金字塔

测试方面一个重要的总结是测试金字塔,其想表达的是:bug发现的越早,处理的成本越低。由此引出一个原则:尽量早地发现bug,尽量在开发过程中发现bug,而不是过度依赖QA,单元测试和持续集成是重要手段。下面的表格说明了bug发现阶段所增加的成本。

发现BUG的阶段 相比在前一阶段修复BUG的额外成本
Coding 直接改代码
开发期间部署测试 Debug,重新ci代码,重新部署
QA 和QA沟通,完成bug提交、确认、fix、回测的流程
上线后 处理用户反馈,重新走上线流程

用到的工具

    • 单元测试框架JUnit/TestNG

一两年前JUnit和TestNG相比简直是弱爆了,现在JUnit也逐步赶了上来,补充了一些不错的feature,比如timeout、exception、Parameterized Test等实用功能,详见JUnit wiki

    • Spring Testing

Spring TestContext Framework,实现测试组件的依赖注入,避免繁琐的setUp过程。 官方文档

    • mock框架mockito、PowerMock

mockito比JMock和easyMock有更优雅的语法 项目主页
用PowerMock测试static方法和final类 项目主页
用反射测试private方法(spring的ReflectionTestUtils)

    • lombok

编译期代码生成工具(JDK1.6+),自动生成getter/setter、toString、equals、hashCode、构造函数,checked exception转runtime exception,自动close资源等各种magic,项目主页

    • JRebel

基于java agent的热部署工具,实现代码的热替换,避免重启web容器。大幅提高开发效率(尤其是对启动过程比较漫长的应用来说),支持大多数java ee容器。结合Ant的sshexec task可以实现一键从开发机更新代码到测试机,并且立即生效。项目主页

    • 持续集成工具jenkins

Jenkins结合Ant、覆盖率测试工具cobertura、java代码静态检查工具checkstyle、findbugs、sonar,完成每次提交自动构建、运行test case、计算test case覆盖率、检查代码bug的功能,极大的方便了对代码质量的监控(感谢测试开发同事的工作)。

    • teambox.com

项目协作的工具,一个SaaS,速度还凑合,对于小团队来说不错,基本功能是task管理,另外还有会话、文件共享、笔记等功能,5个人以下免费用,就是速度略慢。

This is not the end, this is not the beginning.

感谢Barton和Calphy。

THIS ENTRY WAS POSTED IN 技术学习. BOOKMARK THE PERMALINK.

一些practice和总结(转载)的更多相关文章

  1. 转载https://www.luogu.org/problemnew/solution/P1665,http://bailian.openjudge.cn/practice/2002/的新解法

    不知道为什么O(n^4)O(n4)的玄学方法能过,正解显然是O(n^2)O(n2)的,枚举对角线,然后算出另外两点判断存不存在. 关键就在怎么通过对角线算出另外两点的坐标. 先贴公式. int mid ...

  2. Atitit 数据存储视图的最佳实际best practice attilax总结

    Atitit 数据存储视图的最佳实际best practice attilax总结 1.1. 视图优点:可读性的提升1 1.2. 结论  本着可读性优先于性能的原则,面向人类编程优先于面向机器编程,应 ...

  3. 【转载】Recommendations with Thompson Sampling (Part II)

    [原文链接:http://engineering.richrelevance.com/recommendations-thompson-sampling/.] [本文链接:http://www.cnb ...

  4. 【转载】Bandits for Recommendation Systems (Part I)

    [原文链接:http://engineering.richrelevance.com/bandits-recommendation-systems/.] [本文链接:http://www.cnblog ...

  5. [转载] TLS协议分析 与 现代加密通信协议设计

    https://blog.helong.info/blog/2015/09/06/tls-protocol-analysis-and-crypto-protocol-design/?from=time ...

  6. [转载] what's goole mock

    原文: https://code.google.com/p/googlemock/wiki/V1_7_ForDummies 地址被墙了, 看起来费劲, 转载一份 Google C++ Mocking ...

  7. (转载)iOS Framework: Introducing MKNetworkKit

    This article is available in Serbo-Croatian,  Japanese and German. (Translations in Serbo-Croatian b ...

  8. (转载)XML Tutorial for iOS: How To Choose The Best XML Parser for Your iPhone Project

    There are a lot of options when it comes to parsing XML on the iPhone. The iPhone SDK comes with two ...

  9. [转载] 常用 Java 静态代码分析工具的分析与比较

    转载自http://www.oschina.net/question/129540_23043 简介: 本文首先介绍了静态代码分析的基本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代 ...

随机推荐

  1. Servlet主要的作用

    1,收集Request传递过来的参数: 2,把这些参数组织成模型需要的类型: 3,调用模型进行逻辑功能处理: 4,选择下一个页面,先准备好一个页面需要的数据,然后转向下一个页面.

  2. Google Guava学习笔记——基础工具类Joiner的使用

    Guava 中有一些基础的工具类,如下所列: 1,Joiner 类:根据给定的分隔符把字符串连接到一起.MapJoiner 执行相同的操作,但是针对 Map 的 key 和 value. 2,Spli ...

  3. 【BZOJ】【1878】【SDOI2009】HH的项链

    树状数组/前缀和 Orz lct1999 好神的做法... 先看下暴力的做法:对于区间[l,r],我们依次扫过去,如果这个数是第一次出现,那么我们种类数+1. 我们发现:区间中相同的几个数,只有最左边 ...

  4. 【BZOJ】【1036】树的统计

    嗯这题是一道对树进行动态修改&查询的经典题目,可以拿来练习树链剖分~ 啊对于这种动态修改&查询的题目,我们最喜闻乐见的就是在一个序列上去做了,毕竟可以直接套各种数据结构模版啊,比如线段 ...

  5. Matlab绘制透明平面(二元函数)

    一.需求来源 对空间结构聚类,恰好是圆台,找到了上下底面的方程,所以画图. 二.需求解决 2.1 绘制平面 x = linspace(0,5,100); y = linspace(0,4,100); ...

  6. HDU1004 Let the Balloon Rise(map的简单用法)

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...

  7. .NET设计模式(13):享元模式(Flyweight Pattern)(转)

    摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价.那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面 ...

  8. flashdevelop 开发技巧

    FlashDevelop用来编写AS3代码,Flash CS5用来编辑程序所需要的资源(图片,声音-),Flash CS5自带有Flex SDK,在目录 C:\Program Files\Adobe\ ...

  9. Android的事件处理机制(一)------基于回调机制的事件处理

    Android平台的事件处理机制有两种,一种是基于回调机制的,一种是基于监听接口的,现介绍第一种:基于回调机制的事件处理.Android平台中,每个View都有自己的处理事件的回调方法,开发人员可以通 ...

  10. Javascript 正则表达式_4

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...