How to use GitLab’s built-in test coverage report tool for pure Swift packages?

Some test coverage report generation tools do not support “pure” Swift packages. One example is Slather. By pure, I’m referring to packages that contain only the Package.swift file, without any .xcodeproj or .xcworkspace files.

One solution to this problem was to generate a project file for a Swift package on the fly using Fastlane. This solution has one limitation: it’s not possible to generate a project file for a Swift package that contains any resources. When you try doing so, you’ll see Type 'Bundle' has no member “module” error when building.

Solution

What worked was using Fastlane with xcov. Here’s a snippet:

scan(
  package_path: ".",
  # Schemes generated by Xcode have a "-Package" suffix
  scheme: "MyPackage-Package",
  clean: true,
  device: "iPhone 14",
  code_coverage: true,
  result_bundle: true
)
xcov(
  is_swift_package: true
)

Here’s how the xcov output looks like:

+----------------------+--------+
|[32mxcov Coverage Report[0m    |
+----------------------+--------+
| MyPackage            | 13.75% |
| MyPackageTestUtils   | 0.00%  |
| MyPackageTests       | 22.12% |
| Average Coverage     | 11.96% |
+----------------------+--------+

The final piece of the puzzle is displaying the test coverage on the MR page like so:

hello there

In order to do that, we’ll need a regex to parse output from xcov. In this case we’re only interested in getting the percentage right beside “MyPackgae”. Here’s a snippet from the .gitlab-ci.yml file:

unit_test:
  stage: tests
  script:
    - bundle exec fastlane unit_test
  coverage: '/\|\s+MyPackage\s+\|\s+\d+\.\d+\%\s+\|/'

Resources