狠狠撸

狠狠撸Share a Scribd company logo
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
iOSDC Reject Conference days2
2016/08/31(Wed)
平田敏之@DeNA
iOSアプリ開発のテスト環境
- テストをはじめる最初の一歩 -
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
自己紹介
? 平田 敏之
? 経歴
? GWの開発 → ホムペサービスの開発、iOSアプリの開発 → SWET
? SWET(Software Engineer in Test)
? ミッション
? DeNAサービス全般の品質向上
? DeNAエンジニアの開発生産性向上
? 事業サポートチーム / テスト基盤チーム
? 私がやっていること(の一部)
? クライアントアプリ周りのテスト戦略、自動テストの開発
? CI/CD環境整備
? テスト基盤環境の開発
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
本発表のゴール
? 皆さんが、自らのアプリでテストを書き始める
? そして、テストについて苦悩する苦悩する
? 苦悩したことを勉強会などで共有する
約1年後
? iOSDC2017にテスト関係で発表を申し込む
? 誰か1人でもiOSDC2017でテスト関係で発表する
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
今日、皆さんに話すこと
? iOSアプリ開発でテストってどうしていますか?
? E2Eテストしていますか?
? マニュアルテストにまかせていませんか?
? テストは(基本的に)書いたほうが良い
? しかし、iOSアプリ開発におけるテストって「何ができるのか」「何からはじめ
たら良いか」分かっていなかったりしませんか?
? iOSアプリ開発においても(以前より)色々できるようになってきています
? そこで、どのようなものがあるのか(の一部)を皆さんに紹介します
? 色々とありますが、「コレだ」というベストのものは無く、プロジェクト
に応じて利用するものは変えたほうが良い
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
今日の発表の流れ
? 最近のiOSアプリ開発のテスト環境についての紹介
1. テストを書くために
? UIテスティングフレームワーク
2. 書いたテストを動かすために
? 実行環境
3. 継続的にテストを動かし続けるために
? CI環境
? テスト環境の例を紹介
? テスト環境があるときのリリースフローの例を紹介
? まとめ
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
本日話さないこと
? 以下については話しきれませんので省略
? 自動テストのテスト戦略
? 自動テストの書き方
? UIテストを書き続けるつらみ
? Appleのつらみ
? CI環境のつらみ
? ここは少々Kyobashi.swift#2で話しました
ここらへんは別の機会に
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
iOSアプリ開発をとりまくテスト環境(の一例)
UIテスティングフレームワーク 実行環境 CI
XCUITest AWS Device Farm Jenkins
EarlGrey Xamarin Test Cloud CircleCI
Appium iOSシミュレーター
iOS実機
Androidに比べるとツライ面もあるが以前よりは良くなっている
※他にも多数あります※
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
UIテスティングフレームワーク
一番注意して選ぶべきところ
別に1つで全てのテストを書かなくても良いのです
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
UIテスティングフレームワーク
? プロダクトコードと一緒
? XCUITest
? Apple純正
? OS ver: iOS9 ?
? EarlGrey
? Google製
? プロダクトコードとは別(アプリがあればOK)
? Appium
? iOS / Androidに対応
? RspecやJUnitなどが使える
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
サンプルアプリ x UIテスティングフレームワーク
[Swiftで書かれた簡単なアプリ]
? 機能説明
? 上記のタブをタップしたら下部の
ページが対応するページに遷移する
今回のサンプルテストは以下
? Action:
? 上部の2をタップ
? Result:
? 下部のページが2と書かれたページに遷
移する
サンプルアプリ
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
XCUITest
import XCTest
class SampleUITest: XCTestCase {
private let app: XCUIApplication = XCUIApplication()
override func setUp() {
super.setUp()
continueAfterFailure = false
app.launch()
}
override func tearDown() {
super.tearDown()
app.terminate()
}
//testというprefixが必要
func test上部の2のタブをタップするとページ2に遷移する() {
let pageNumber = “2”
app.scrollViews.otherElements.staticTexts[pageNumber].tap()
XCTAssertTrue(app.scrollViews.elementBoundByIndex(1).staticTexts[pageNumber].exists)
}
}
サンプルコード
ユニークなidを利用せずにテス
トコードを書いた場合の例
.existsは、その要素が存在するか
どうかでtrue/falseが返ってくる。
※従ってhidden=trueでもtrueが
返ってくる。
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
EarlGrey
import XCTest
class SampleUITest: XCTestCase {
let earlgray = EarlGrey()
override func setUp() {
super.setUp()
}
override func tearDown() {
super.tearDown()
}
//testというprefixが必要
func test上部の2のタブをタップするとページ2に遷移する() {
let pageNumber = 2
let pageLabel= “label-” + pageNumber
earlgray .selectElementWithMatcher(grey_accessibilityLabel(pageNumber )).performAction(grey_tap())
earlgray .selectElementWithMatcher(grey_accessibilityLabel(pageLabel)).assertWithMatcher(grey_sufficientlyVisible())
}
}
サンプルコード
SetupはCocoaPodsを使っておこなうことを推奨。
基本的に要素にuniqueなidをふることを推奨している。
(テストを書く上では当然な行為だと思います)
要参考
https://github.com/google/EarlGrey/blob/1.0.0/docs/api.md
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
Appium
describe “画面遷移テスト” do
before(:each) do
end
after(:each) do
end
let(:pageNumber) { “2” }
it “上部の2のタブをタップするとページ2に遷移する” do
find_element(:name, pageNumber).click()
pageTitle= find_element(:name, “label” + pageNumbe).text
expect(pageTitle).to eq(pageNumber)
end
end
サンプルコード(Rspec)
AppiumはXCTestやEarlGreyとはアー
キテクチャーが異なる点に注意
※左のコード以外にも必要なコードがあります。
上記のサンプルコードはRspecなので、describe/itなどが使えます。
要素の取得には、accessibilityIdentifierやaccessibilityLabelやXpathを使用しておこないます。
上記の例では、accessibilityLabelを使用しています。
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
UIテストを書くときのTips
? iOSシミュレーターのAcccessibility Inspectorは便利
? 要素にuniqueなidは必須
? 無くても書けるが後で苦労する
? テスト名は分かりやすくする
? 無理して英語にしなくても良い
? 頑張り過ぎない
? 単にスクリーンショットを撮るレベルにするのも1つの手
? CIに載せておいて、結果が全員が見えるようにしておく
? 手元だけで動く状態だと確実に廃れていく
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
自動テストの実行環境
Androidに比べて非常に面倒なのがコレですよね
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
自動テストの実行環境(1/2)
? AWS Device Farm
? 利用できるテスティングフレームワークが限られている
? Appium Java Junit / Java TestNG / Python
? Calabash
? UI Automation
? XCTest
? XCUITest
? Xamarin Test Cloud
? Cucumber(C# / Ruby)
? iOSシミュレーター
? CI環境であるMac上で起動
? あくまでもシミュレーター
? (自前の)iOS実機
? CI環境であるMacに接続している必要がある
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
自動テストの実行環境(2/2)
? AWS Device Farm
? ? 定額 250 USD/デバイススロット/月
? ? 0.17 USD/分
? Xamarin Test Cloud
? ? ?178,200(税抜き)/年間 → 1日1時間 / 1デバイス
? ? ?682,200(税抜き)/年間 → 1日5時間 / 3デバイス
? iOSシミュレーター
? シミュレーターだから..
? (基本的に)mac1台につき1iOSシミュレーター
? (自前の)iOS実機
? CI環境に接続されたiOS実機を用いる形
? Jenkinsなどのようなオンプレミスでないと無理
? 資産をいかすならコレが良いのだけど運用がなかなか..
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
CI環境
プロジェクトの状況に応じて決めるのが良い
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
CI環境
? Jenkins(オンプレミス)
? ど定番だが学習コストや運用コストがかかる
? なんでも出来るがJenkinsおじさんも出来やすい
? 見た目に抵抗がある人も…
? blueocean pluginで多少は良くなる
? LTS 2.7.2 (https://jenkins.io/changelog-stable/)
? CircleCI(クラウド)
? さくっと簡単に利用できる優れもの
? ただしiOSは有料になってしまいました…
? Bitriseというのもあります
? 痒いところに手が届かない
? Enterprise版もある
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
Jenkins 2.7.1(LTS) + blueocean plugin
Jenkinsも進化しています
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
今回紹介するテスト環境一式
Jenkins x XCUITest x iOSシミュレーター
※この環境だとさくっとすぐにはじめられます※
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
iOSアプリ開発のテスト環境の例(1/2)
lane :test do
scan(
sdk: 'iphonesimulator',
device: ENV[“device”],
workspace: "sample-ios-swift.xcworkspace",
scheme: "sample-ios-swift",
configuration: "Debug",
output_directory: 'test-report/',
buildlog_path: 'test-report/',
output_types: 'html, junit',
clean: true
)
end
Jenkins x XCUITest x iOSシミュレーター
XCUITest
? テストの実行はfastlane/scanを使用
? 実行するdeviceは環境変数で渡す
? テストの結果はJUnit形式、htmlファイルで出力
Jenkins (Mac上で動作)
Jenkinsのjobの設定
? ビルドパラメータを用意
? 対象branch
? ソースコード管理(Git)でのBranch Specifierで利用する
? 対象device
? groove scriptで動的表
? Dynamic Parameter pluginを利用
? xcrun simctl listコマンドを使ってiOSシミュレーター一覧は取得可能
?※実機の場合はmobiledeviceを利用するとIDも取得できる
? ビルドのシェルの実行でテストを実行
? fastlane test
? 出力結果を集計して表示
? JUnit pluginを利用
? 出力結果をslackにpost
? slack pluginを利用
fastlaneの例
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
iOSアプリ開発のテスト環境の例(2/2)
? Jenkinsにおけるテスト結果の表示
? 右画像のように表示される
? 全てが成功した場合の例
? Jenkinsにおけるテスト結果の通知
? Slackに下画像のように通知される
? テストが落ちた場合は、mentionが飛ばされる
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
テスト環境がある場合のリリースフロー例
1. WIPでPRを出す
2. 機能を実装する
3. 上記機能のテスト観点を記述しレビュー依頼
? 主にQA担当者がチェックする
? これにより手動で検証する箇所を把握する
4. 上記機能のテストコードを実装
5. PR中においてはテストフレーズでテストを動かす
? 例) build this please: アプリをビルドする
? 例) test this please: 自動テストを実行する
? これを詠唱のように長くしてみようというアホな案を出したが、当然却下された..
6. コードのレビューはテストが全て通った後におこなう
7. 全レビュー後、merge
8. QA検証へ
? 自動テストで担保している箇所は特にやらない
Copyright ? DeNA Co.,Ltd. All Rights Reserved.
まとめ
? テスト周りは以前より色々とできるようになりました
? 開発環境と同様にテスト環境を整えるのはプロダクトにおいて重要
? iOSアプリ開発のテスト環境を用意してみましょう
? 環境を変えやすいようにしつつ作るのがベターです
? そして、テストをどんどん書いてみましょう
? その先の苦悩は別の勉強会で

More Related Content

iOSアフ?リ開発のテスト環境 - テストをはじめる最初の一歩 -

  • 1. Copyright ? DeNA Co.,Ltd. All Rights Reserved. iOSDC Reject Conference days2 2016/08/31(Wed) 平田敏之@DeNA iOSアプリ開発のテスト環境 - テストをはじめる最初の一歩 -
  • 2. Copyright ? DeNA Co.,Ltd. All Rights Reserved. 自己紹介 ? 平田 敏之 ? 経歴 ? GWの開発 → ホムペサービスの開発、iOSアプリの開発 → SWET ? SWET(Software Engineer in Test) ? ミッション ? DeNAサービス全般の品質向上 ? DeNAエンジニアの開発生産性向上 ? 事業サポートチーム / テスト基盤チーム ? 私がやっていること(の一部) ? クライアントアプリ周りのテスト戦略、自動テストの開発 ? CI/CD環境整備 ? テスト基盤環境の開発
  • 3. Copyright ? DeNA Co.,Ltd. All Rights Reserved. 本発表のゴール ? 皆さんが、自らのアプリでテストを書き始める ? そして、テストについて苦悩する苦悩する ? 苦悩したことを勉強会などで共有する 約1年後 ? iOSDC2017にテスト関係で発表を申し込む ? 誰か1人でもiOSDC2017でテスト関係で発表する
  • 4. Copyright ? DeNA Co.,Ltd. All Rights Reserved. 今日、皆さんに話すこと ? iOSアプリ開発でテストってどうしていますか? ? E2Eテストしていますか? ? マニュアルテストにまかせていませんか? ? テストは(基本的に)書いたほうが良い ? しかし、iOSアプリ開発におけるテストって「何ができるのか」「何からはじめ たら良いか」分かっていなかったりしませんか? ? iOSアプリ開発においても(以前より)色々できるようになってきています ? そこで、どのようなものがあるのか(の一部)を皆さんに紹介します ? 色々とありますが、「コレだ」というベストのものは無く、プロジェクト に応じて利用するものは変えたほうが良い
  • 5. Copyright ? DeNA Co.,Ltd. All Rights Reserved. 今日の発表の流れ ? 最近のiOSアプリ開発のテスト環境についての紹介 1. テストを書くために ? UIテスティングフレームワーク 2. 書いたテストを動かすために ? 実行環境 3. 継続的にテストを動かし続けるために ? CI環境 ? テスト環境の例を紹介 ? テスト環境があるときのリリースフローの例を紹介 ? まとめ
  • 6. Copyright ? DeNA Co.,Ltd. All Rights Reserved. 本日話さないこと ? 以下については話しきれませんので省略 ? 自動テストのテスト戦略 ? 自動テストの書き方 ? UIテストを書き続けるつらみ ? Appleのつらみ ? CI環境のつらみ ? ここは少々Kyobashi.swift#2で話しました ここらへんは別の機会に
  • 7. Copyright ? DeNA Co.,Ltd. All Rights Reserved. iOSアプリ開発をとりまくテスト環境(の一例) UIテスティングフレームワーク 実行環境 CI XCUITest AWS Device Farm Jenkins EarlGrey Xamarin Test Cloud CircleCI Appium iOSシミュレーター iOS実機 Androidに比べるとツライ面もあるが以前よりは良くなっている ※他にも多数あります※
  • 8. Copyright ? DeNA Co.,Ltd. All Rights Reserved. UIテスティングフレームワーク 一番注意して選ぶべきところ 別に1つで全てのテストを書かなくても良いのです
  • 9. Copyright ? DeNA Co.,Ltd. All Rights Reserved. UIテスティングフレームワーク ? プロダクトコードと一緒 ? XCUITest ? Apple純正 ? OS ver: iOS9 ? ? EarlGrey ? Google製 ? プロダクトコードとは別(アプリがあればOK) ? Appium ? iOS / Androidに対応 ? RspecやJUnitなどが使える
  • 10. Copyright ? DeNA Co.,Ltd. All Rights Reserved. サンプルアプリ x UIテスティングフレームワーク [Swiftで書かれた簡単なアプリ] ? 機能説明 ? 上記のタブをタップしたら下部の ページが対応するページに遷移する 今回のサンプルテストは以下 ? Action: ? 上部の2をタップ ? Result: ? 下部のページが2と書かれたページに遷 移する サンプルアプリ
  • 11. Copyright ? DeNA Co.,Ltd. All Rights Reserved. XCUITest import XCTest class SampleUITest: XCTestCase { private let app: XCUIApplication = XCUIApplication() override func setUp() { super.setUp() continueAfterFailure = false app.launch() } override func tearDown() { super.tearDown() app.terminate() } //testというprefixが必要 func test上部の2のタブをタップするとページ2に遷移する() { let pageNumber = “2” app.scrollViews.otherElements.staticTexts[pageNumber].tap() XCTAssertTrue(app.scrollViews.elementBoundByIndex(1).staticTexts[pageNumber].exists) } } サンプルコード ユニークなidを利用せずにテス トコードを書いた場合の例 .existsは、その要素が存在するか どうかでtrue/falseが返ってくる。 ※従ってhidden=trueでもtrueが 返ってくる。
  • 12. Copyright ? DeNA Co.,Ltd. All Rights Reserved. EarlGrey import XCTest class SampleUITest: XCTestCase { let earlgray = EarlGrey() override func setUp() { super.setUp() } override func tearDown() { super.tearDown() } //testというprefixが必要 func test上部の2のタブをタップするとページ2に遷移する() { let pageNumber = 2 let pageLabel= “label-” + pageNumber earlgray .selectElementWithMatcher(grey_accessibilityLabel(pageNumber )).performAction(grey_tap()) earlgray .selectElementWithMatcher(grey_accessibilityLabel(pageLabel)).assertWithMatcher(grey_sufficientlyVisible()) } } サンプルコード SetupはCocoaPodsを使っておこなうことを推奨。 基本的に要素にuniqueなidをふることを推奨している。 (テストを書く上では当然な行為だと思います) 要参考 https://github.com/google/EarlGrey/blob/1.0.0/docs/api.md
  • 13. Copyright ? DeNA Co.,Ltd. All Rights Reserved. Appium describe “画面遷移テスト” do before(:each) do end after(:each) do end let(:pageNumber) { “2” } it “上部の2のタブをタップするとページ2に遷移する” do find_element(:name, pageNumber).click() pageTitle= find_element(:name, “label” + pageNumbe).text expect(pageTitle).to eq(pageNumber) end end サンプルコード(Rspec) AppiumはXCTestやEarlGreyとはアー キテクチャーが異なる点に注意 ※左のコード以外にも必要なコードがあります。 上記のサンプルコードはRspecなので、describe/itなどが使えます。 要素の取得には、accessibilityIdentifierやaccessibilityLabelやXpathを使用しておこないます。 上記の例では、accessibilityLabelを使用しています。
  • 14. Copyright ? DeNA Co.,Ltd. All Rights Reserved. UIテストを書くときのTips ? iOSシミュレーターのAcccessibility Inspectorは便利 ? 要素にuniqueなidは必須 ? 無くても書けるが後で苦労する ? テスト名は分かりやすくする ? 無理して英語にしなくても良い ? 頑張り過ぎない ? 単にスクリーンショットを撮るレベルにするのも1つの手 ? CIに載せておいて、結果が全員が見えるようにしておく ? 手元だけで動く状態だと確実に廃れていく
  • 15. Copyright ? DeNA Co.,Ltd. All Rights Reserved. 自動テストの実行環境 Androidに比べて非常に面倒なのがコレですよね
  • 16. Copyright ? DeNA Co.,Ltd. All Rights Reserved. 自動テストの実行環境(1/2) ? AWS Device Farm ? 利用できるテスティングフレームワークが限られている ? Appium Java Junit / Java TestNG / Python ? Calabash ? UI Automation ? XCTest ? XCUITest ? Xamarin Test Cloud ? Cucumber(C# / Ruby) ? iOSシミュレーター ? CI環境であるMac上で起動 ? あくまでもシミュレーター ? (自前の)iOS実機 ? CI環境であるMacに接続している必要がある
  • 17. Copyright ? DeNA Co.,Ltd. All Rights Reserved. 自動テストの実行環境(2/2) ? AWS Device Farm ? ? 定額 250 USD/デバイススロット/月 ? ? 0.17 USD/分 ? Xamarin Test Cloud ? ? ?178,200(税抜き)/年間 → 1日1時間 / 1デバイス ? ? ?682,200(税抜き)/年間 → 1日5時間 / 3デバイス ? iOSシミュレーター ? シミュレーターだから.. ? (基本的に)mac1台につき1iOSシミュレーター ? (自前の)iOS実機 ? CI環境に接続されたiOS実機を用いる形 ? Jenkinsなどのようなオンプレミスでないと無理 ? 資産をいかすならコレが良いのだけど運用がなかなか..
  • 18. Copyright ? DeNA Co.,Ltd. All Rights Reserved. CI環境 プロジェクトの状況に応じて決めるのが良い
  • 19. Copyright ? DeNA Co.,Ltd. All Rights Reserved. CI環境 ? Jenkins(オンプレミス) ? ど定番だが学習コストや運用コストがかかる ? なんでも出来るがJenkinsおじさんも出来やすい ? 見た目に抵抗がある人も… ? blueocean pluginで多少は良くなる ? LTS 2.7.2 (https://jenkins.io/changelog-stable/) ? CircleCI(クラウド) ? さくっと簡単に利用できる優れもの ? ただしiOSは有料になってしまいました… ? Bitriseというのもあります ? 痒いところに手が届かない ? Enterprise版もある
  • 20. Copyright ? DeNA Co.,Ltd. All Rights Reserved. Jenkins 2.7.1(LTS) + blueocean plugin Jenkinsも進化しています
  • 21. Copyright ? DeNA Co.,Ltd. All Rights Reserved. 今回紹介するテスト環境一式 Jenkins x XCUITest x iOSシミュレーター ※この環境だとさくっとすぐにはじめられます※
  • 22. Copyright ? DeNA Co.,Ltd. All Rights Reserved. iOSアプリ開発のテスト環境の例(1/2) lane :test do scan( sdk: 'iphonesimulator', device: ENV[“device”], workspace: "sample-ios-swift.xcworkspace", scheme: "sample-ios-swift", configuration: "Debug", output_directory: 'test-report/', buildlog_path: 'test-report/', output_types: 'html, junit', clean: true ) end Jenkins x XCUITest x iOSシミュレーター XCUITest ? テストの実行はfastlane/scanを使用 ? 実行するdeviceは環境変数で渡す ? テストの結果はJUnit形式、htmlファイルで出力 Jenkins (Mac上で動作) Jenkinsのjobの設定 ? ビルドパラメータを用意 ? 対象branch ? ソースコード管理(Git)でのBranch Specifierで利用する ? 対象device ? groove scriptで動的表 ? Dynamic Parameter pluginを利用 ? xcrun simctl listコマンドを使ってiOSシミュレーター一覧は取得可能 ?※実機の場合はmobiledeviceを利用するとIDも取得できる ? ビルドのシェルの実行でテストを実行 ? fastlane test ? 出力結果を集計して表示 ? JUnit pluginを利用 ? 出力結果をslackにpost ? slack pluginを利用 fastlaneの例
  • 23. Copyright ? DeNA Co.,Ltd. All Rights Reserved. iOSアプリ開発のテスト環境の例(2/2) ? Jenkinsにおけるテスト結果の表示 ? 右画像のように表示される ? 全てが成功した場合の例 ? Jenkinsにおけるテスト結果の通知 ? Slackに下画像のように通知される ? テストが落ちた場合は、mentionが飛ばされる
  • 24. Copyright ? DeNA Co.,Ltd. All Rights Reserved. テスト環境がある場合のリリースフロー例 1. WIPでPRを出す 2. 機能を実装する 3. 上記機能のテスト観点を記述しレビュー依頼 ? 主にQA担当者がチェックする ? これにより手動で検証する箇所を把握する 4. 上記機能のテストコードを実装 5. PR中においてはテストフレーズでテストを動かす ? 例) build this please: アプリをビルドする ? 例) test this please: 自動テストを実行する ? これを詠唱のように長くしてみようというアホな案を出したが、当然却下された.. 6. コードのレビューはテストが全て通った後におこなう 7. 全レビュー後、merge 8. QA検証へ ? 自動テストで担保している箇所は特にやらない
  • 25. Copyright ? DeNA Co.,Ltd. All Rights Reserved. まとめ ? テスト周りは以前より色々とできるようになりました ? 開発環境と同様にテスト環境を整えるのはプロダクトにおいて重要 ? iOSアプリ開発のテスト環境を用意してみましょう ? 環境を変えやすいようにしつつ作るのがベターです ? そして、テストをどんどん書いてみましょう ? その先の苦悩は別の勉強会で