以前、SauceLabsを使った自動テストと、AndroidのTravis CIによるビルドを実行してみました。
今回はiOSを対象に実施しますが、さらに一歩進んで、
GitHubへPush => Travis CIによるビルド => Travis CIのビルドスクリプトでSauceLabsによるテスト => 結果
という流れを実行してみます。
.travis.ymlの内容以外は基本Androidのものと同一なので省略しておきます。
内容
こちらによると、今(20140721現在)サポートされているiOSアプリは、以下の模様。
7.1 (simulator and device)
7.0 (simulator and device)
6.1 (simulator and device)
travis.ymlには、
- language:
- xcode_sdk:
などの要素をまずは指定してObjectiv-Cアプリのビルドスクリプトを記述します。
SchemeをShared指定する
1カ所、まずはビルドする上で忘れては行けない操作があります。
それは、「Manage Schemes」から、ビルドしたいスキームのSharedのチェックボックスにチェックを入れることです。こうしなければ、Schemeを指定してもビルドエラーになりビルドを実施できません。
環境
今回の開発環境の前提として、以下を考えます。
- CocoaPodsを使う
- xcode_workspace
実行
実際に実行に使ったtravis.ymlは以下となります。
ポイントだけ押さえておくと、
- rvm 1.9.3を指定することで、CocoaPodをgem install可能にする
- 2.0.0なんかだと、何やらインストール時にエラー出るらしいです。
- install:でpod installを行ったあと、rvm 2.1.0を使いSauceLabs利用に必要なgem群を取得
- env:指定で環境変数を与え
- rspecにてテストまで実施
これにより、テスト時にfalseを検出した場合、ビルド結果がfalseになります。
一方、after_scriptなんかにてrspec test.rbを入力したとしても、ログ上は失敗になるけれど、Travisの結果としてはsuccessとなります。なので、script:におさめてます。
.travis.yml
language: objective-c
xcode_sdk: iphonesimulator7.1
rvm: 1.9.3
# whitelist
branches:
only:
– master
before_install:
– gem install cocoapods -v '0.32.1'
install:
– pod install
env: SAUCE_USERNAME="sause username" SAUCE_ACCESS_KEY="sauce access key"
rvm: 2.1.0
script:
– ./travis_build.sh
– bundle install
– rspec test.rb
ビルドスクリプト
ビルドスクリプトであるtravis_build.shは以下のような形です。
ここは通常のxcodebuildによるアプリのビルドですね。
特に変わったところは無いのですが、あるとすればCocoaPodsを使うので、Xcodeのprojectではなく、xcworkspaceをプロジェクト対象と指定しているところでしょうか。
travis_build.sh
#!/bin/sh
PROJECT=sampleTravis.xcworkspace
SCHEME=sampleTravis
TEST_SDK=iphonesimulator
CONFIGURATION_DEBUG=Debug
DESTINATION="platform=iOS Simulator,name=iPhone Retina (4-inch),OS=7.1"
OUTPUT_PATH="`pwd`/build/"
# clean, build, XCTest を実行する
xcodebuild \
-workspace "${PROJECT}" \
-scheme "${SCHEME}" \
-sdk "${TEST_SDK}" \
-configuration "${CONFIGURATION_DEBUG}" \
-destination "${DESTINATION}" \
SYMROOT="$OUTPUT_PATH" \
DSTROOT="$OUTPUT_PATH" \
clean build test
SauceLabとの連携
以下のtest.rbには、今回は直接シナリオ(空ですが)を書いています。
ポイントは、env指定により指定された要素を環境変数として使っているところですかね。
test.rb
require 'rubygems'
require 'appium_lib'
require 'sauce_whisk'
require 'json'
require 'rest_client'
SAUCE_USERNAME = ENV['SAUCE_USERNAME']
SAUCE_ACCESS_KEY = ENV['SAUCE_ACCESS_KEY']
# This is the test itself
describe 'Computation' do
before(:each) do
Appium::Driver.new(desired_caps).start_driver
Appium.promote_appium_methods RSpec::Core::ExampleGroup
end
after(:each) do
# Get the success by checking for assertion exceptions,
# and log them against the job, which is exposed by the session_id
job_id = driver.send(:bridge).session_id
update_job_success(job_id, example.exception.nil?)
driver_quit
end
it 'just sample' do
puts 'in description'
# nothing
end
end
def desired_caps
{ caps:
{
'appium-version' => '1.2.0',
platformName: 'iOS',
platformVersion: '7.1',
deviceName: 'iPhone Simulator',
app: 'build/Debug-iphonesimulator/sampleCaptureForIos.app',
name: 'test for Appium'
}
}
end
def auth_details
un = SAUCE_USERNAME
pw = SAUCE_ACCESS_KEY
unless un && pw
STDERR.puts < success }.to_json, :content_type => :json
end
最後に
最後になりますが、Travis CIと連携できるビルドシステムとか、胸熱ですね!
デプロイメントパイプラインを自動化し、自分たちの開発スタイルにあわせていく。そんなツールにTravis良さそう。