为了进一步加强测试质量,同时探索测试左移在同步中的实践,iOS 同步助手尝试接入静态代码扫描工具。希望通过不同的途径提前发现日常测试中难发现的问题。
然而 iOS 静态代码扫描工具有不少,它们都有什么不同?我应该选哪一个?因此,本文主要针对主流的几个工具,对同步助手的代码进行扫描,并分析对比它们的扫描结果,再敲定后续的接入计划。
该文章从以下几部分进行阐述,可按需阅读:
一、工具介绍
二、遇到的坑点
三、扫描能力对比
*四、部分结果分析 *
本次选取了四个主流的扫描工具: coverity、infer、clang、oclint。
Coverity 是检测和解决 C、C++、Java 和 C# 源代码中最严重的缺陷的领先的自动化方法。它将基于布尔可满足性验证技术应用于源代码分析引擎,分析引擎利用其专利的软件 DNA 图谱技术和 meta-compilation 技术,综合分析源代码、编译构建系统和操作系统等可能使软件产生的缺陷。
Clang 作为 LLVM 编译器框架的前端,最主要的任务是词法分析、语法分析,中间代码生成。源代码通过 clang 语法分析后,生成了语法分析树 (AST) 后,可作为静态分析工具对 AST 进行分析。
Clang 命令行调用方法:
(1)下载 clang:http://clang-analyzer.llvm.org/
(2)命令行 cd 到项目代码所在目录:$ cd /path
(3)使用 clang 扫描,命令开头为 clang 的 scan-build 所在目录:$
/Users/kylinhuang/Documents/tools/analyzer/bin/scan-build -vxcodebuild
-target QQPimPro -configuration Developer
(4)可以看到生成报告在指定目录下
Infer 是 Facebook 开源的用来执行增量分析的一款静态分析工具,由 OCaml 语言编写的 infer 目前能检测出空指针访问、资源泄露以及内存泄露,可对 C、Java 和 Objective-C 代码进行检测。
Infer 命令行调用方法:
(1)前置条件
安装 python 2.7:MAC 自带;
安装 opam:$ brew install opam;
安装 xcode;
(2)下载 infer:https://github.com/facebook/infer
(3)安装 ocaml
$opam init --comp=4.01.0
$eval opam config env
$opam install sawja.1.5 atdgen.1.5.0 javalib.2.3 extlib.1.5.4
(4)将 infer 的执行目录配置到环境变量
命令行 cd 到 infer 所在目录:$ cd /infer-master
$echo "export PATH=\"\$PATH:pwd
/infer-master/infer/bin\""\ >> ~/.bash_profile && source ~/.bash_profile
(5) 验证是否安装成功:$ infer -version
(6)使用 infer 扫描
命令行 cd 到项目代码所在目录:$ cd /path
infer-- xcodebuild -target QQPimPro -configuration Developer
(7)项目代码所在目录下生成结果文件夹 infer-out:report.csv、report.json
4、oclint
Oclint 是针对 C、C++ 和 Objective C 代码的静态扫描分析工具,可以和 xcode、xcodebuild、xctool 等集成,使用命令行方式生成分析报告。这里主要使用 oclint 对 xcodebuild 产生的 log 进行分析,获取相关数据以后生成 html 文件。
Oclint 命令行调用方法:
(1)下载 oclint:https://github.com/oclint/oclint/releases
(2)配置环境变量,将 oclint 的 bin 目录添加到/etc/bashrc 文件中:exportPATH=$PATH:/Users/kylinhuang/Documents/tools/oclint-0.11.1/bin
(3)验证是否安装成功:$ oclint
(4)命令行 cd 到项目代码所在目录:$ cd /path
(5)进行 xcodebuild clean:$ xcodebuild clean
(6)xcodebuild 与 oclint 结合,将 xcodebuild analyze 的输出信息记录在 xcodebuild.log 中,并使用 xcpretty 生成 json 文件:
$xcodebuild analyze | tee xcodebuild.log | xcpretty --reportjson-compilation-database
(7)xcpretty 生成的 json 文件在/代码目录/build/reports 下,名字为 compilation_db.json,和 oclint 默认生成的文件命名和路径均不同,因此需要移至代码根目录并重命名为 compile_commands.json。
(8)生成 html 文件
$oclint-json-compilation-database -- -o=report.html
Build 代码的时候可能会遇到缺少了部分证书的问题,因此命令行调用时使用了 developer 模式,可忽略部分证书问题;
Infer 在扫描过程中提示出错,需要安装 xcpretty。但由于公司网络问题,按照网上教程使用 gem install xcpretty 安装时会出错。这里可以采用离线安装的方法:下载 xcpretty.gem 文件,并下载对应依赖版本的 rouge.gem 文件,离线文件下载地址:https://rubygems.org/
命令行打开离线文件所在目录:$ cd/Users/kylinhuang/Documents/tools
安装 rouge.gem:$ sudo gem install rouge-1.8.0.gem
安装 xcpretty.gem:$ sudo gem install --local xcpretty-0.2.4.gem
查看 xcpretty.gem 是否安装成功:$ xcpretty –v
Infer 为增量分析工具,通常默认只有修改过并提交编译的文件才会被 infer 分析。如果想要全量分析,可以调用前先清除扫描记录:
$ rm -rf /tmp/scan-build
$ rm -rf build
4、oclint:Skipping [path] Compile command notfound
使用 oclint 执行最后一步生成.html 文件时出现该错误,最后排查到是开始没有 clean xcodebuild,因此在进行扫描之前先执行这一步。
在未加任何过滤规则的情况下,四个工具对同一份代码进行扫描,并于开发童鞋一起对扫描结果进行了初步筛选和整理:
(1)准确率:coverity > infer >clang > oclint;
(2)coverity 扫描维度更多、发现问题更精准;infer、clang 能发现部分 coverity 未发现的问题,但误报率较高,可作为补充扫描;
(3)infer 发现的大部分问题为第三方库问题,后续加入过滤计划可提高扫描准确率;
(4)oclint 扫描出的问题数量最多,但大多是开发不关注的问题,可过滤特定结果类型关注,更适合作为扫描代码复杂度的工具。
(1)无法执行到的代码
(2)if 和 else 分支的代码一样
(3)废弃代码
已经走到 return,后面的代码不会再执行:
(1)复制粘贴错误
代码中存在"com.xxx.unname",没有问题;
(2)switch 中缺少 break
开发故意设计如此,没有问题:
(3)没有判断是否为空
提示 844 行传传入的 actionButton 可能为空,但实际前面已赋值,且排查没有问题:
(4)未使用的值
提示 cacheSuccess 不会被使用,实际是在打印日志时使用了,而扫描时日志为关闭状态,没有走到下面的路径:
关注微信公众号:腾讯移动品质中心 TMQ,获取更多测试干货!