イントロダクション
iOSアプリとゲーム開発の常に変化し続ける風景では、テストのアプローチが大きく変革しました。過去には「ウォーターフォール」方法論が主導し、テストは独立したフェーズとして行われていました。しかし今日、組織は繰り返しとアジャイルなプロセスにシフトし、迅速なフィードバックと柔軟性を優先しています。この変化により、自動化されたテストが台頭し、製品の品質を確保する方法が根本的に変わりました。この記事では、手動テストと自動化テストの主要な違いについて掘り下げ、アジャイルな開発フレームワーク内での自動化テストの利点を探求します。
ウォーターフォール vs アジャイル: パラダイムの変化
ウォーターフォール方法論:
伝統的なウォーターフォール方法論では、開発プロセスは要件収集、設計、実装、テスト、展開、サポートなどのフェーズを順次実行します。要件はプロジェクトの開始時に固定され、開発サイクルの最後にテスト(主に手動)が行われます。
アジャイル方法論:
一方、アジャイルは反復的で柔軟なアプローチを採用しています。開発プロセス全体で継続的なフィードバックと調整が可能です。ウォーターフォールとは異なり、テストは独立したフェーズではなく、開始時から連続的に統合されます。アジャイルでは、開発者が迅速なフィードバックを受け取り、要件の変更に適応できるように、自動化テストが一般的です。
アジャイルiOSアプリおよびゲーム開発における自動化テストの利点
迅速なフィードバック:アジャイルの自動化テストは、開発者が問題を迅速に検出し修正するのを支援し、iOSアプリおよびゲーム開発業界で非常に重要です。 リグレッションテスト:自動化テストにより、新しいコードが追加または変更されても既存の機能が正常に機能することが保証され、リグレッションの問題が防止されます。 品質向上:一貫して自動化テストを実行することで、開発者はプロセスの早い段階で欠陥を検出し、製品の品質を向上させることができます。これにより、継続的な改善の文化が醸成されます。 柔軟性:アジャイルの柔軟性は自動化テストとシームレスに連携し、要件の変更がある場合でもテストを簡単に更新できます。これはダイナミックなiOS開発において重要です。 効率性:自動化テストは、手動テストと比較して時間と労力を大幅に節約します。これにより、開発者はコーディングと創造性に集中できます。
iOSでのテスト駆動開発(TDD)
テスト駆動開発は、コードを実装する前にテストを書くことを提唱しています。テストはコードの実装の詳細ではなく、アプリの動作を定義するものとして捉えます。このアプローチにより、変更やリファクタリングが既存の機能を壊さないようになり、コードの堅牢性が向上します。
赤、緑、リファクタリング
「赤、緑、リファクタリング」戦略は、ユニットテストで貴重なツールです。以下の手順に従います: 動作を定義するテストを書き、テストを失敗させる(赤)。 テストを通過させるコードを実装する(緑)。 テストが引き続き成功した状態でコードをリファクタリングする(リファクタリング)。このプロセスにより必要な動作が維持されます。
アジャイルの世界での手動テスト
手動テストは、特に自動化が難しい視覚的なテストや探索的なテストには依然として有効です。探索的テストでは、特定の機能の範囲外でアプリの動作を調査し、使用可能な機能を探索し実験します。
CI/CD:継続的な品質を確保
継続的インテグレーション(CI)と継続的デリバリー(CD)は、アジャイルな環境で重要です。自動化されたCI/CDパイプラインは、コードの変更がデプロイ前に自動化されたテストを経ることを保証し、迅速なフィードバックを提供し、リグレッションのリスクを減少させます。 私たちのCI/CDパイプラインの例: ワークスペースをクリーンアップする。 コードをチェックアウトする。 デフォルトのスキームを設定する。 自動化テストをビルドおよび実行する。 証明書とプロビジョニングプロファイルをインストールする。 バージョン番号を増やす。 アプリをビルドしてアーカイブする。 クラッシュモニタリングのためにdSYMsをアップロードする。 IPAファイルを作成する。 TestFlightに展開する。 この自動化されたパイプラインにより、変更が徹底的にテストされ、手動の介入なしにアプリの機能性が向上しました。その結果、アプリの機能に対する信頼が高まります。
サポート方法
このコンテンツは永遠に無料で提供されます。気に入ってサポートしたい場合は、他の人と共有していただけると幸いです。また、私たちのゲームをダウンロードして正直なレビューを残していただけると嬉しいです。質問やフィードバックがある場合は、お気軽にお問い合わせいただければ、できる限りお手伝いさせていただきます。
今すぐApple App StoreからFalling Skyをダウンロードしてください:リンク
こちらは、日本語への翻訳です。
name: Falling sky CI/CD
on:
push:
branches: [ "main" ]
workflow_dispatch:
env:
ARCHIVE_SCHEME: "Falling Sky"
APP_NAME: "FallingSky"
BUNDLE_ID: com.fallingsky
jobs:
build:
name: Build and Test default scheme using any available iPhone simulator
runs-on: self-hosted
steps:
- name: Clean Workspace
run: |
rm -rf $GITHUB_WORKSPACE/*
rm -rf $RUNNER_TEMP/*
- name: Checkout
uses: actions/checkout@v3
- name: Set Default Scheme
run: |
scheme_list=$(xcodebuild -list -json | tr -d "\n")
default=$(echo $scheme_list | ruby -e "require 'json'; puts JSON.parse(STDIN.gets)['project']['targets'][0]")
echo $default | cat >default
echo Using default scheme: $default
- name: Build for test
env:
scheme: ${{ 'default' }}
platform: ${{ 'iOS Simulator' }}
run: |
# xcrun xctrace returns via stderr, not the expected stdout (see https://developer.apple.com/forums/thread/663959)
device=`xcrun xctrace list devices 2>&1 | grep -oE 'iPhone.*?[^\(]+' | head -1 | awk '{$1=$1;print}' | sed -e "s/ Simulator$//"`
if [ $scheme = default ]; then scheme=$(cat default); fi
if [ "`ls -A | grep -i \\.xcworkspace\$`" ]; then filetype_parameter="workspace" && file_to_build="`ls -A | grep -i \\.xcworkspace\$`"; else filetype_parameter="project" && file_to_build="`ls -A | grep -i \\.xcodeproj\$`"; fi
file_to_build=`echo $file_to_build | awk '{$1=$1;print}'`
xcodebuild clean build-for-testing -scheme "$scheme" -"$filetype_parameter" "$file_to_build" -destination "platform=$platform,name=$device"
- name: Test
timeout-minutes: 30
env:
scheme: ${{ 'default' }}
platform: ${{ 'iOS Simulator' }}
run: |
# xcrun xctrace returns via stderr, not the expected stdout (see https://developer.apple.com/forums/thread/663959)
device=`xcrun xctrace list devices 2>&1 | grep -oE 'iPhone.*?[^\(]+' | head -1 | awk '{$1=$1;print}' | sed -e "s/ Simulator$//"`
if [ $scheme = default ]; then scheme=$(cat default); fi
if [ "`ls -A | grep -i \\.xcworkspace\$`" ]; then filetype_parameter="workspace" && file_to_build="`ls -A | grep -i \\.xcworkspace\$`"; else filetype_parameter="project" && file_to_build="`ls -A | grep -i \\.xcodeproj\$`"; fi
file_to_build=`echo $file_to_build | awk '{$1=$1;print}'`
xcodebuild test-without-building -scheme "$scheme" -"$filetype_parameter" "$file_to_build" -destination "platform=$platform,name=$device" -test-iterations 3 -retry-tests-on-failure
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.DIST_CERT_BASE64 }}
P12_PASSWORD: ${{ secrets.DIST_CERT_P12_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.PROVISIONING_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- uses: yanamura/ios-bump-version@v1
with:
version: 1.1.0
build-number: ${{ github.run_number }}
- name: Build and archive app
run: |
if [ "`ls -A | grep -i \\.xcworkspace\$`" ]; then filetype_parameter="workspace" && file_to_build="`ls -A | grep -i \\.xcworkspace\$`"; else filetype_parameter="project" && file_to_build="`ls -A | grep -i \\.xcodeproj\$`"; fi
file_to_build=`echo $file_to_build | awk '{$1=$1;print}'`
xcodebuild archive -"$filetype_parameter" "$file_to_build" -scheme "$ARCHIVE_SCHEME" -archivePath "$APP_NAME" -configuration Release
- name: Install Sentry CLI
run: |
# Check if sentry-cli is already installed
if ! command -v sentry-cli &> /dev/null; then
# Install sentry-cli
curl -sL https://sentry.io/get-cli/ | sh
else
echo "sentry-cli is already installed"
fi
- name: Upload dSYMs files to Sentry
run: |
sentry-cli debug-files upload --auth-token ${{ secrets.SENTRY_AUTH_TOKEN }} \
--include-sources \
$GITHUB_WORKSPACE/$APP_NAME.xcarchive/dSYMs
- name: Create IPA file
env:
EXPORT_OPTIONS_PLIST: ${{ secrets.EXPORT_OPTIONS_PLIST_BASE64 }}
run: |
EXPORT_OPTIONS_PLIST_PATH=$RUNNER_TEMP/ExportOptions.plist
echo -n "$EXPORT_OPTIONS_PLIST" | base64 -d -o $EXPORT_OPTIONS_PLIST_PATH
xcodebuild -exportArchive -archivePath $GITHUB_WORKSPACE/$APP_NAME.xcarchive -exportPath $RUNNER_TEMP/build -exportOptionsPlist $EXPORT_OPTIONS_PLIST_PATH
mv "$RUNNER_TEMP/build/Falling Sky.ipa" $RUNNER_TEMP/build/$APP_NAME.ipa
- name: Upload to TestFlight
env:
API_KEY_BASE64: ${{ secrets.APPSTORE_API_PRIVATE_KEY }}
run: |
mkdir -p ./private_keys
echo -n "$API_KEY_BASE64" | base64 --decode -o "./private_keys/AuthKey_${{ secrets.APPSTORE_API_KEY_ID }}.p8"
xcrun altool --validate-app -f ${{ runner.temp }}/build/${{ env.APP_NAME }}.ipa -t ios --apiKey ${{ secrets.APPSTORE_API_KEY_ID }} --apiIssuer ${{ secrets.APPSTORE_ISSUER_ID }}
xcrun altool --upload-app -f ${{ runner.temp }}/build/${{ env.APP_NAME }}.ipa -t ios --apiKey ${{ secrets.APPSTORE_API_KEY_ID }} --apiIssuer ${{ secrets.APPSTORE_ISSUER_ID }}