Gitlab CI中Swift 3.0项目的代码覆盖率

Svy*_*lav 10 cocoapods xcode-workspace gitlab-ci swift

我有一个由Swift 3.0和CocoaPods编写的iOS项目.我为这个项目配置了Gitlab CI,它运行得很好.这是我的.gitlab-ci.yml文件:

stages:
- build
build_project:
  stage: build
  script:
  - rm -rf Pods;rm -rf MyProject.xcworkspace;rm -rf MyProject.xcodeproj/project.xcworkspace
  - pod install
  - xcodebuild clean -workspace MyProject.xcworkspace -scheme MyProject | xcpretty
  - xcodebuild test -workspace MyProject.xcworkspace -scheme MyProject -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.2' | xcpretty -s
tags:
- ios
- lunchdot
Run Code Online (Sandbox Code Playgroud)

我在Gitlab repo中看不到这个项目的代码覆盖率.目前,我所有构建的覆盖列都是空的.我试图在CI/CD Pipelines Gitlab设置中设置测试覆盖率解析,但它没有任何效果,因为我不知道Swift的正则表达式.是否可以在Gitlab CI中为Swift项目设置代码覆盖率?我怎样才能做到这一点?

Did*_*ido 9

所以,我尝试了一百万种方法来实现这个问题,结果证明是xcpretty.删除后,我开始使用gitlab ci覆盖数据获得一致的结果.如果您仍然不想获得大量数据而不关心,可以在gitlab yams文件中使用-quiet.我会发布所有内容,所以请继续阅读.

我们仍然需要进行覆盖分析外部工具- xcov似乎让我用不再提供涂满.工作就像一个魅力.

这些是步骤:

1)得到诽谤.

2)让你的.slather.yml文件理顺.我看起来如下(YourApp显然是你的应用程序的名称):

# .slather.yml

coverage_service: cobertura_xml
xcodeproj: ./YourApp.xcodeproj
workspace: ./YourApp.xcworkspace
scheme: YourApp
source_directory: ./YourApp
output_directory: path/to/xml_report
ignore:
- "**/Pods/*"
- "thirdparty/*"
- "./Scripts/*"
- "**/3rdParty/*"
- "../**/Developer/*"
- "**/libraries/*"
- "Module-Core/*"
- "Module-Components/*"
- "**/AppUnitTests/*"
Run Code Online (Sandbox Code Playgroud)

您可以在codecov.io等中获得html,xml的测试输出,完全取决于您.查看slave GitHub页面,了解可能的方法.但是对于当前的问题,我们所需要的只是在命令行中进行报告,因此gitlab可以接收它.这是正确设置gitlab yaml文件的地方.

3)设置.gitlab-ci.yml文件.我看起来像这样:

stages:
  - build

build_project_1:
  stage: build
  script:
    - xcodebuild clean -workspace YourApp.xcworkspace -scheme YourApp -quiet
    - xcodebuild test -workspace YourApp.xcworkspace -scheme YourApp -destination 'platform=iOS Simulator,name=iPhone 6,OS=10.3.1' -enableCodeCoverage YES -quiet
  after_script:
    - slather coverage -s

  only:
    - master
Run Code Online (Sandbox Code Playgroud)

4)下一步是:

  • 转到你的gitlab页面/个人资料或你称之为的任何内容

  • 转到"设置",然后转到" 管道"

设置/管道

  • 向下滚动到测试覆盖率解析并在此处添加此正则表达式:\d+\%\s*$

在提供的空白处添加正则表达式,然后保存它

就是这样.您需要做的就是调用构建.

  • 文本中的正则表达式不正确,使用图片中的正则表达式或```\d+(?:\.\d*)?\%$``` (2认同)

Nik*_*iev 8

由于的Xcode 9.3苹果提供xccov,所以这里使用了一个解决方案,即不依赖于第三方的依赖关系(和不关心,如果你使用xcpretty-quiet等等)

xccovreport和的概述xccov

当您的Scheme启用了测试覆盖率时(或当您传递-enableCodeCoverage YES到时xcodebuild),将.xccovreport创建一个文件。它包含您可以在Xcode UI中看到的覆盖率百分比。

该文件位于:

(对于Xcode 9)
/Users/somename/Library/Developer/Xcode/DerivedData/MyApp-airjvkmhmywlmehdusimolqklzri/Logs/Test/E387E6E7-0AE8-4424-AFBA-EF9FX71A7E46.xccovreport

(对于Xcode 10)
/Users/somename/Library/Developer/Xcode/DerivedData/MyApp-airjvkmhmywlmehdusimolqklzri/Logs/Test/Test-MyApp-2018.10.12_20-13-43-+0100.xcresult/action.xccovreport

(除非您xcodebuild通过来指定其他文件夹-derivedDataPath

注意:在Xcode 10中,.xccovreport测试完成后,文件位置会在控制台中打印出来,但是Xcode 9不会这样做。无论如何,依靠它可能不是一个好主意,因为它可能会被静音(例如通过xcpretty

该文件不是纯文本,要查看它,您必须调用: xcrun xccov view <path_to_xccovreport_file>

它将输出报告。(您可以通过--jsonJSON报告)

我们需要做的

我们希望能够解析文件并打印出总百分比(以便GitLab可以选择它并在仪表板中使用它)。

There are a couple of challenges:
- Firstly we need to find out the file path of the xccovreport which contains random strings (in two places)
- Then we need to parse the file (using some regular expressions) and extract the total percentage.

The script

Here's what I am using (any improvement suggestions welcome, as I am not a bash expert):

#!/bin/bash

#1

# Xcode 10
TEST_LOGS_DIR=`xcodebuild -project MyApp.xcodeproj -showBuildSettings | grep BUILD_DIR | head -1 | perl -pe 's/\s+BUILD_DIR = //' | perl -pe 's/\/Build\/Products/\/Logs\/Test/'`
TEST_RESULTS_DIR=`ls -t $TEST_LOGS_DIR | grep "xcresult" | head -1`
TEST_COV_REPORT_FILENAME=`ls "$TEST_LOGS_DIR/$TEST_RESULTS_DIR/1_Test" | grep "xccovreport"`
TEST_COV_REPORT_FULL_PATH="$TEST_LOGS_DIR/$TEST_RESULTS_DIR/1_Test/$TEST_COV_REPORT_FILENAME"


# Xcode 9
# TEST_LOGS_DIR=`xcodebuild -project MyApp.xcodeproj -showBuildSettings | grep BUILD_DIR | head -1 | perl -pe 's/\s+BUILD_DIR = //' | perl -pe 's/\/Build\/Products/\/Logs\/Test/'`
# TEST_COV_REPORT_FILENAME=`ls $TEST_LOGS_DIR | grep "xccovreport"`
# TEST_COV_REPORT_FULL_PATH="$TEST_LOGS_DIR/$TEST_COV_REPORT_FILENAME"


# More general recursive search. Perhaps less likely to fail on new Xcode versions. Relies on filepaths containing timestamps that sort alphabetically correctly in time
# TEST_LOGS_DIR=`xcodebuild -project MyApp.xcodeproj -showBuildSettings | grep BUILD_DIR | head -1 | perl -pe 's/\s+BUILD_DIR = //' | perl -pe 's/\/Build\/Products/\/Logs\/Test/'`
# TEST_COV_REPORT_FULL_PATH=`find $TEST_LOGS_DIR -name '*.xccovreport' | sort -r | head -1`


#2
TOTAL_XCTEST_COVERAGE=`xcrun xccov view $TEST_COV_REPORT_FULL_PATH | grep '.app' | head -1 | perl -pe 's/.+?(\d+\.\d+%).+/\1/'`

#3
echo "TOTAL_XCTEST_COVERAGE=$TOTAL_XCTEST_COVERAGE"
Run Code Online (Sandbox Code Playgroud)

What it does

#1 - gets the BUILD_DIR and then manipulates the path to get to the xccovreport file. Comment / uncomment the block for your version of Xcode.

#2 - We start with the full report as text. grep '.app' takes only the lines that contain .app. This is guaranteed to exist, because there is a line that reports the total coverage and contains MyApp.app. There will be multiple matches, but the first match will always be the overall total codecov score. So we use head -1 to take that first line of the grep result.

Now we have a line that looks like this:

MyApp.app                                      12.34% (8/65)
Run Code Online (Sandbox Code Playgroud)

We use a perl regex to take only the “12.34%” part.

#3 - We simply print out the result (together with the variable name to make it easier to locate later in GitLab CI)

How to use

  • Replace MyApp.xcodeproj with your correct value
  • Make sure the correct logic is applied in step #1 (Xcode 9 / Xcode 10 / Generalized recursive search)
  • Save to a printCodeCov.sh file in the root of your project.
  • Make the file executable chmod +x printCodeCov.sh
  • In your .gitlab-ci.yml file, add a line to the script that says - ./printCodeCov.sh
  • In your GitLab Pipeline Settings, set the Test coverage parsing to TOTAL_XCTEST_COVERAGE=(.+)%

Notes

  • This does not use the --json format of xccov. For that version, see below.
  • This solution might be fragile, because of multiple assumptions about folder locations and report format
  • I use perl instead of sed because the latter was too difficult (BSD/GNU differences, regex limitations etc).

JSON version

如果您希望使用JSON报告(来自xccov), then in the script you need something like this:

# Xcode 10
COV_NUMBER_FRACTION=`xcrun xccov view --json $TEST_COV_REPORT_FULL_PATH | perl -pe 's/.+?\.app.+?"lineCoverage":([^,]+).+/\1/'`

# Xcode 9
# COV_NUMBER_FRACTION=`xcrun xccov view --json $TEST_COV_REPORT_FULL_PATH | perl -pe 's/.+"targets"[^l]+lineCoverage":([^,]+),.+/\1/'`

COV_NUMBER_PERCENTAGE=`bc <<< $COV_NUMBER_FRACTION*100`
TOTAL_XCTEST_COVERAGE=`printf "%0.2f%%\n" $COV_NUMBER_PERCENTAGE`
Run Code Online (Sandbox Code Playgroud)