Xcodeでカバレッジを取得する

gcovというテストカバレッジツールを使ってカバレッジを取得します。

gcovはC/C++でお世話になるカバレッジ測定ツールでgccに付属しているものになります。
Objective-Cもgcovでカバレッジが取得できるようです。

まずは前置きとして、
今回の記事で使用するプロジェクト構成です。

Xcodeのバージョンは 6.1.1 です。

![スクリーンショット 2015-02-27 16.48.10.png](https://qiita-image-store.s3.amazonaws.com/0/53393/bf7532a9-f616-2f91-2ca0-bc51cdb5cc02.png)

中身はサンプル用のメソッドが1個定義してあるだけです。

# gcov用ファイルの.gcnoと.gcdaを吐く

デフォルトのXcodeプロジェクトでは、テストコードを実行してもカバレッジ取得まではできません。
Xcodeプロジェクトの設定を変更し、カバレッジ取得用の.gcno, .gcdaというファイルを出力させます。

## Xcodeプロジェクトの設定を変更する

### 1. Generate Test Coverage Files

プロジェクトをクリックしてBuild Settingsを開き、「gcov」を検索します。

**Generate Test Coverage Files** を **No -> Yes** に変更します。

![スクリーンショット 2015-02-27 16.57.44.png](https://qiita-image-store.s3.amazonaws.com/0/53393/de518129-1824-bef8-44dd-daf031472207.png)

### 2. Instrument Program Flow

続いて「flow」と検索します。

**Instrument Program Flow** を **No -> Yes** に変更します。

![スクリーンショット 2015-02-27 16.58.21.png](https://qiita-image-store.s3.amazonaws.com/0/53393/17481ae0-23f1-425f-4435-c7f7146dfaad.png)

準備完了！

# 実際にテストを実行してカバレッジを取得する

普通にXcodeでテストを実行します。

![20150227193940.png](https://qiita-image-store.s3.amazonaws.com/0/53393/dda8a632-61d1-b216-a715-da0f79cb450b.png)

Windows -> Organizer で Derived Data の場所を確認。

その奥深くを見に行くと...

![20150227194114.png](https://qiita-image-store.s3.amazonaws.com/0/53393/c051cd2e-749e-c500-68f5-3780eb936ccd.png)

HelloLibrary.gcno
HelloLibrary.gcda

があり、Organizerで確認したDerived Dataの位置からのパスは以下のようになっています。

HelloLibrary-dfakvcppqwhskdgievpsvprvyout/Build/Intermediates/HelloLibrary.build/Debug-iphonesimulator/HelloLibrary.build/Objects-normal/x86_64

# CoverStoryでカバレッジを見る

CoverStoryはGoogle製のコードカバレッジビューワーです。

CoverStoryをインストールしたら **File -> Open** で上記のディレクトリを開きます。

※CoverStoryは起動してもUI的なものは立ち上がらないのでご注意ください。
※ディレクトリをOpenすればUIが起動します。

![20150227200149.png](https://qiita-image-store.s3.amazonaws.com/0/53393/de8f0b52-478e-f2dd-a322-c4e03fd6dc88.png)

こんな感じ。

# Jenkinsと連携する

Jenkinsと連携するためには、gcovr + Coverturaプラグインを使います。

gcovrとは、gcovの結果をcovertura形式のxmlに変換してくれるpythonスクリプトです。

gcovrもC++でお世話になっております。
(せっかく保存しておいたgcovr君を後輩の手によって誤って消されるという事件もありましたが...)

Jenkinsで表示するからには、
ビルドからテストから全部コマンドでやらねばか...
(JenkinsにXcode用のプラグインもありますがまたの機会に使おうと思います)

## 1. xcodebuildコマンドでビルドする

```bash
$ cd ${WORKSPACE}
$ xcodebuild -sdk iphonesimulator -configuration Debug build
Build settings from command line:
    SDKROOT = iphonesimulator8.1

=== BUILD TARGET HelloLibrary OF PROJECT HelloLibrary WITH CONFIGURATION Debug ===

〜略〜

** BUILD SUCCEEDED **
```

buildというディレクトリが出来上がってHelloLibrary.aなどが生成されます。

## 2. xcodebuildコマンドでテストを実行する

```bash
$ cd ${WORKSPACE}
$ xcodebuild test -scheme HelloLibraryTests -sdk iphonesimulator -configuration Debug -destination "platform=iOS Simulator,OS=8.1,name=iPhone 6" OBJECT_FILE_DIR=Objects
Build settings from command line:
    OBJECT_FILE_DIR = Objects
    SDKROOT = iphonesimulator8.1
    
=== BUILD TARGET HelloLibrary OF PROJECT HelloLibrary WITH CONFIGURATION Debug ===

〜略〜

=== BUILD TARGET HelloLibraryTests OF PROJECT HelloLibrary WITH CONFIGURATION Debug ===

〜略〜

** BUILD SUCCEEDED **

$ cd Objects-normal/x86_64/
$ ls
HelloLibrary.LinkFileList	HelloLibrary.dia		HelloLibrary.gcno		HelloLibraryTests.LinkFileList	HelloLibraryTests.dia		HelloLibraryTests.gcno
HelloLibrary.d			HelloLibrary.gcda		HelloLibrary.o			HelloLibraryTests.d		HelloLibraryTests.gcda		HelloLibraryTests.o
```

Objects-normal/x86_64というディレクトリが出来上がり、
何故か、不要なテストクラスの.gcnoと.gcdaも出来上がっています。

そして、実行ログを見ての通り **1. xcodebuildコマンドでビルドする** の手順が必要ありませんでした。

## 3. gcovrを実行する

```bash
$ cd ${WORKSPACE}
$ ./gcovr -e ".*Tests" Objects-normal/x86_64 --xml > coverage.xml
```

何故かテストクラスのカバレッジも取得されていますので、
HelloLibraryTestsは要らないので-eで除外してます。

## 4. Jenkinsに喰わせる

あとは、JenkinsのCoverturaプラグインにcoverage.xmlを喰わせれば完了！

# まとめ

XcodeやxcodebuildコマンドといったMac OS特有のもの以外は、
gcovなど自分にとっては慣れ親しんだツールばかりだったのでやりやすかった。

やっぱりObjective-CよりもXcodeとかxib周りとかが難しい。