您现在的位置是:知识 >>正文
静态代码测试
知识3374人已围观
简介上周帮同事查一个线上崩溃,日志里堆栈指向一行看起来毫无问题的赋值语句。折腾半天才发现,是某个分支里变量没初始化,编译器没报错,运行时才炸。这种事静态代码测试本来能拦住——如果项目里真配了的话。 静态代 ...
上周帮同事查一个线上崩溃,静态日志里堆栈指向一行看起来毫无问题的代码赋值语句。折腾半天才发现,测试是静态某个分支里变量没初始化,编译器没报错,代码运行时才炸。测试这种事静态代码测试本来能拦住——如果项目里真配了的静态话。
静态代码测试,代码说白了就是测试不跑代码,只靠分析源码找毛病。静态跟单元测试、代码集成测试那种“跑起来看结果”的测试路子完全不同。它像审稿编辑,静态逐行读你的代码文字,挑语法、测试逻辑、风格上的刺,但不会把稿子拿去印刷。
它到底在查什么
最常见的几类问题:空指针解引用、资源未释放、数组越界、死循环、未使用变量、重复代码块。有些工具还能查安全漏洞,比如SQL注入点、硬编码密码。SonarQube、Coverity、ESLint、Pylint这些名字,做开发的多多少少都见过。
拿ESLint举例。写JavaScript时,如果声明了变量却从没用到,它会标黄。这看起来是小事,但代码库里积累几百个未使用变量,新人接手时根本分不清哪些是废弃逻辑、哪些是预留接口。我见过一个项目,光未使用导入就清理出两百多行,删完之后构建速度都快了一截。
为什么很多人不跑
误报率高是头号劝退理由。Coverity在C++项目里经常把某些模板元编程判成问题,开发者点开一看,纯属工具理解不了。几次下来,大家就学会了一键忽略。另一个原因是集成成本——老项目接静态扫描,第一次跑能出几千条告警,修不完,干脆不修。
但这里有个取舍。我自己的习惯是:新项目从第一天就配好规则,只开最基础的几项,比如空指针和资源泄漏。老项目则用增量模式,只扫描改动的文件。这样告警量可控,修起来不痛苦。全量扫描留给 nightly build,当报表看,不当门禁。
一个具体案例
去年重构一个订单服务,用SonarQube扫出某段循环里反复调用size()方法。代码本身没错,但集合在循环体内没被修改,每次迭代都重新计算长度纯属浪费。改成局部变量后,那个接口的P99延迟降了8毫秒。这种问题人眼很难注意到,静态分析器却一抓一个准。
还有一次更悬。某个工具报出“可能的空指针解引用”,位置在一个异常分支里。那段代码三年没改过,也没出过事。但顺着逻辑推下去,确实存在一条极端路径能让变量为null。后来加了防御性判断,半年后真收到一条相关告警,证明那个分支被触发了。
怎么用才不烦人
规则集要裁剪。别一上来就开“所有严格模式”,那等于给自己找罪受。先选十到十五条最要命的规则,跑两周,看误报率。高于30%的规则直接关掉,等工具升级或项目结构改善再说。
跟CI/CD的集成也有讲究。我倾向于把静态扫描放在构建之后、部署之前,但只对新增代码做阻断。历史遗留问题记入技术债看板,排期慢慢还。这样既不会卡住日常发布,又能防止新代码引入新债。
工具选择上,多语言项目可以试试SonarQube全家桶,单语言项目用专用工具更利索。Python用Pylint加mypy,Java用SpotBugs,Go用staticcheck。别指望一个工具通吃,组合使用效果更好。
静态代码测试不是银弹。它查不出业务逻辑错误,也替代不了代码审查。但把它当成一道低成本过滤网,在代码合入前拦下那些低级又致命的毛病,这笔时间投资回报率相当高。至少,别再让未初始化变量溜到线上了。
Tags:
相关文章
黑黑乳广告
知识《黑黑乳》广告在电视上蹦出来的时候,我正端着泡面,准备熬一个加班的夜。画面里,一个穿着深色西装的男演员,把一罐黑乎乎的饮料举到镜头前,嘴角挂着一丝“你懂我”的笑。他说:“黑黑乳,给肠胃放个假。” 这句 ...
【知识】
阅读更多渗透测试的流程是怎么样的
知识```html 客户打电话来的时候,语气很急。说他们的后台管理页面被一个实习生用默认密码就登进去了。我问他,你们上次做渗透测试是什么时候。他愣了一下,说没做过,一直觉得系统挺安全的。 这种事我见得太多 ...
【知识】
阅读更多clipdrop根本用不了
知识昨天下午三点,我打开Clipdrop想抠一张产品图。上传,转圈,然后弹出一行红字:“处理失败,请重试。”我重试了七次。七次。最后我用手机自带的抠图功能,三秒钟搞定。 这不是我第一次被Clipdrop惹 ...
【知识】
阅读更多