白盒测试 android 静态代码扫描

Tcat · 2016年04月18日 · 最后由 hanbao0126 回复于 2016年04月19日 · 1668 次阅读

开始做这样一个东西是为了帮助开发减少代码方面的问题,提高代码质量,减小以后上线的风险。前面看了 360 的那个静态代码扫描感觉很强大,但目前没这实力去做成这样,希望早日开源,多多学习。所以就先用开源的也能解决下问题。

怎么来的

开始做是想直接使用 sonar 自带的 android 静态代码扫描,但后面发现不是很好用,而且 sonar 对于移动端的扫描能力好像也不是很强。
后面在逛 github 时发现一个项目,就是关于 android 的代码扫描的,觉得思路不错,而且扩展性也不错,就参考了这个项目,传送门

怎么做的

我们项目是用 gradle 进行编译,我用的方法比较 low,每次 jenkins 拉下代码后,直接用自己的 gradle 文件替换项目的文件,然后将配置文件夹 config 直接拷进项目。

  1. 说下 gradle 文件吧,主要是先引用 config/quality.gradle 这个 gradle 文件,主要是添加apply from: '../config/quality.gradle',
  2. quality.gradle这个文件定义了包括 checkstyle,findbugs,pmd,lint 这些扫描工具的任务,因为现在我们项目的 android 代码没有定义规范,所以 checkstyle 就没用,文件内容如下: ``` apply plugin: 'findbugs' apply plugin: 'pmd'

/*

  • Copyright 2015 Vincent Brison. *
  • Licensed under the Apache License, Version 2.0 (the "License");
  • you may not use this file except in compliance with the License.
  • You may obtain a copy of the License at *
  • http://www.apache.org/licenses/LICENSE-2.0 *
  • Unless required by applicable law or agreed to in writing, software
  • distributed under the License is distributed on an "AS IS" BASIS,
  • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  • See the License for the specific language governing permissions and
  • limitations under the License. */

// Add checkstyle, findbugs, pmd and lint to the check task.
check.dependsOn 'findbugs', 'pmd', 'lint'

task findbugs(type: FindBugs, dependsOn: assembleDebug) {
ignoreFailures = true # 注意这里需要设置为 true,否则有失败就会停止,后面的任务就不会跑了
effort = "max"
reportLevel = "low"
excludeFilter = new File("${project.rootDir}/config/quality/findbugs/findbugs-filter.xml")
classes = files("${project.rootDir}/app/build/intermediates/classes")

source 'src'
include '/*.java'
exclude '
/gen/**'

reports {
xml.enabled = true # 因为需要在 jenkins 中集成,所以需要开启 xml
html.enabled = false # 而且 xml 和 html 只能开启一个,注意关掉 html 哦
xml {
destination "$project.buildDir/reports/findbugs/findbugs.xml"
}
html {
destination "$project.buildDir/reports/findbugs/findbugs.html"
}
}

classpath = files()
}

task pmd(type: Pmd) {
ignoreFailures = true # 注意这里需要设置为 true,否则有失败就会停止,后面的任务就不会跑了
ruleSetFiles = files("${project.rootDir}/config/quality/pmd/pmd-ruleset.xml")
ruleSets = []

source 'src'
include '/*.java'
exclude '
/gen/**'

reports {
xml.enabled = false # 同理
html.enabled = true
xml {
destination "$project.buildDir/reports/pmd/pmd.xml"
}
html {
destination "$project.buildDir/reports/pmd/pmd.html"
}
}
}

android {
lintOptions {
abortOnError true
xmlReport false
htmlReport true
lintConfig file("${project.rootDir}/config/quality/lint/lint.xml")
htmlOutput file("$project.buildDir/reports/lint/lint-result.html")
xmlOutput file("$project.buildDir/reports/lint/lint-result.xml")
}
}


### 怎么集成的
1. 下载`gradle`编译的插件,并且在系统管理中配置gradle的路径
2. 下载`findbugs`,`pmd`以及`lint`相应的插件
3. 插件都弄完后,在jenkins中创建任务,指定拉去代码仓库,跑下shell脚本替换指定文件,并且加入config目录
4. 指定gradle的task`clean findbugs pmd lint`
5. 如有需要指定需要什么什么跑
6. 然后再配置各个插件收集结果的xml文件,注意需要设置`Run always`,根据自己的需求进行配置
7. 设置邮件模版,将结果发给指定的开发基本就完成了
![](/photo/2016/ad1da298153d8d8d1a395a71a7d30b7d.png)

### 后续
目前还处在试验阶段,开发对这东西也还不怎么习惯,毕竟以前有些人以前都不会怎么关注代码的一些质量问题,并且相关的问题信息都是英文的...不过基本还是正向的,毕竟以后代码质量优化这块肯定要做的,而且确实代码一些潜在问题可能现在看不出,但这都是隐患。另外有些规则确实也没什么卵用,所以现在需要开发在磨合过程中,逐渐完善扫描规则,让扫描不是一个摆设。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 10 条回复 时间 点赞

我也做过同样的工作,正如最后一句所说的 “成了一个摆设”。
由于在过程中发现的一些问题都是对于代码编写习惯相关的问题,而且这类问题偏多对于筛选真正有问题的错误被埋没在茫茫多多的无效问题中~最后因为自己个人精力有限也就把它放弃了。愿你能坚持下去~~~

Tcat #9 · 2016年04月18日 Author

#1 楼 @junyjiang 对的,其实这个还是要有人去推动这事情,而且还有有效,但代码扫描要保证一定扫出来都是问题是很难的,目前我们开发还是支持这事的,不过开发事情多了就不知道了呵呵

运行和报告都集成到 jenkins 了啊,看着不错。其实比较难的是纠错 + 白名单 + 特批什么的,需要流程上的支持,再加上运行速度的保证和准确性高,前期推广很谨慎,一般是慢慢纠错,搜集样本,不然开发根本不看的。

Tcat #4 · 2016年04月18日 Author

#3 楼 @simple 白名单这块目前是直接通过 xml 文件进行定制了,流程上后期我们计划规则定制好后,在测试打包时会自动跑,如果有严重问题会打回开发的

android 代码就 lint 做下 API 兼容性够了吧。。

Tcat #6 · 2016年04月18日 Author

#5 楼 @lihuazhang 开始也是这样想的,也做过不过发现问题较少,也参考了一些资料,对于 android 其实传统的那些静态工具也是能有效发现问题的,所以都加上后续应该需要完善下规则什么的

代码扫描得 研发参与定规则,自然越权威越好。工具无所谓,关键看规则。
360 那个是公司内几个大牛门一起制定的。算是比较权威。

Tcat #8 · 2016年04月18日 Author

#7 楼 @zhangzhao_lenovo 是的,所以目前我们要开发在报告中去确认哪些规则是有效的,哪些确实是问题,然后我们这边再进行定制化,不过因水平有限也只能做到这样了

#5 楼 @lihuazhang lint 主要是 Android 方面的,Java 层面的 还需要其他的配合

—— 来自 TesterHome 官方 安卓客户端

你们难道不觉得误报率太高吗?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册