はじめに
バグが好きですか? 私はそれらのいくつかを崇拝します:脂肪のジューシーな致命的なバグは本当の喜びです、それらを逃してリリースをリリースすることは不可能です。 ただし、肉眼では見えないが、 OSの特定のバージョンでのみ、またはコンパイラーの最適化がオンになっている場合など、特定の条件で顕在化しようとする小さなバグもあります。 捕まえられないこれらの小さな悪党は、開発者の血をたくさん飲み、夜に睡眠を台無しにすることができます。 逆説的に、バグが現れる頻度が少なければ少ないほど、より多くの力がバグを捕らえて排除することがあります。 私の言いたいことを理解していれば、OSバージョン、デバイス、およびコンパイル設定の潜在的に使用される組み合わせのセット全体でテストを実行するという考えは、おそらく明らかです。
ただし、GitHubで人気のある数十のライブラリを簡単に確認するとわかるように、ほとんどの開発者は、各コミットの自動テスト実行( Travis-CIを使用 )を使用しても、iOSの最新バージョンの1つの構成のみをテストします。 さらにユニットはOS Xでテストを実行しますが、これは制限されています。 それがどのように異なる方法で行われるかを見てみましょう。
原則として、Xcode 5に組み込まれた継続的統合モジュールを使用すると、複数のシミュレーターでテストを実行できますが、十分な柔軟性が提供されず、一般的に多くの人がそれを嫌いました。 したがって、この記事では詳細に検討することはせず、さらに、すでにそれについて書いています。
xcodebuild
テストには、 Xcode Command Line Toolsに付属のxcodebuildユーティリティを使用します 。 以前は、Facebookのxctoolが最も好まれていました。 第一に、 xcodebuildはタンバリンとダンスなしでは起動しませんでした。第二に、 xctoolはより快適な結論を出します。 ただし、Xcode 5のリリースにより、ネイティブのxcodebuildが優先されて状況が変わりました。タンバリンは不要になり、現時点では xctoolではシミュレーターのタイプを設定でき ません 。これが実際に重要な瞬間です。
典型的なテストコマンドは次のようになります。
xcodebuild test -project {project}.xcodeproj -scheme {scheme} -sdk iphonesimulator -destination OS=6.0,name=iPhone -configuration Release
すべてが明らかです。プロジェクト(またはワークスペース)、スキーム、SDK、OSバージョン、シミュレーター名、デバッグ/リリース構成を示します。
小さなスクリプトで、可能なすべての構成を簡単に反復してテストできます(5.0 Deployment Targetがあり、iOSおよびOS Xのユニバーサルライブラリをテストしていると仮定):
for configuration in Release Debug do for device in "iPhone" "iPad" do for iosversion in 6.0 6.1 5.0 5.1 do test_ios iOSTests "$iosversion" "$device" "$configuration" done done for device in "iPhone Retina (3.5-inch)" "iPhone Retina (4-inch)" "iPad Retina" do for iosversion in 6.0 6.1 7.0 do test_ios iOSTests "$iosversion" "$device" "$configuration" done done for device in "iPhone Retina (4-inch 64-bit)" "iPad Retina (64-bit)" do test_ios iOSTests-64bit 7.0 "$device" "$configuration" done test_osx OSXTests "$configuration" done
(test_iosおよびtest_osx-テスト用の関数。 スクリプトの完全版は GitHubのテストプロジェクトで利用可能です)
これにより、40個の構成が可能になりますが、おそらく既に冗長になっているようです。 結局のところ、異なる解像度または異なる最適化設定でUIでロジックをテストすることはあまり意味がありません。 また、システムをOS X Mavericksにアップグレードできた場合、iOS 5シミュレーターが動作しないことに気づきました。
全体として、今後の記事では、次の構成をテストします。
論理テスト | iOS 6.0 | iOS 6.1 | iOS 7.0 | iOS 7.0 64ビット | OS X |
リリース | ✓ | ✓ | ✓ | ✓ | ✓ |
デバッグする | ✓ | ✓ | ✓ | ✓ | ✓ |
UIテスト | iPhone | iPad | iPhone Retina(3.5インチ) | iPhone Retina(4インチ) | iPad Retina |
iOS 6.0 | ✓ | ✓ | ✓ | ✓ | ✓ |
iOS 7.0 | ✓ | ✓ | ✓ | ✓ |
バインディングを追加して、正常にテストされた構成をカウントし、最初の失敗で終了すると、
スクリプトの最終バージョン:
test-main-configurations.sh
#!/bin/sh # Global settings project=XCode/TravisCI.xcodeproj
出力のフォーマット
function red() { eval "$1=\"$(tput setaf 1)$2$(tput sgr 0)\"" } function green() { eval "$1=\"$(tput setaf 2)$2$(tput sgr 0)\"" } function yellow() { eval "$1=\"$(tput setaf 3)$2$(tput sgr 0)\"" } function bold() { eval "$1=\"$(tput bold)$2$(tput sgr 0)\"" } function echo_fmt() { local str=$1 local color=$2 local bold=$3 if [ "$color" != '' ]; then $color str "$str" fi if [ "$bold" != '' ]; then $bold str "$str" fi echo $str }
テスト中
succeeded_count=0 function test() { local options="$@" echo_fmt "xcodebuild test -project $project $options" yellow xcodebuild test -project $project "$@" local exitcode=$? if [[ $exitcode != 0 ]] ; then echo_fmt "xcodebuild exited with code $exitcode" red echo_fmt "=== TESTS FAILED ===" red bold exit 1 else ((succeeded_count++)) fi } function test_ios() { local scheme=$1 local iosversion=$2 local device="$3" local configuration=$4 shift 4 echo_fmt "=== TEST SCHEME $scheme IOS $iosversion DEVICE $device CONFIGURATION $configuration ===" yellow bold test -scheme "$scheme" \ -sdk iphonesimulator \ -destination OS="$iosversion",name="$device" \ -configuration "$configuration" \ "$@" } function test_osx() { local scheme=$1 local configuration=$2 shift 2 echo_fmt "=== TEST SCHEME $scheme OSX CONFIGURATION $configuration ===" yellow bold test -scheme "$scheme" -configuration "$configuration" "$@" }
# Logic tests for configuration in Release Debug do for iosversion in 6.0 6.1 7.0 #5.0 5.1 # Mavericks does not support iOS 5 Simulator do test_ios "iOSLogicTests" "$iosversion" "iPad Retina" "$configuration" done test_ios "iOSLogicTests-64bit" 7.0 "iPad Retina (64-bit)" "$configuration" ONLY_ACTIVE_ARCH=YES test_osx "OSXTests" "$configuration" done # UI tests test_ios "iOSUITests" 6.0 "iPhone" Debug for device in "iPad" "iPhone Retina (3.5-inch)" "iPhone Retina (4-inch)" "iPad Retina" do for iosversion in 6.0 7.0 do test_ios "iOSUITests" "$iosversion" "$device" Debug done done # Result echo_fmt "=== SUCCEEDED $succeeded_count CONFIGURATIONS. ===" green bold
どの打ち上げ:
./Script/test-main-configurations.sh
成功したテストに関するメッセージを提供します:
===成功した19の構成===またはエラーメッセージ:
===テストに失敗しました===
iOS 64ビットシミュレーターでのテストについて
ある種のバグにより、Xcode は64ビットシミュレータでのテストの実行を許可せず 、奇妙なメッセージを宣誓します。
この不名誉は 、テストされた構成(デバッグ/リリース)で「アクティブアーキテクチャのみをビルド」 = 「YES」に設定することで修正されます。 したがって、64ビットテスト用のスクリプトには、追加オプション
ます。
この不名誉は 、テストされた構成(デバッグ/リリース)で「アクティブアーキテクチャのみをビルド」 = 「YES」に設定することで修正されます。 したがって、64ビットテスト用のスクリプトには、追加オプション
ONLY_ACTIVE_ARCH=YES
ます。
Xcode
誰かがスクリプトを手動で実行することを好まない可能性があるため、それを実行する別のターゲットを作成できます。 これを行うには、Xcodeで、 ターゲットの追加...- > その他 -> 集計操作、次にエディター -> ビルドフェーズの 追加 -> 実行スクリプトビルドフェーズの追加を実行し 、次のスクリプトを追加します。
cd ${SRCROOT}/.. # scriptname="test-main-configurations" script="Script/${scriptname}.sh" log="Script/${scriptname}.log" $script > $log # , if [[ $? != 0 ]] ; then # , ... echo "error: TESTS FAILED" # ... , ... exit 1 else rm $log # ... fi
ここで、このターゲット( ⌘ + B )のアセンブリが正常に完了した場合、テストは正常に合格し、そうでない場合は、 Scripts / test-main-configurations.logログに移動して、理由を確認します。
もちろん、各コミットの前にそのようなテストを手動で実行するのは十分ではありませんが、新しいDVCSブランチに同様のビルドフェーズを追加するなどして、新しいリリースをリリースするときにこれを必須ステップにすることは非常に可能です。
トラビス-ci
ただし、テストが定期的に自動的に実行されるとより効果的です。GitHubを押すたびにすべてのテストが自動的に実行されるTravis-CI統合システムをセットアップするためです。 対応する記事が既にあったので、あまり詳細には説明しません。必要な点だけを説明します。
必要なのは、リポジトリのルートに.travis.yml ファイルを追加することです。これは、スクリプトを実行する必要があることを示します。
language: objective-c script: Script/test-main-configurations.sh
さて、Travis-CIにログインし、目的のリポジトリのチェックマークを有効にします。 原則として、それだけです。 これで、コミットが徹底的にテストされ、プルリクエストにTravisからのメッセージが添付されます。
テスト回路がリポジトリに存在することを確認することを忘れないでください。 共有チェックボックスが設定されています:
ところで、TravisはOS X 10.8.5でXcode 5.0.2を使用しているため、iOS 5.0およびiOS 5.1でテストを実行できます。
デバイスでのテスト。
iOS 5にまだデバイスがある場合は、いくつかの構成に対して同様のスクリプトを記述することにより、デバイスでテストを実行できます。 論理テストはシミュレータでのみ実行され、アプリケーションテストのみがデバイスで実行できます。 したがって、ライブラリをテストする場合は、ライブラリで空のコンテナアプリケーションを作成してテストする必要があります。
デバイスでテストするためのxcodebuildコマンドは次のようになります。
xcodebuild test -project XCode/TravisCI.xcodeproj -scheme iOSDeviceLogicTests -sdk iphoneos -destination name='iPad Yan' -configuration Release
何かが開始されない場合は、ネタバレを参照してください
- プロビジョニングプロファイルに問題がある可能性があります 。 Xcodeからデバイスでアプリケーションが起動しているかどうかを確認します。
- [ ターゲットの依存関係]の[ ビルドフェーズ]に、テストターゲットのコンテナーアプリケーションがあることを確認します。
- Build SettingsのBundle Loaderパラメーターは次のように設定する必要があります。
$(BUILT_PRODUCTS_DIR)/MyExistingApp.app/MyExistingApp
- また、 Test Hostパラメーターには値があります。
$(BUNDLE_LOADER)
- また、コンテナアプリケーションのアセンブリ設定では、[ デフォルトで非表示のシンボル]パラメーターはNOに等しくなければなりません。
それだけです いいテストをしてください!