ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
XCTIssueを使用してテストの失敗をトリアージする
テストの失敗を役立たせましょう:Xcodeでの最新のテスティングAPIを使い、キャッチされていない問題をトリアージし分析する方法をお伝えします。テストワークフローを簡単にする方法、最高品質の製品を提供するのに役立つであろう失敗をコンテキストに組み込む方法について紹介します。 よりよいトリアージをするためにテストをデザインする方法に関しては、“Write tests to fail”をご覧ください。 Xcodeのテストワークフローに関する最新の改善情報に関しては、 “Get your test results faster”、“Handle interruptions and alerts in UI tests”、“XCTSkip your tests”をご覧ください。
リソース
関連ビデオ
WWDC20
-
ダウンロード
こんにちは WWDCへようこそ “XCTIssueを使用して テストでの失敗をトリアージする” 私はウィル Xcodeのtestingおよびautomation エンジニアです テスト失敗時の検証に役立つ 新しいAPIや改良点について説明します テストスイートを管理するためには 失敗の検証がとても重要です 原因の究明に時間がかかると リリースに間に合わず バグを含んだままの製品になるかもしれません 進行中のプロジェクトでは コードの変更がテストの失敗原因になり得ます 失敗した時は こんな疑問が浮かぶでしょう 何が どのように どうして失敗したのか 何より ソースコードの どこで失敗が起きたのか Xcode 12では APIを追加し テスト失敗のレポートUIを拡張 効率的に疑問の答えを導き出します こうした答えが とても重要なことから コーディングのパターンだけを特集した セッションがあります “Write Tests to Fail”をご覧ください
今回のセッションは4つの項目に分けました Swiftエラーやリッチな失敗オブジェクト スタックの呼び出し そしてワークフローです 順を追って見ていきますが まず Xcode 12での失敗表示を確認しましょう
私は3歳の娘と一緒に “PlayGarden”というプロジェクトで 裏庭にある植物やおもちゃ 家具をすべて管理しています 3歳とはいえ 娘はテスト駆動開発を理解し すべてのビュークラスで エレメントのテストができています 最近 コードの重複が判明したので ユーティリティをリファクタリングしました テストを1つ実行します 失敗要因を入れているので どう表示されるか見てみましょう
すぐにテストの失敗が表示され 注釈はグレーでコメントされています これは 注釈行のすぐ下の呼び出しで 失敗が発生したということです Issue Navigatorで 更に検証しましょう
Issue Navigatorでは失敗だけでなく テストコードのコールスタックも確認できます フレームをクリックすると 失敗位置へ移動するので 赤で表示された失敗ポイントを 見ることができます 他のフレームをクリックすると ソースエディタには 失敗が確認された位置から テストポイントまでのコードが表示されます 失敗前後のコンテキストを 素早く理解できるので 解決に必要な時間が短縮されます では テストレポートに切り替えてみましょう これは 検証に優れた方法で 連続的な統合システムから 結果をバンドルする際に有効です
直近のテストレポートには 失敗したテストが赤く表示され 展開すると 失敗したファイル 行やメッセージが見られます 更に下を見てみましょう Issue Navigatorと 同じコールスタックが表示されました フレームにカーソルを合わせると 右側に2つのボタンが現れます 1つ目は ソースコードへ移動する ジャンプボタンです
レポートに戻り 2つ目のボタンを確認します Xcode 12では このアシスタントボタンで 隣にエディタを開き 参照するソースを表示します テストレポートとソースコードを 並べて確認でき Issue Navigatorと同様に 失敗を検証できます
Xcode 12では このように失敗を確認します 続いて テストのSwiftエラーについてです
Swiftのコーディングパターンに対応するには テスト関数をスローすることで可能です テストがスローすると エラーを元に失敗メッセージが作られます つまり エラーの処理には これまでの定型文ではなく テストは このように書かれ シンプルになりました 最近まで XCTAssertでは 失敗位置のソースコードや ファイル 行の表示ができませんでした そのため今でも 定型文を使う開発者もいます しかし Swiftランタイムの改良により iOSやtvOS 13.4 macOS 10.15.4では スローされたエラーとソースコードの位置が 分かるようになりました これで他の処理コードなしで エラーのコンテキストが得られます ソースコードの改良に加え APIも追加し テストのsetUpとtearDownも便利になりました 追加したAPIは 以前のsetUpとtearDownの変形です
新しいsetUpWithErrorは 元々のsetUp前に実行され tearDownWithErrorは 元々のtearDown後に呼び出されます 2つのメソッドは 新しいテストファイルにあります これらのAPIは 同じテスト内で使えますが 古いメソッドを維持する場合を除き 新たなメソッドに切り替えることを推奨します 次は リッチな失敗オブジェクトについてです XCTestは 失敗を4つの値として記録します メッセージ ファイルパス 失敗が記録された行番号 そして 失敗の予想を示すフラグです 予想された失敗は XCTAssertで記録されます 予期せぬ失敗とは スローされた例外をXCTestが捉えることです
値はXCTAssertから recordFailure APIに渡され 失敗を記録し Xcodeに伝えられていました
Xcode 12では XCTIssueで 異なる値をカプセル化しています 加えて 新しい失敗データには 明示型タイプの計算法 詳細な記述 内在するエラーと添付があります
XCTAttachmentは 任意のデータをキャプチャするAPIで テスト自体か XCTContextによるアクティビティに添付します XCTIssueにも追加できるので カスタム診断を テストの失敗とひも付けられます XCTestCaseには 失敗を記録する新たなAPIがあり record(_issue:)は すべてのXCTAssertで使われます 直接呼び出しやオーバーライドも可能です recordFailure APIは廃止されました recordFailureを直接呼び出しているか オーバーライドしているなら 早めに record(_issue:)へ更新してください record(_issue:)を使う場合 XCTIssueをどう変更するのでしょう Swiftでは letでなくvarで宣言すると issueを変えられます Objective Cでは XCTIssueが変更できず NS mutableCopyに従います XCTIssueは多様な方法で 失敗のトリアージを向上 コールスタックも さまざまです 最初にテストの失敗について 重大な疑問は“どこで”だと言いました それを探すために データは常にファイルパスと行番号を含み コンパイラトークンを使い ビルド時にキャプチャされます
シングルソースコードは 単純なテスト向きですが 1つ以上のテストで共有される関数には あまり有効ではありません こちらが その例です 同じ関数を呼び出す2つのテストがあります 失敗がある場合 注釈がアサーションの横に現れますが 失敗のマークがあることで テストメソッドが混乱します そして 失敗位置を示す情報は これ以上ありません ヘルプ機能でソースの位置を キャプチャすれば改善できるので XCTAssertを呼び出す時に使用します 表示とテストメソッドは向上しますが ヘルプ機能に複数のアサーションがあると 不明確さが残ります
XCTIssueなら コールスタックを キャプチャしシンボル化できるので 複雑なテストコードの失敗に対する コンテキストが増えます
コールスタックをキャプチャした 同じ失敗の例です 前のデモと似ていますが ここでは“どこで”の疑問に焦点を置きます テストメソッドのグレーの注釈が 失敗の発生行を示し ヘルプメソッドの赤い注釈は 失敗自体を表示します 位置を伝える追加のコードや 注釈位置を選択する必要もないので 労力なく簡単に結果が得られます
最後に 新たなAPIによる 進歩的なワークフローを紹介します XCTIssueインスタンスのrecord(_issue:)で カスタムアサーションの実装が可能です データの正当性を立証するアサーションを 記録したissueに添付として含めます
issue作成時は varを使います 他のコードが構造体へ変更するからです 情報は より長い初期化子に渡せますが この方が読みやすくなると思います
次に データをissueへ添付しましょう データはXcodeのテストレポートに 失敗と共に表示されるので トリアージの間に調査し なぜ失敗したのか判断できます カスタムアサーションが 呼ばれた位置をキャプチャ 明確な表示のためですが 必須ではありません 失敗そのものの理解には あまり役に立たないからです issueを記録しXcodeへ送るため record(_issue:)を呼び出します
もう1つのワークフローでは record(_issue:)をオーバーライドし テストクラスで記録された失敗を 監視や抑制 または修正します これは失敗時に必ず通過するメソッドで オーバーライドは テストクラスのアウトプットを制御します 最初の例では監視のために record(_issue:)をオーバーライドしました superを呼び出し issueの記録を継続させることが重要です XCTestObservationCenterを使い 監視もできますが ここでのアプローチは 1つのクラスで監視する場合です superが呼び出されなければ issueは抑制されていて 記録が継続されず ログもなく Xcodeに報告もされません
record(_issue:)をオーバーライドする 一般的な理由は修正です このパターンのように添付を加えると 診断に大きく役立ちます ここでは簡単な文字列だけですが APIは さまざまな追加が可能です それでは 重要な点をまとめましょう テストの失敗におけるトリアージは 非常に重要です コールスタックは 失敗に関わるコードの位置を 見つけやすくします テストコードを より自然なパターンで書けるので コードの再利用や他の作業にも注力できます XCTIssueは添付にも対応するので カスタム診断のデータを追加し テスト失敗時の疑問を解決しましょう ありがとうございました
-
-
9:52 - Implement a custom test assertion using XCTIssue
func assertSomething(about data: Data, file: StaticString = #filePath, line: UInt = #line) { // Call out to custom validation function. if !isValid(data) { // Create issue, declare with var for mutability. var issue = XCTIssue(type: .assertionFailure, compactDescription: "Invalid data") // Attach the invalid data. issue.add(XCTAttachment(data: data)) // Capture the call site location as the point of failure. let location = XCTSourceCodeLocation(filePath: file, lineNumber: line) issue.sourceCodeContext = XCTSourceCodeContext(location: location) // Record the issue. self.record(issue) } }
-
11:12 - Override record(_ issue:) for observation
override func record(_ issue: XCTIssue) { // Observe, introspect, log, etc.: if shouldLog(issue) { print("I just observed an issue!") } // Don't forget to call super! super.record(issue) }
-
11:30 - Override record(_ issue:) to suppress failures
override func record(_ issue: XCTIssue) { // If you don't want to record it, just return. if shouldSuppress(issue) { return } // Otherwise pass it to super. super.record(issue) }
-
11:39 - Override record(_ issue:) to add an attachment
override func record(_ issue: XCTIssue) { // Redeclare using var to enable mutation. var issue = issue // Add a simple attachment. issue.add(XCTAttachment(string: "hello")) // Pass it to super. super.record(issue) }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。