iOS 测试 [腾讯 TMQ] iOS 静态代码扫描之工具调研

匿名 · 2017年08月18日 · 1097 次阅读

为了进一步加强测试质量,同时探索测试左移在同步中的实践,iOS 同步助手尝试接入静态代码扫描工具。希望通过不同的途径提前发现日常测试中难发现的问题。

然而 iOS 静态代码扫描工具有不少,它们都有什么不同?我应该选哪一个?因此,本文主要针对主流的几个工具,对同步助手的代码进行扫描,并分析对比它们的扫描结果,再敲定后续的接入计划。

该文章从以下几部分进行阐述,可按需阅读:

一、工具介绍

二、遇到的坑点

三、扫描能力对比

*四、部分结果分析 *

一、工具介绍

本次选取了四个主流的扫描工具: coverity、infer、clang、oclint。

1、coverity

Coverity 是检测和解决 C、C++、Java 和 C# 源代码中最严重的缺陷的领先的自动化方法。它将基于布尔可满足性验证技术应用于源代码分析引擎,分析引擎利用其专利的软件 DNA 图谱技术和 meta-compilation 技术,综合分析源代码、编译构建系统和操作系统等可能使软件产生的缺陷。

2、clang

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)可以看到生成报告在指定目录下

3、infer

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

二、遇到的坑点

1、缺少证书问题

Build 代码的时候可能会遇到缺少了部分证书的问题,因此命令行调用时使用了 developer 模式,可忽略部分证书问题;

2、xcpretty 安装

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

3、infer 增量分析

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、缺陷类

(1)无法执行到的代码

(2)if 和 else 分支的代码一样

(3)废弃代码

已经走到 return,后面的代码不会再执行:

2、误报类

(1)复制粘贴错误

代码中存在"com.xxx.unname",没有问题;

(2)switch 中缺少 break

开发故意设计如此,没有问题:

(3)没有判断是否为空

提示 844 行传传入的 actionButton 可能为空,但实际前面已赋值,且排查没有问题:

(4)未使用的值

提示 cacheSuccess 不会被使用,实际是在打印日志时使用了,而扫描时日志为关闭状态,没有走到下面的路径:

关注微信公众号:腾讯移动品质中心 TMQ,获取更多测试干货!

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