作者:京东零售吴滔
本教程将运用北汽登录模块为例,一步一步和咱们一起树立单元测验用例,并在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的版别信息共同