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

时间:2017-01-06 01:04:18

标签: swift cocoapods gitlab-ci xcode-workspace

我有一个由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

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

2 个答案:

答案 0 :(得分:8)

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

还需要一个外部工具进行覆盖率分析 - xcov 似乎不再可用,所以我使用了 slather 。工作就像一个魅力。

以下是步骤:

1)获取slather

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/*"

您可以在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

4)下一步是:

  • 转到 gitlab页面/个人资料或其他任何名称

  • 转到设置,然后管道

Settings/Pipelines

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

Add your regex expression in the space provided and then save it

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

答案 1 :(得分:4)

由于Xcode 9.3 Apple提供了xccov,因此这是一个使用此解决方案的解决方案,它不依赖第三方依赖项(并且不在乎是否使用xcpretty-quiet等)

xccovreportxccov的概述

当您的计划启用了测试覆盖率时(或将-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>

将输出报告。 (您可以通过--json获得JSON报告)

我们需要做什么

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

面临两个挑战:
-首先,我们需要找出xccovreport的文件路径,其中包含随机字符串(在两个位置)
-然后,我们需要分析文件(使用一些正则表达式)并提取总百分比。

脚本

这就是我正在使用的(欢迎提出任何改进建议,因为我不是bash专家)

#!/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"

它做什么

#1-获取BUILD_DIR,然后操纵路径以获取xccovreport文件。注释/取消注释您的Xcode版本的块。

#2-我们以全文作为报告开始。 grep '.app'仅采用包含.app的行。由于存在一行报告总覆盖率并包含MyApp.app的行,因此保证存在这一点。将有多个匹配项,但第一个匹配项将始终是总的codecov分数。因此,我们使用head -1来获取grep结果的第一行。

现在我们有一行如下:

MyApp.app                                      12.34% (8/65)

我们使用perl正则表达式仅占“ 12.34%”部分。

#3-我们只需将结果打印出来(连同变量名一起使以后在GitLab CI中更容易定位)

使用方法

  • 用正确的值替换MyApp.xcodeproj
  • 确保在步骤#1中应用了正确的逻辑(Xcode 9 / Xcode 10 /广义递归搜索)
  • 保存到项目根目录中的printCodeCov.sh文件中。
  • 使文件可执行chmod +x printCodeCov.sh
  • 在您的.gitlab-ci.yml文件中,在script上添加一行- ./printCodeCov.sh
  • 在您的GitLab管道设置中,将测试覆盖率解析设置为TOTAL_XCTEST_COVERAGE=(.+)%

注释

  • 这不使用--json的{​​{1}}格式。对于该版本,请参见下文。
  • 由于对文件夹位置和报告格式有多种假设,因此该解决方案可能比较脆弱
  • 我使用xccov代替perl,因为后者太难了(BSD / GNU差异,正则表达式限制等)。

JSON版本

如果您希望使用sed的{​​{1}}报告,则在脚本中需要这样的内容:

JSON