14
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

XcodeのコードカバレッジをHTMLなどで出力する方法

はじめに

「Slather」というツールを使い、XcodeプロジェクトのコードカバレッジをHTMLなどで出力する方法を紹介します。

「Slather」とは?

Ruby製のXcodeプロジェクト用コードカバレッジレポート生成ツールです。
Xcodeのテストで出力したコードカバレッジを、XMLやHTML形式に変換できます。
Fastlane、Circle CIやTravis CIなどのCIサービスと連携できるようにもなっており、簡単に導入できるのが魅力です。

環境

  • RubyGems:2.7.1
  • Bundler:2.0.1
  • Slather:2.4.6

Slatherのセットアップ

Slatherのインストール

Gemfileに以下を追加し、Bundlerからインストールします。

Gemfile
+ gem 'slather'
$ bundle install

設定ファイルの編集

プロジェクトのルートフォルダに .slather.yml というファイルを作成し、Xcodeプロジェクトの情報や出力パスなどを記述します。
設定ファイルを作成せず、必要な情報をコマンドラインの引数に渡して実行することもできます。

設定ファイルの書き方は公式をご参照ください。
https://github.com/SlatherOrg/slather

例:
CoberturaのXML形式でコードカバレッジを出力

.slather.yml
coverage_service: cobertura_xml
xcodeproj: {プロジェクト名}.xcodeproj
workspace: {ワークスペース名}.xcworkspace
scheme: {スキーマ名}
source_directory: {プロジェクトのルートフォルダ}
output_directory: xml_report
ignore:
  - Pods/*
  - Carthage/*
  - "**/AppDelegate.swift"
  - "**/SceneDelegate.swift"
  - "**/Generated/*"
  - "**/UIParts/*"
  - "**/Views/*"
  - "**/Routers/*"

ignoreで指定するパスの先頭にワイルドカード( * )を使う場合、ダブルクォーテーション( " )で括らないと以下のエラーが発生します。

bundle exec slather coverage --html --output-directory html_report
bundler: failed to load command: slather (/Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/bin/slather)
Psych::SyntaxError: (.slather.yml): did not find expected alphabetic or numeric character while scanning an alias at line 10 column 5
  /usr/local/Cellar/ruby@2.6/2.6.5/lib/ruby/2.6.0/psych.rb:456:in `parse'
  /usr/local/Cellar/ruby@2.6/2.6.5/lib/ruby/2.6.0/psych.rb:456:in `parse_stream'
  /usr/local/Cellar/ruby@2.6/2.6.5/lib/ruby/2.6.0/psych.rb:390:in `parse'
  /usr/local/Cellar/ruby@2.6/2.6.5/lib/ruby/2.6.0/psych.rb:277:in `load'
  /usr/local/Cellar/ruby@2.6/2.6.5/lib/ruby/2.6.0/psych.rb:578:in `block in load_file'
  /usr/local/Cellar/ruby@2.6/2.6.5/lib/ruby/2.6.0/psych.rb:577:in `open'
  /usr/local/Cellar/ruby@2.6/2.6.5/lib/ruby/2.6.0/psych.rb:577:in `load_file'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/gems/slather-2.4.7/lib/slather/project.rb:298:in `yml'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/gems/slather-2.4.7/lib/slather/command/coverage_command.rb:102:in `project'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/gems/slather-2.4.7/lib/slather/command/coverage_command.rb:73:in `setup_output_directory'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/gems/slather-2.4.7/lib/slather/command/coverage_command.rb:44:in `execute'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/gems/clamp-1.3.1/lib/clamp/command.rb:66:in `run'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/gems/clamp-1.3.1/lib/clamp/subcommand/execution.rb:18:in `execute'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/gems/clamp-1.3.1/lib/clamp/command.rb:66:in `run'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/gems/clamp-1.3.1/lib/clamp/command.rb:140:in `run'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/gems/slather-2.4.7/bin/slather:17:in `<top (required)>'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/bin/slather:23:in `load'
  /Users/runner/runners/2.165.2/work/1/s/vendor/bundle/ruby/2.6.0/bin/slather:23:in `<top (required)>'
Slathering...

ignoreでコードカバレッジの計算に含めないファイルを指定できるのがいいです。
Xcodeによるコードカバレッジの算出では除外するファイルを(自分の知る限り)指定できません。

スキーマの編集

コードカバレッジを出力するようにスキーマを編集します。
公式の通りに設定します。
https://github.com/SlatherOrg/slather#usage

私は「all targets」でなく、「some targets」にしてテストターゲットを除いて指定しています。

スクリーンショット_2019-04-09_23_03_55.jpg

コードカバレッジレポートの生成・閲覧

Xcodeによるテスト実行

Xcodeでテストを実行し、コードカバレッジを算出します。
Slatherではこのコードカバレッジを元にレポートを生成します。

コードカバレッジレポートの生成

プロジェクトのルートフォルダで以下のコマンドを実行します。

$ bundle exec slather

HTML形式で出力するには --html オプションを付けます。

$ bundle exec slather coverage --html \
  --output-directory html_report

設定ファイルを作成していない場合、以下のように引数を追加して実行します。

$ bundle exec slather coverage -s \
  --scheme {スキーマ名} \
  --workspace {.xcworkspaceのパス} \
  {.xcodeprojのパス}

コードカバレッジレポートの閲覧

例としてHTML形式のレポートを閲覧します。
「…/html_report/index.html」をWebブラウザで開くとドキュメントを閲覧できます。

スクリーンショット_2019-04-09_23_55_39.jpg

ファイル名をクリックすると、どの処理が実行されているのか確認できます。

スクリーンショット_2019-04-09_23_56_25.jpg
スクリーンショット_2019-04-09_23_56_37.jpg

注意

Xcodeでテストを実行せずにコードカバレッジが生成されていないと、以下のエラーが発生します。
エラーから原因が特定できず、少し苦戦しました。
https://github.com/SlatherOrg/slather/issues/341

$ bundle exec slather coverage -s --scheme {スキーマ名} --workspace {ワークスペース名}.xcworkspace {プロジェクト名}.xcodeproj
Slathering...
no implicit conversion of nil into String

Are you sure your project is generating coverage? Make sure you enable code coverage in the Test section of your Xcode scheme.
Did you specify your Xcode scheme? (--scheme or 'scheme' in .slather.yml)
If you're using a workspace, did you specify it? (--workspace or 'workspace' in .slather.yml)
If you use a different Xcode configuration, did you specify it? (--configuration or 'configuration' in .slather.yml)

bundler: failed to load command: slather (/usr/local/bin/slather)
TypeError: no implicit conversion of nil into String
/Library/Ruby/Gems/2.3.0/gems/slather-2.4.6/lib/slather/project.rb:184:in `initialize'
/Library/Ruby/Gems/2.3.0/gems/slather-2.4.6/lib/slather/project.rb:184:in `new'
/Library/Ruby/Gems/2.3.0/gems/slather-2.4.6/lib/slather/project.rb:184:in `profdata_coverage_dir'
/Library/Ruby/Gems/2.3.0/gems/slather-2.4.6/lib/slather/project.rb:460:in `find_binary_files'
/Library/Ruby/Gems/2.3.0/gems/slather-2.4.6/lib/slather/project.rb:399:in `configure_binary_file'
/Library/Ruby/Gems/2.3.0/gems/slather-2.4.6/lib/slather/project.rb:281:in `configure'
/Library/Ruby/Gems/2.3.0/gems/slather-2.4.6/lib/slather/command/coverage_command.rb:57:in `execute'
/Library/Ruby/Gems/2.3.0/gems/clamp-0.6.5/lib/clamp/command.rb:67:in `run'
/Library/Ruby/Gems/2.3.0/gems/clamp-0.6.5/lib/clamp/subcommand/execution.rb:11:in `execute'
/Library/Ruby/Gems/2.3.0/gems/clamp-0.6.5/lib/clamp/command.rb:67:in `run'
/Library/Ruby/Gems/2.3.0/gems/clamp-0.6.5/lib/clamp/command.rb:132:in `run'
/Library/Ruby/Gems/2.3.0/gems/slather-2.4.6/bin/slather:17:in `<top (required)>'
/usr/local/bin/slather:22:in `load'
/usr/local/bin/slather:22:in `<top (required)>'

おまけ: SwiftPMで管理しているライブラリのソースを無視する

デフォルトでは、SwiftPMで管理しているライブラリのソースが対象になってしまいます。
無視するには xcodebuild コマンドの -clonedSourcePackagesDirPath オプションで ./SourcePackages を指定し、設定ファイルに以下を追加します。

.slather.yml
ignore:
+   - SourcePackages/*

参考:https://github.com/uhooi/UhooiPicBook/commit/a14031e09331b65f703a59a56fffb45191bd29e6

おわりに

Xcodeプロジェクトのコードカバレッジを、HTMLなどでグラフィカルに出力することができました!
これでiOSアプリ開発でコードカバレッジの提出を求められても安心です:relaxed:

参考リンク

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
14
Help us understand the problem. What are the problem?