背景
很感激这篇文章的详细介绍,依据这篇文章,我手工走通了一遍,然后就开始调研怎么落地在我们项目。
难点
手工走通这篇文章之后,落实在自动化上,有两个难点:
客户端的*.gcda文件如何生成,并传递出来?
自己写的基于Flask的服务端接收并存储.gcda之后,怎么同步打包过程中的.gcno文件?
由于XcodeCoverage其实是不支持在linux上执行,怎么把服务部署在linux上,并保证可以执行?
如何妥善处理客户端发送*.gcda文件的并发问题,并且,合并生成的测试覆盖率?
解决方案
我在我们项目中已经通过自动化的方式,实现了XcodeCoverage手工覆盖率监测,并开始这个项目的内测。对于接触这篇文章前,最好先通过手工方式走通一遍iOS (Object-C) 非单元测试状态下代码覆盖率获取尝鲜。
我的解决方案分三步:
第一步:解决linux不能执行XcodeCoverage命令问题
第二步:基于Flask搭建了一个服务,用于接收.gcda文件,并请求iOS客户端同学实现了,集成XcodeCoverage进Pods包,然后将.gcda文件发到我写的服务上;
第三步:优化Flask服务,并且将XcodeCoverage等命令实现,通过schedulers后台运行,并优化了执行逻辑。
下面我一一进行简单阐述。
第一步:在linux上运行
部署在linux上调用XcodeCoverage命令,会报错:
Out of memory! Reading tracefile Coverage.info lcov: ERROR: no valid records found in tracefile Coverage.info Reading tracefile Coverage.info lcov: ERROR: no valid records found in tracefile Coverage.info cat: /.xcodecoverageignore: No such file or directory Reading tracefile Coverage.info lcov: ERROR: no valid records found in tracefile Coverage.info Reading data file Coverage.info genhtml: ERROR: no valid records found in tracefile Coverage.info |
直接给出解决方案:
# 修改/envcov.sh为 LCOV() { "${LCOV_PATH}/lcov" "$@" } # 修改/getcov为 "${LCOV_PATH}/genhtml" --ignore-errors source --output-directory . "${LCOV_INFO}" |
简单解释就是执行lcov生成测试覆盖率.info文件的时候稍微有点改变,我还是很佩服XcodeCoverage这个项目的作者,只是改了一点点就支持linux执行。
第二步:接收并处理*.gcda文件
其实这里更多的是依赖客户端同学的配合,他帮我实现了,从手机端生成*.gcda文件以后,并打了个以当时时间戳为名的zip包,然后直接post到我写的服务接口上。
客户端在传递*.zip包同时,在header里面增加了关于这个包的版本号,构件号,userid,和固件号等信息,我在后台解析以后统一存入一个表。
第三步:执行XcodeCoverage等一系列命令
其实接收了*.gcda文件只是万里长征第一步,还需要将在mac slave上打包过程中的临时性文件,*.gcno文件转存到linux上,并且需要修改*.gcno的文件中的路径。这样才能执行XcodeCoverage命令。
在这个过程中,我踩过的坑有:
复制*.gcno文件
我通过scp的方式,先实现linux可以免密登录打包的mac slave,由于我们执行打覆盖率的包是指定slave的,然后只需要将linxu和slave互相信任免密登录,然后再执行完打包之后,通过如下命令:
服务端接收到打包的版本号和构建号以后,同时还存入commid以及commit message等,执行scp命令就很简单了。对了,还需要强调一下,这里打的iOS包必须为Debug包。
更改*.gcno文件内容的路径
需要保证*.gcno文件内的内容路径字符数,和替换后的完全相等,并不需要在linux上建立和slave同样的路径。这里的路径可以从集成到iOS项目工程中Pods/XcodeCoverage/env.sh里面取SRCROOT,意思是如果${SRCROOT}有四位为/opt/,则在linux上执行的时候,需要字符相等的进行替换,替换为linux上存在的路径,为/ttt/。
覆盖率结果的合并
其实XcodeCoverage已经考虑到了覆盖率结果的合并,只需要在执行XcodeCoverage之前,指定XcodeCoverage/env.sh中OBJECT_FILE_DIR_normal和CURRENT_ARCH的值为高一级的目录,比如我想合并时间戳为11.gcda和22.gcda的覆盖率结果,那么我只需要在文件夹33内分别建立两个文件夹11和22,然后将11.gcda放入11中,22.gcda放入22中,然后将*.gcno分别拷入11和22。执行XcodeCoverage命令之前,将XcodeCoverage/env.sh中OBJECT_FILE_DIR_normal替换为33,CURRENT_ARCH替换为/,即可。
最后
还有一些细节,比如什么时候执行scp命令,什么时候执行替换*.gcno内的路径,什么时候执行XcodeCoverage/getcov 命令等。
当然,覆盖率报告并不能衡量app的质量,它只是一个定量化的报告展示。
最后放一张我简单写的展示报告。
我想等我再整理整理,在github上放出我写的很low的代码。
ToDo
git diff和覆盖率结合
将结果不放在自己写的服务中,放入之前搭建的Sonar中
Android覆盖率报告集成到这个服务
继续优化当前的服务
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。