Pragmatic ball boy

iOSを中心にやってる万年球拾いの老害エンジニアメモ

Travis CIでObjective-C/Swiftのテストを実行する

[環境]Xcode 6.1

Swift,Objective-Cどちらの場合でもこの方法でいけるはずです。

Travis CIにドキュメントが用意されていますが、xctoolを使った例が示されているので無視したほうがよいです。xctoolはAppleが用意した標準のビルドツールではなく、Facebookがその置換えとして作ったツールなので、Xcodeがバージョンアップするたびに大抵ぶっ壊れるので使わないほうが無難です。Travis CIでは何を間違ったのかデフォルトでxctoolを使っています、自分らでXcodeの変化についていけるようにメンテしてるならいいんですが、そこは不明。。ここではxcodebuildを使った方法を記載します。

Building an Objective-C Project - Travis CI

xcodebuild

command lineでテストを実行するにはxcodebuildを使います。

xcodebuild(1) Mac OS X Developer Tools Manual Page

xcodebuildには最低限以下のようなオプションを設定する必要があります

  • -workspace
  • -scheme(必須)
  • -configuration
  • -destination(必須)
    • platform
      • iOS Simulator を指定
    • name
      • シミュレーター名。 xcrun simctl listで確認
    • OS
      • iOSバージョン。 8.1 など。これも xcrun simctl listで確認

そして、buildactionとして test を指定すれば、ビルド後テストが実行されます。

 xcodebuild -workspace MyWorkspace.xcworkspace -scheme MyScheme -configuration Debug -destination 'platform=iOS
              Simulator,name=iPhone 6,0S=8.0' -destination 'platform=iOS Simulator,name=iPad Air,0S=7.1' test

destination複数設定できるので、複数のシミュレータで実行したい場合などは複数指定すれば、何度もxcodebuild testを実行する必要はありません。

引っかかりやすいポイント

scheme

schemeがgit repositoryで管理されていない状態でxcodebuildを実行すると

xcodebuild: error: The project 'XXXX' does not contain a scheme named 'XXXX'.

とエラーが出てしまいます。 schemeの情報は通常だとxcuserdataいかに保存されるようですが、ユーザー毎の情報なので普通はrepositoryからは.gitigoreで排除しているはず。それではどうするかというとxcshareddataとしてrepositoryにいれます。 方法は、以下のように"Manage schemes..."を選択し、scheme一覧を表示し、"shared"のチェックボックスにチェックをいれてcloseするとxcshareddataが生成されているのでrepositoryにコミットすればよいはず。

f:id:yanamura:20141025210054p:plain

f:id:yanamura:20141025210105p:plain

destinationの name と OSの対応の調べ方

以下のコマンドを実行します

> xcrun simctl list

そうすると以下のようにOSのバージョンとそれに対応するシミュレーターのリストが出てくるのでこれを使えばよいです。

== Device Types ==
iPhone 4s (com.apple.CoreSimulator.SimDeviceType.iPhone-4s)
iPhone 5 (com.apple.CoreSimulator.SimDeviceType.iPhone-5)
iPhone 5s (com.apple.CoreSimulator.SimDeviceType.iPhone-5s)
iPhone 6 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus)
iPhone 6 (com.apple.CoreSimulator.SimDeviceType.iPhone-6)
iPad 2 (com.apple.CoreSimulator.SimDeviceType.iPad-2)
iPad Retina (com.apple.CoreSimulator.SimDeviceType.iPad-Retina)
iPad Air (com.apple.CoreSimulator.SimDeviceType.iPad-Air)
Resizable iPhone (com.apple.CoreSimulator.SimDeviceType.Resizable-iPhone)
Resizable iPad (com.apple.CoreSimulator.SimDeviceType.Resizable-iPad)
== Runtimes ==
iOS 7.0 (7.0.3 - 11B507) (com.apple.CoreSimulator.SimRuntime.iOS-7-0)
iOS 7.1 (7.1 - 11D167) (com.apple.CoreSimulator.SimRuntime.iOS-7-1)
iOS 8.1 (8.1 - 12B411) (com.apple.CoreSimulator.SimRuntime.iOS-8-1)
== Devices ==
-- iOS 7.0 --
    iPhone 4s (0FF14361-F567-4B40-9FE4-79D572867676) (Shutdown)
    iPhone 5 (29226DD1-620D-4746-911E-CEC9A5B76A94) (Shutdown)
    iPhone 5s (CD01CF0C-5715-499D-A1F2-96E1E7D043CF) (Shutdown)
    iPad 2 (C884ACD1-D4D7-4391-9147-882B2C22B394) (Shutdown)
    iPad Retina (8C7D647C-7024-4E44-8555-4273A4264891) (Shutdown)
    iPad Air (33CDAD90-98F8-49FE-8EF9-51CE0F7B9043) (Shutdown)
-- iOS 7.1 --
    iPhone 4s (2FA61CBE-0077-44C2-A981-2B9B09A53C77) (Shutdown)
    iPhone 5 (9FE60E90-DB4A-4975-885A-087171F27099) (Shutdown)
    iPhone 5s (42A87F6B-BB69-499A-BB3A-FBBF4F8BDBCF) (Booted)
    iPad 2 (1A35A3AE-6F13-499F-BF8D-3AF0CF23096E) (Shutdown)
    iPad Retina (953DF503-1B98-4A74-8784-42680F1498C1) (Shutdown)
    iPad Air (9B94DE85-F421-4C2B-B570-D78D31034F16) (Shutdown)
-- iOS 8.1 --
    iPhone 4s (10AB167F-7C6F-4773-A9F0-4E3F66E2A4E4) (Shutdown)
    iPhone 5 (A12F3ACD-1DCE-4666-A1FA-443AA6AECC39) (Shutdown)
    iPhone 5s (7597741D-4654-4AC3-83A0-C82C81AFFFF7) (Shutdown)
    iPhone 6 Plus (EFE25990-D630-4D91-9A16-29479BAC6C44) (Shutdown)
    iPhone 6 (6A000F08-7D65-4894-B4AA-8A9A20CD57E3) (Shutdown)
    iPad 2 (CF8E7FC1-CC33-4F21-AA17-6DA5812DEA51) (Shutdown)
    iPad Retina (7AA79E2F-C397-46AC-B0F4-A291EB7A3B62) (Shutdown)
    iPad Air (09476634-4289-437E-B2EB-E4BDB4BFD6DA) (Shutdown)
    Resizable iPhone (131ED5C5-7E49-46CE-A72F-9FB2283B5D70) (Shutdown)
    Resizable iPad (24C58956-E9EF-4295-80BC-676343C8FA1B) (Shutdown)

command lineでのテスト実行方法がわかったので、後はTravis CIでこれを実行できるようにします。

.travis.yaml

Travis CIでテストを実行するgitリポジトリのrootに.travis.yamlファイルを作成します。 SwiftObjective-Cの場合以下を記載。

language: objective-c
script: xcodebuild -workspace MyWorkspace.xcworkspace -scheme MyScheme -destination 'platform=iOS
              Simulator,name=iPhone 6,OS=8.1' test

script以下はなんでもよいのでxcodebuildを別のファイルに切り出して、そのファイルを実行するとかでもよいです。そのほうがtravis CI用途以外でも使えるので。