You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

M1芯片Mac上Xcode Swift项目SonarQube测试覆盖率上报问题

问题描述
  • 环境:M1芯片Mac Pro、Xcode 13.4,已通过适配M1的Docker镜像成功启动本地SonarQube
  • 核心问题:无法将测试结果和代码覆盖率上报至SonarQube项目,执行xcrun xccov view YourPathToThisFile/*.xccovreport --json失败(实际需要XML格式),SonarQube页面显示“主分支无代码行”
  • 当前SonarQube配置文件:
#
# Swift SonarQube Plugin - Enables analysis of Swift and Objective-C projects into SonarQube.
# Copyright © 2015 Backelite (${email})
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# Sonar Server details
sonar.host.url=http://localhost:9000/
sonar.login=782a04fee8bfc7ae181f04bbd13734eb89e5580c

# sonar.password=admin

# Project Details
sonar.projectKey=tinggios
sonar.projectName=TinggIOSApp
sonar.projectDescription=This is TinggiOS

# Comment if you have a project with mixed ObjC / Swift
sonar.language=swift
sonar.projectKey=tinggios
sonar.qualitygate.wait=true

# Path to source directories
# sonar.sources=SonarDemo,SonarDemoTests,SonarDemoUITests
sonar.sources=.

# Exclude directories
sonar.test.inclusions=**/*Test*/**
sonar.test.inclusions=*.swift
sonar.exclusions=**/*.xml,Pods/**/*,Reports/**/*
# sonar.inclusions=*.swift

# Path to test directories (comment if no test)
sonar.tests=TinggIOS/Core/Tests/CoreTests,TinggIOS/Home/Tests/HomeTests,TinggIOS/OnboardingUITest

# Destination Simulator to run surefire
# As string expected in destination argument of xcodebuild command
# Example = sonar.swift.simulator=platform=iOS Simulator,name=iPhone 6,OS=9.2
# sonar.swift.simulator=platform=iOS Simulator,name=iPhone 7,OS=12.0
sonar.swift.simulator=platform=iOS Simulator,name=iPhone 11,OS=15

# Xcode project configuration (.xcodeproj)
# and use the later to specify which project(s) to include in the analysis (comma separated list)
# Specify either xcodeproj or xcodeproj + xcworkspace
sonar.swift.project=TinggIOS/TinggIOS.xcodeproj
sonar.swift.workspace=TinggIOS/TinggIOS.xcworkspace

sonar.language=swift

sonar.c.file.suffixes=-
sonar.cpp.file.suffixes=-
sonar.objc.file.suffixes=-
# Specify your appname.
# This will be something like "myApp"
# Use when basename is different from targeted scheme.
# Or when slather fails with 'No product binary found'
sonar.swift.appName=TinggIOS

# Scheme to build your application
sonar.swift.appScheme=TinggIOS

# Configuration to use for your scheme. if you do not specify that the default will be Debug
sonar.swift.appConfiguration=Debug

##########################
# Optional configuration #
##########################

# Encoding of the source code
sonar.sourceEncoding=UTF-8

# SCM
# sonar.scm.enabled=true
# sonar.scm.url=scm:git:http://xxx

# JUnit report generated by run-sonar.sh is stored in sonar-reports/TEST-report.xml
# Change it only if you generate the file on your own
# The XML files have to be prefixed by TEST- otherwise they are not processed
sonar.junit.reportsPath=sonar-reports/TEST-report.xml

# Cobertura report generated by run-sonar.sh is stored in sonar-reports/coverage-swift.xml
# Change it only if you generate the file on your own
sonar.swift.coverage.reportPattern=sonar-reports/coverage-swift*.xml
#sonar.coverageReportPaths=sonarqube-generic-coverage.xml
#sonar.swift.coverage.reportPattern=sonar-reports/cobertura.xml

# OCLint report generated by run-sonar.sh is stored in sonar-reports/oclint.xml
# Change it only if you generate the file on your own
sonar.swift.swiftlint.report=sonar-reports/*swiftlint.txt

# Change it only if you generate the file on your own
sonar.swift.tailor.report=sonar-reports/*tailor.txt

# Paths to exclude from coverage report (surefire, 3rd party libraries etc.)
# sonar.swift.excludedPathsFromCoverage=pattern1,pattern2
# sonar.swift.excludedPathsFromCoverage=.*Tests.*,

##########################
# Tailor configuration #
##########################
# Tailor configuration
# -l,--max-line-length=<0-999>                  maximum Line length (in characters)
#    --list-files                               display Swift source files to be analyzed
#    --max-class-length=<0-999>                 maximum Class length (in lines)
#    --max-closure-length=<0-999>               maximum Closure length (in lines)
#    --max-file-length=<0-999>                  maximum File length (in lines)
#    --max-function-length=<0-999>              maximum Function length (in lines)
#    --max-name-length=<0-999>                  maximum Identifier name length (in characters)
#    --max-severity=<error|warning (default)>   maximum severity
#    --max-struct-length=<0-999>                maximum Struct length (in lines)
#    --min-name-length=<1-999>                  minimum Identifier name length (in characters)

sonar.swift.tailor.config=--no-color --max-line-length=100 --max-file-length=500 --max-name-length=40 --max-name-length=40 --min-name-length=4
可行解决方案

一、修复代码行识别问题(解决“主分支无代码行”)

  1. 修正源文件与测试文件路径配置
    当前sonar.sources=.会包含所有目录,导致SonarQube无法正确识别业务代码,建议明确指定业务代码目录:

    sonar.sources=TinggIOS/Core,TinggIOS/Home,TinggIOS/Onboarding
    

    同时清理重复的sonar.test.inclusions规则,保留精准匹配:

    sonar.test.inclusions=**/*Test*/**/*.swift
    sonar.exclusions=**/*Test*/**,Pods/**/*,Reports/**/*,**/*.xml
    
  2. 确认Swift插件兼容性
    确保SonarQube安装的Swift插件版本兼容Xcode 13.4与M1架构,建议使用最新稳定版。

二、生成JUnit格式测试报告

直接使用xcresulttool将Xcode测试结果转换为SonarQube支持的JUnit XML格式:

  1. 先执行测试生成xcresult文件:
    xcodebuild test -workspace TinggIOS/TinggIOS.xcworkspace -scheme TinggIOS -destination 'platform=iOS Simulator,name=iPhone 11,OS=15' -configuration Debug -resultBundlePath TestResults.xcresult
    
  2. 转换为JUnit XML:
    xcresulttool export --path TestResults.xcresult --type junit --output sonar-reports/TEST-report.xml
    
    确保生成的文件路径与配置中sonar.junit.reportsPath一致。

三、生成Cobertura格式覆盖率报告

使用slather工具将xccov数据转换为SonarQube支持的Cobertura XML格式:

  1. 安装slather(需Ruby环境):
    gem install slather
    
  2. 生成覆盖率报告:
    slather coverage --workspace TinggIOS/TinggIOS.xcworkspace --scheme TinggIOS --configuration Debug --output-format cobertura --output-directory sonar-reports --binary-path ./Build/Products/Debug-iphonesimulator/TinggIOS.app/TinggIOS
    
    注意:binary-path需指向你的APP二进制文件实际路径,根据Xcode构建产物位置调整。
  3. 更新Sonar配置中的覆盖率路径:
    sonar.swift.coverage.reportPattern=sonar-reports/cobertura.xml
    

四、执行Sonar扫描

确保所有报告生成完成后,执行扫描命令:

sonar-scanner

内容的提问来源于stack exchange,提问作者Darotudeen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 05:03:19