在Bamboo上怎么使用iOS的单元测试
作者:京东零售 吴滔
本教程将使用北汽登录模块为例,一步一步和大家一起搭建单元测试用例,并在Bamboo上跑起来,最终测试结果和代码覆盖率会Bamboo上汇总。
模块名称:BQLoginModule,是通过iBiu创建的一个模块工程
一 建立单元测试Bundle
ProductName: BQLoginTests
二 测试代码编写
1 配置文件同步
如果我们要在测试代码使用我们在Pod里的类,需要同步 Targets Support Files/Pods-BQLoginTests/Pods-BQLoginTests.debug.xcconfig 文件的内容到 Targets Support Files/Pods-BQLoginUITests/Pods-BQLoginUITests.debug.xcconfig,直接内容copy就成了,只是每次用iBiu安装过后都要做这个操作,后续使用脚本实现同步:
2 测试代码编写
具体的编写我这里就过多介绍了,网上教程一大篇,这里就不多说了,如果没有做性能测试,这里可以把自动生成的 testPerformanceExample 屏蔽掉。
三 运行单元测试
用 command+u,或者菜单(product->test)执行,就能获得结果
结果在这里看:
完成以上操作,基本的单元测试就OK了
下面我们用命令行来跑下单元测试,首先进入工程目录:
cd BQLoginModule/Example
执行如下命令:
xcodebuild test -UseModernBuildSystem=NO -configuration=Debug -workspace './BQLoginModule.xcworkspace' -scheme "BQLoginModule_Example" -destination 'platform=iOS Simulator,name=iPhone 8,OS=13.2.2'
请大家注意将 workspace/scheme /模拟器信息 修改为自己工程对应信息,就可以看到结果
四 代码覆盖率
1 单元覆盖率
在XCode打开覆盖率统计,我们只打开我们的库做代码覆盖就成了,Xcode 12.4在如下地方:
在Pod里面BQLoginModule设置 BuildSettings 查找 "cov" ,把 以下2项都设置为YES;
然后我们跑下单元测试,就可以看到覆盖率结果了:
2 Bamboo报告
因为我们需要在Bamboo上汇总覆盖率报告,这里我们使用iBiu的一个高级特性:用 Podfile.custom 文件加载通用cocoapods的外网库来使用,具体见图:
这里我们引入2个库: OCMock(单元测试必备的Mock库) XcodeCoverage(覆盖率统计的库)
加入这个文件后,需要使用 iBou重新安装下组件
做如下设置:
这个命令主要是生成XcodeCoverage的环境依赖 env.sh 我们打开文件看下,文件路径如下
env.sh内容如下:
这里 OBJECT_FILE_DIR_normal 和 SRCROOT指向的是我们Example工程,我们是需要对Pods里的BQLoginModule里的代码做单元覆盖,这2个环境变量修改如下:
export OBJECT_FILE_DIR_normal ="/Users/cdwutao3/Library/Developer/Xcode/DerivedData/BQLoginModule-fvrzeicgcswucwfgjqweugauzxia/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/BQLoginModule.build/Objects-normal"
export SRCROOT="/Users/cdwutao3/Desktop/ut/BQLoginModule/BQLoginModule/Classes"
然后在Pods/XcodeCoverage目录新建 xmlout目录,并运行命令:
./getcov -x -s -o xmlout
可以得到如下结果:
还可以查看哪些代码没被覆盖,和Bamboo结果对齐:
完成以上步骤,就完成了本地用命令号完成单元测试的所有步骤,下面我们接着来看要在Bamboo上输出报告需要怎么做。
五 Bamboo操作
1 创建应用
这里要确保对应库和依赖的库 ,给 xn_testdev_ci账号开权限
2 新建流水线
选择 “从零开始创建”
3 配置流水线
基础信息里面的选择如下
需要用到以下四个原子:
“下载代码”--大家可先配置使用“下载代码-iBiu”这个原子,我用这个一直使用不成功,所以直接用“下载代码”来手动配置:
“自定义脚本”--因为现在iOS的单元测试还没有对应的原子操作,所有我们通过自己写脚本来完成:
“单元测试”--你没看错,就是用java的单元测试原子,我们输出的结果和这个原子匹配,所以选他就成了
“GCC代码覆盖率”
其中“单元测试”和“代码覆盖率”的路径是可以修改的,这个可以根据自己的实际路径修改
4 自定义脚本
说明:
1 下载代码和配置iBiu都是自己的命令行来做的,但是需要开始配置下git用户信息
2 开始我用命令行写全部命令,但是Bamboo的命令行规则会导致一些的shell指令的失效,所以我采用把 shell命令 写到文件上传到git仓库,然后执行的方式来完成
3 结果转换会还会用到 ocunit2junit 和 xcpretty 这2个命令,如果这2个命令出错,请联系Bamboo同事协助安装下
4 大家在写shell命令时,不知道文件是否生成,可以多用 ls 来看目录下的文件
5 重点:
- 为了手动安装iBiu配置,请将本机 ~/Library/Application Support/iBiu/BQLoginModule/下的2个文件 spec_sources 和 pod_setup 上传到git,我是copy到 Example/BQLoginModule/Resource目录下然后上传到git仓库,这个目录可以修改,然后修改对应shell 命令的目录就成了
- iBiu建的git仓库默认会过滤一些内容,修改 BQLoginModule 工程目录下的 .gitignore 文件,需要上传xcworkspacedata内容
- 代码覆盖率设置,XcodeCoverage的说明强调了不要用于AppStore的工程,为了避免线上事故,我们通过命令来设置,不直接在工程里设置:
所以修改xcode的构建命令新加 GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES,命令如下:
xcodebuild -UseModernBuildSystem=NO -enableCodeCoverage=YES -configuration=Debug GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES -workspace "./${moduleName}.xcworkspace" -scheme "${moduleName}_Example" -destination 'platform=iOS Simulator,name=iPhone 8,OS=13.2.2' test
5 Bamboo结果
覆盖率下载地址:
六 脚本汇集
1 本地脚本
以BQLoginModule为例,最终本地脚本命令如下,大家可以重新找到本地目录执行查看效果:
git clone --depth=1 https://git.jd.com/BQMobileshop/BQLoginModule.git
cd BQLoginModule/Example
pod update
pwd
moduleName="BQLoginModule"
testName="BQLoginTests"
biu -pod install ./
ls
ls ./Pods
rm -f "./Pods/Target Support Files/Pods-${testName}/Pods-${testName}.debug.xcconfig"
cp -f "./Pods/Target Support Files/Pods-${moduleName}_Example/Pods-${moduleName}_Example.debug.xcconfig" "./Pods/Target Support Files/Pods-${testName}/Pods-${testName}.debug.xcconfig"
cat "./Pods/Target Support Files/Pods-${testName}/Pods-${testName}.debug.xcconfig"
xcodebuild clean -workspace "./${moduleName}.xcworkspace" -scheme "${moduleName}_Example"
xcodebuild -UseModernBuildSystem=NO -enableCodeCoverage=YES -configuration=Debug GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES -workspace "./${moduleName}.xcworkspace" -scheme "${moduleName}_Example" -destination 'platform=iOS Simulator,name=iPhone 8,OS=13.2.2' test > utlogfile.txt
cat utlogfile.txt |grep ".xcresult" > utlogpath.txt
logStr=$(cat ./utlogpath.txt)
logPath=${logStr:1}
if [ -z "$logPath" ]; then
exit 1
fi
sed "s/${moduleName}.build\/Debug-iphonesimulator\/${moduleName}_Example.build/Pods.build\/Debug-iphonesimulator\/${moduleName}.build/g" ./Pods/XcodeCoverage/env.sh> cov_env1.txt
sed "s/${moduleName}\/Example/${moduleName}\/${moduleName}\/Classes/g" ./cov_env1.txt > cov_env2.txt
cp -f ./Pods/XcodeCoverage/env.sh ./Pods/XcodeCoverage/env_bak.sh
rm -f ./Pods/XcodeCoverage/env.sh
cp ./cov_env2.txt ./Pods/XcodeCoverage/env.sh
cat "./utlogfile.txt"|ocunit2junit
ls test-reports
cp ./cov_env2.txt ./Pods/XcodeCoverage/env.sh
mkdir xmlout
./Pods/XcodeCoverage/getcov -x -o xmlout
ls ./xmlout/lcov
cat "./utlogfile.txt"|xcpretty -t -r html --output testresult/testresult.html
ls te
2 Bamboo脚本
Bamboo脚本分成2部分,一个是在Bamboo上执行的脚本
rm -fr "/Users/admin/Library/Application Support/iBiu/BQLoginModule"
mkdir "/Users/admin/Library/Application Support/iBiu/BQLoginModule"
rm -fr ./BQLoginModule
git clone --depth=1 https://git.jd.com/BQMobileshop/BQLoginModule.git
cd BQLoginModule/Example
cp "./BQLoginModule/Resource/spec_sources" "/Users/admin/Library/Application Support/iBiu/BQLoginModule"
cp "./BQLoginModule/Resource/pod_setup" "/Users/admin/Library/Application Support/iBiu/BQLoginModule"
ls "/Users/admin/Library/Application Support/iBiu/BQLoginModule"
biu -pod install ./
sh UT.sh
脚本剩下部分写入 UT.sh,放在BQLoginModule/Example目录下, 然后上传到git仓库来执行,大家做的时候注意修改变量名称:
pwd
moduleName="BQLoginModule"
testName="BQLoginTests"
ls ./Pods
rm -f "./Pods/Target Support Files/Pods-${testName}/Pods-${testName}.debug.xcconfig"
cp -f "./Pods/Target Support Files/Pods-${moduleName}_Example/Pods-${moduleName}_Example.debug.xcconfig" "./Pods/Target Support Files/Pods-${testName}/Pods-${testName}.debug.xcconfig"
cat "./Pods/Target Support Files/Pods-${testName}/Pods-${testName}.debug.xcconfig"
xcodebuild clean -workspace "./${moduleName}.xcworkspace" -scheme "${moduleName}_Example"
xcodebuild -UseModernBuildSystem=NO -enableCodeCoverage=YES -configuration=Debug GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES -workspace "./${moduleName}.xcworkspace" -scheme "${moduleName}_Example" -destination 'platform=iOS Simulator,name=iPhone 8,OS=13.2.2' test > utlogfile.txt
cat utlogfile.txt |grep ".xcresult" > utlogpath.txt
logStr=$(cat ./utlogpath.txt)
logPath=${logStr:1}
if [ -z "$logPath" ]; then
exit 1
fi
sed "s/${moduleName}.build\/Debug-iphonesimulator\/${moduleName}_Example.build/Pods.build\/Debug-iphonesimulator\/${moduleName}.build/g" ./Pods/XcodeCoverage/env.sh> cov_env1.txt
sed "s/${moduleName}\/Example/${moduleName}\/${moduleName}\/Classes/g" ./cov_env1.txt > cov_env2.txt
cp -f ./Pods/XcodeCoverage/env.sh ./Pods/XcodeCoverage/env_bak.sh
rm -f ./Pods/XcodeCoverage/env.sh
cp ./cov_env2.txt ./Pods/XcodeCoverage/env.sh
cat "./utlogfile.txt"|ocunit2junit
ls test-reports
cp ./cov_env2.txt ./Pods/XcodeCoverage/env.sh
mkdir xmlout
./Pods/XcodeCoverage/getcov -x -o xmlout
ls ./xmlout/lcov
cat "./utlogfile.txt"|xcpretty -t -r html --output testresult/testresult.html
ls test
七 错误速查
这里汇集了在写脚本时的一些错误,方便大家查看
1 不能在测试工程引用自己的代码
请参看 二--1 ”配置文件同步“ 解决
2 在Bamboo上的Pods文件夹,没有拉到iBiu的其他配置信息
请参看 五--4 ”自定义脚本“的重点 1 来解决
3 “No coverage data in result bundle”
请参看 五--4 ”自定义脚本”的重点 2 来解决
4 使用命令行跑单元测试时,一直提示不能找到模拟器
-destination 'platform=iOS Simulator,name=iPhone 8,OS=13.2.2' 改为 -destination 'id=xxxxxxxxxx' 这种格式,id为屏幕提示
5 Bamboo Shell里提示 “未设置原子执行条件”
因为Bamboo的Shell对字符拼接,变量的处理有限制,所以一部分shell命令最好放在文件执行
6 在本地测试时,Pods/XXXXModule的设置项在每次iBiu安装后都会重置
请注意手动修改,或者直接使用脚本运行
7 在本地测试时,代码覆盖率只包含了一部分源码文件,不是全部
请清空 ~/Library/Developer/Xcode/DerivedData 目录再测试一次
8 在Bamboo上发现有些库拉不下来
请确保 对应 库给xn_testdev_ci开了权限
9 覆盖率文件生成不了
请确保XXXTests的版本信息和主工程的XXXXModule_Example的版本信息一致
在Bamboo上怎么使用iOS的单元测试的更多相关文章
- 实现多文件上传在iOS开发中
该功能实现了实现多文件上传在iOS开发中,喜欢的朋友可以研究一下吧. NSURL* url = [NSURL URLWithString:@"xxx"]; ASIFormDataR ...
- mac上搭建appium+IOS自动化测试环境(一)
阅读须知 由于OS X系统最近才开始接触,所以有些东西也不是很清楚,这里只提供方法不提供原理,能解释清楚的我也会尽量解释.可能也有一些地方说的不严谨或有错的,还望大家指点一二. 实验环境 操作系统: ...
- 了解iOS消息推送一文就够:史上最全iOS Push技术详解
本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表. 1.引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ.微信等IM界面处于前台时,聊天消息和指 ...
- 在VS2017上对C++项目进行单元测试
操作系统:win10 VS2017安装:http://www.cnblogs.com/Metak/p/7471671.html 参考博客: http://blog.csdn.net/lovehaiho ...
- mac上搭建appium+IOS自动化测试环境(二)
上一篇: mac上搭建appium+IOS自动化测试环境(一) 9.安装appium-xcuitest-driver依赖 进入WebDriverAgent安装目录,运行bootstrap 首先进入目录 ...
- 【iOS】单元测试
iOS单元测试(作用及入门提升) 字数1704 阅读16369 评论26 喜欢247 由于只是一些简单实用的东西,学学还是挺不错的.其实单元测试用的好,开发起来也会快很多.单元测试对于我目前来说,就是 ...
- iOS - UnitTests 单元测试
1.UnitTests 在计算机编程中,单元测试(又称为模块测试, Unit Testing)是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作.程序单元是应用的最小可测试部件.在过程化编 ...
- iOS 初步单元测试
- (void)testExample { // This is an example of a functional test case. // Use XCTAssert and related ...
- iOS 开发-单元测试
前言 维基百科对单元测试的定义如下: 在计算机编程中,单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作.程序单元是应用的最小可 ...
- 从此走上一条iOS程序猿不归路。。。
新的城市,新的生活!前不久刚刚结束了苦逼的面试找工作之旅,期间也小有收货,如今正处年底工作闲暇之余,将前一阵子陆陆续续的总结整理了一下,本人菜鸟程序猿一只,水平有限,本文总结的知识不算深入,比较浅显, ...
随机推荐
- 使用Python+Appium+夜神模拟器,并连接uiautomatorviewer
本文不介绍安装步骤,实在是太多博文了 一.安装 Python:3.8 Appium:1.22.3 夜神模拟器 node JDK1.8 SDK 二.成功连接模拟器 PytCharm代码如下: # cod ...
- Vue3中,如何获取在for循环中设置的ref对象
思考: for循环中,如果给每一个元素绑定一个特定的ref值(ref="xxx"),那么就要定义N多个变量来分别接受它们,显然不现实. 通过改变ref的绑定方式(:ref=&quo ...
- 01-第一个Spring程序
1.导包 所有和spring有关的包(有mybatis包的忽略),后期会使用maven引入 2. 引入spring的配置文件 可命名为applicationContext-service.xml或sp ...
- adb 全局
win10: 我的电脑-右键属性--系统保护--高级--环境变量--选择path--编辑--点击新建 在新建条目下输入 C:\Users\GL\platform-tool--重新打开cmd 测试adb ...
- 【新版】使用 go-cqhttp 扫码登录,一键接入 ChatGPT 机器人到 QQ 群
目录 项目效果 安装 go-cqhttp 虚拟文件 启动 ChatGPT 项目效果 由于 ChatGPT 目前只能在漂亮国使用,所以想要在国内使用 ChatGPT 必然险阻重重 不仅时时刻刻要跟企鹅公 ...
- 什么是RPA?RPA能干什么?
一.什么是RPA什么是RPA? RPA的全称为机器人流程自动化(Robotic Process Automation),即:"机器人流程自动化",是一种智能化的企业流程管理系统.R ...
- Javaweb学习笔记第八弹
继续MyBatis学习 SQL语句警告提示问题 产生原因:IDEA和数据库没有建立连接,不识别表的信息 解决方式:在IDEA中配置MySQL数据库连接 在IDEA的Maven项目中,如果想要直接通过I ...
- python安装robotframework的一些常见的错误
python安装robotframework的一些常见的错误 首先的电脑环境是x86的,然后下载的python版本起初是3.10.1的 在cmd 中出入pip install robotframwor ...
- 针对im输入框的一种处理方式
针对im输入框的一种处理方式 <template> <div class="chatInput"> <!-- 通过contenteditable使普通 ...
- 5.Web信息收集
Web信息收集 目录 Web信息收集 1.whois查询 2.服务器操作系统的识别 3.服务器加固 4.服务版本识别 5.常见组合: 6.指纹识别 7.敏感路径识别 8.历史漏洞信息收集 1.whoi ...