一小时写给同组的如何使用工具检测代码质量

因为要做个小项目,同组的同事都比较年轻,为了规范下代码,因此简单的写了下怎么提高代码质量,分享一下:

在接口不通的情况下进行单元测试

使用Mockito, 如果获取余额部分代码为:

public class PayServiceImpl implements PayService {
    private BizPayService bizPayService;
    @Override
    public BigDecimal getBalance(String pin) {
        try {
            return bizPayService.getBalace("", 0);
        } catch (BizVirtualPayException e) {
             e.printStackTrace();
        }
        return null;
    }
    public void setBizPayService(BizPayService bizPayService) {
           this.bizPayService = bizPayService;
    }
}

bizPayService为一个dubbo接口,如果没有提供,那么测试代码如下:

public class PayServiceTest {
    @Test
    public void testGetBalance() throws BizVirtualPayException{
        PayServiceImpl payService = new PayServiceImpl();
        BizPayService bizPayService = mock(BizPayService.class);
        when(bizPayService.getBalace("", 0)).thenReturn(new BigDecimal(20.00));
        payService.setBizPayService(bizPayService);
        Assert.assertEquals(20.00, payService.getBalance("").doubleValue(), 0);
    }
}

单元测试覆盖率

  • 安装Eclemma, 安装包点击这里下载
  • 安装后在eclipse中:

    多了最左侧的图标

  • 对测试代码右键Coverage as进行执行,执行完后:

    显示该测试代码覆盖率

  • 展开可见:

  • 红色为未覆盖部分,说明该处代码没有测试到可能存在隐患

代码质量三驾马车之一-findbugs

静态代码缺陷检测工具

1. 对代码击右键,选择FindBugs->FindBugs,我们的开发环境中一般内置了该插件

2. 执行完成后,在代码根目录会显示找到的缺陷个数如图:

3. 打开对应的类,在左边框有如下的图标,点之:

4. 下面会出现具体的说明:

5. 对字段进行说明

Confidence 是造成缺陷的可能性, 一般为High的必须解决,这里是因为日志过滤其中使用了静态变量,而用实例方法对静态变量有可能导致并发的问题。

6. 要求

Confidence 为Hign的必须解决。

其他Confidence的必须理解其可能会造成的影响,确定不会影响系统运行时可以不解决

7. 常见问题

  • 缺少空指针检查 这个不仅会造成代码缺陷,还会减少性能,因为不显示的检查空指针,JVM会动态的加进去这部分内容
  • 打开资源没有在finally中关闭
  • 冗余空指针检查 紧接着new 之后进行空指针检查,是没有必要的
  • try{}catch空指针 通常我们的代码如下:Connection conn = null; try{conn = ..}catch(Exception e){}finally{conn.close}这个时候这个conn有可能为空。
  • 用==比较对象 我们出现过这个问题,用==比较Integer导致bug
    • 成员变量和局部变量同名 会导致变量被覆盖

    代码质量三架马车之二-CheckStyle

    1. 对代码击右键
    2. Window->Show view-> CheckStyle->Checkstyle violations打开一个新的View,有所有代码规范有问题的列

    3. 常见问题

      这个工具只有代码规范和风格的检查,一般我们需要注意:

      • 空行, 删除
      • 关键字之间的空格 要加,加上代码好看
      • 注解相关 可以忽略
      • 注释 后面单说
      • 命名 常量名, 变量名,方法名。 这个要改,不改不专业
      • 类长 要改,太长的类说明设计有问题
      • 行长 可以通过设置eclipse Ctrl+F的动作来改
      • 方法长 要改,太长说明设计有问题
      • equals hashCode必须同时覆盖 这个要看HashMap的hash算法的源码部分才能理解为什么

代码质量三家马车之三-PMD

比CheckStyle功能更强的静态代码检查工具,主要是检查一些日常编码中我们经常犯的错误,比如String,StringBuffer的滥用, 复杂度等

1. 右击代码

2. 如上左侧的小图标表示了级别, 带红x的必须解决, 其他的酌情而定

3. 常见问题

  • 空方法 常见于策略,模板等模式的实现中,有的子类没有实现该方法, 这个说明算法设计有问题
  • overriden注解 要加,可以利用eclipse的静态分析功能编译器发现问题
  • System.out.println 要用日志代替,效率极低
  • 抛出JDK自带异常 要用自定义异常代替
  • 复杂度 我们定位不超过12
  • could be final 忽略,这个工具想让我们把所有的变量都加上final,没有必要
  • 没有用泛型 尽量使用
  • 单return 忽略
  • e.printStackTrace() 改为日志打印

注释要求

  1. public 方法必须含有详细注释
  2. private 方法用小方法自注释的风格保证可读性及可维护性
  3. 对外开放API接口要包括包注释
  4. 注释中方法有复杂算法的要进行说明
  5. 分支语句要加注释
  6. 要保证注释中的内容必须与代码逻辑是一致的
  7. 注释要对所有入参进行说明,说明取值范围,边界值,是否允许为空等
  8. 注释要对出参进行说明,特别是集合的情况,要说明该集合是否有肯能为null,如果没有,则用户不用再判空
  9. 注释对异常进行说明,说明可检异常在什么情况下会抛出
  10. 注释要占代码行数的20%左右,尽量达到

补充说明

  1. TDD。

    敏捷开发最佳实践之一: 测试驱动开发。(这个有机会跟大家分享下)

    这是单元测试的一个目的。 先写单元测试,用assert来确定方法的返回结果。在开发代码的时候要注意满足这个期望的结果永远是正确的,有利于设计接口,以及保持正确的返回值。

  2. 减少不用代码

    减少复制粘贴来的大量不用代码。比如BizMessage中所使用到的APIUtils及JSONUtils 这两个类。 其中设计了JSON字符串的处理,但是实际上使用阿里巴巴的FastJSON可以直接满足要求,直接替换之,这样就不用为了这两个类写单元测试了。

    在未他们写单元测试的时候才会发现他们的方法有大量没有使用的部分。

    并且因为写单元测试进行覆盖率的增长是一件很麻烦的事情,会促进大家尽量写行数少的代码,以减少单元测试代码的工作量。

  3. 发现设计问题

    在进行单元测试的时候难避免使用mock技术,当你发现一个类不好mock的时候,那么说明该类在设计上存在问题,具有不可测试性,这样的类应该修改。

  4. 检查代码逻辑错误

    使用覆盖率工具能够检查出大量分支为红色的部分,这个说明我们的单元测试没有测试带该异常分支。同样的,我们的生产环境该分支可能是存在问题的,需要修改。

  5. 单元测试就是对外API文档

    好的单元测试可以看做是一份接入我们API的客户端文档,比如我们写API的使用说明的时候,就可以按照我们单元测试的逻辑来写

时间: 2024-11-09 02:55:19

一小时写给同组的如何使用工具检测代码质量的相关文章

代码示例:一些简单技巧优化JavaScript编译器工作详解,让你写出高性能运行的更快JavaScript代码

告诉你一些简单的技巧来优化JavaScript编译器工作,从而让你的JavaScript代码运行的更快.尤其是在你游戏中发现帧率下降或是当垃圾回收器有大量的工作要完成的时候. 单一同态: 当你定义了一个两个参数的函数,编译器会接受你的定义,如果函数参数的类型.个数或者返回值的类型改变编译器的工作会变得艰难.通常情况下,单一同态的数据结构和个数相同的参数会让你的程序会更好的工作. function example(a, b) { // 期望a,b都为数值类型 console.log(++a * +

Discuz论坛写出的php加密解密处理类(代码+使用方法)

PHP加密解密也是常有的事,最近在弄相关的东西,发现discuz论坛里的PHP加密解密处理类代码,感觉挺不错,在用的时候,要参考Discuz论坛的passport相关函数,后面我会附上使用方法,先把类代码帖上来: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 <?php /*

自己写的一个自动化测试任务执行工具(模板)

@echo off REM 设置自动执行的最大次数 SET nMaxJobTimes=100 REM 启用变量延迟 setlocal enabledelayedexpansion FOR /L %%i IN (0,1,%nMaxJobTimes%) DO ( cls echo. echo. echo ******************************************** echo. echo 测试任务自动化执行工程 echo 版本:v1.0.0.1 echo. echo ***

【来写个2048吧】—— 游戏结束检测与添加分数

一. 游戏结束检测 //检测游戏是否结束 void GameScene :: doCheck() { bool isGameOver = true ; //判断每一个的上下左右和自己是否相同 for ( int y = 0 ; y < 4; y++) { for ( int x = 0 ; x < 4; x++) { if ( cardArr [x ][ y]-> getNumber () == 0 || ( x< 3 && cardArr[ x ][y ]->

用 C# 写一个 Redis 数据同步小工具

用 C# 写一个 Redis 数据同步小工具 Intro 为了实现 redis 的数据迁移而写的一个小工具,将一个实例中的 redis 数据同步到另外一个实例中.(原本打算找一个已有的工具去做,找了一个 nodejs 的小工具,结果折腾了好久都没装上...于是就自己写了这个小工具) 之所以自己写一个工具而不是利用 redis 备份机制来实现,主要是因为我们用的是 redis 云服务,不能像自己的服务器一样 SSH 上去一顿操作,要把云服务的 redis 数据同步到自己服务器上的 redis 实例

两个小时写了一个加法计算器

第一次进行WPF开发... class Number { private string str_buffer = null; private decimal dec_buffer = 0m; public void plus() { dec_buffer = Convert.ToDecimal(str_buffer); this.Result += dec_buffer; str_buffer = null; dec_buffer = 0m; this.expression += "+"

写单元测试的知识结构(2)——单元测试工具的选用(找个顺手的)

一般的新技术手段的应用分三步(我总结的),问题适配(读书.问人,这时一般处于迷茫状态,尽量避免被煽动被诱惑是很重要的,少讲些主义,多研究问题).选择工具(一般都有现成的,除了你玩创新(也创新不到哪去)或在Google这种老遇见没人碰到过的问题的地方搞新技术),测试可用性,也就是能不能解决问题(有哥们管这叫趟坑)),经过这三部,基本就可以投入应用了. 这篇基本属于选择工具的一个过程,陈述一些对我选用的测试工具的看法,也包括一些想和做怎么结合的看法,有不同看法欢迎大家拍砖.   如果是固定平台,网上

Python写的分析MySQL binlog日志工具

因为MySQL数据库增删改突然暴增,需要查询是那些表的操作特别频繁,写了一个用来分析bin-log的小工具,找出增删改查的表,并按照操作次数降序排列,以下是代码: #for mysql5.5 binlog import os,sys #python binlog.py binglog-0001 '2013-07-01 00:00:00' '2013-07-02 00:00:00' def log_w(type,text):     logfile = "%s.txt" % (type,

以前写的一个下载小说的工具

因为当时发现只有一个站点有.但是时时联网的要求太让人不爽.就写了一个给全下下来了. 用到了: 1. 正则表达式,分析章节和内容: 2. 线程池下载,并且对下载中的相关超时做了一些处理: 3. 文件生成与写入,注意格式问题: 结合下载来说一下使用中的感受: 1. 下载并没有想像的飞一般的速度: 2. 经常会出现错误,章节读取不到,(估计是服务器无法响应): 3. 终于不用一直联网了. *__*