ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
XCTestで想定される失敗の容認
優れたAppを構築する上で、テストは非常に重要な要素です。優れたテストは、リリース前に重要な問題を追跡し、ワークフローを改善し、リリース時に高品質な体験を提供するのに役立ちます。ただし、すぐに解決できない問題については、XCTestでは、XCTExpectFailureを使用して問題の背景をわかりやすく説明することができます。このAPIがどのように機能するのか、その厳密な動作、そして新たな問題の特定をさらに効率化するためにテストのS/N比を向上させる方法について確認します。
リソース
関連ビデオ
WWDC22
WWDC21
-
ダウンロード
♪ (XCTestで想定される失敗の容認) こんにちは 「XCTestで想定される失敗の容認」 へようこそ 私はWilです このセッションでは プロジェクト のテストを実行するときに 取得するデータを改善する 方法について説明します まず最初に なぜコードをテストするのかを 考えてみましょう もちろん ハイレベルでは 製品の品質を保証する方法です しかし もっと具体的に言うと バグを発見するのは出荷前であり 出荷後ではありません テストは投資です テストの作成 実行 および 保守にはリソースが必要です どんな投資でもそうですが コストを最小限に抑えリターン を最大化したいと考えています このセッションでは メンテナンスコストを削減する為の ツールについて説明します 保守については 主にテストスイートで障害が 発生した場合の 対処方法について説明します 合格したテストが不合格になり 始めると それは新しい貴重な情報になります これは 製品の欠陥 テスト自体の問題 または依存関係の1つ つまりすべてのフレームワークの 問題のいずれかを示します その上に製品が置かれている サブシステム 問題のタイプに関係なく 障害が登録されると 同じ障害の後続のレポートは すでに持っている 情報を表すため 非常に価値が 低くなります 理想的には 新たに障害が発生した場合は迅速に トリアージおよび修正されます しかし チームが問題をすぐに 解決できない 場合があります つまり 障害は新しい情報の貴重な 一部ではなく ノイズが多く 気が散るものになります テストの既知の失敗がすぐに 解決できない場合 ノイズを管理するために使用できる ツールは何ですか? 考えられる2つのアプローチは 無効化とスキップです これらのツールのトレードオフを 検討してから 最適なツールとこのセッションの トピックについて説明します XCTestのExpectedFailures API Xcodeを使用するとテストプラン 又はスキーム内で試験を無効にでき これは既知のテストの失敗に 使用でき テストコードが引き続き コンパイルされるという 利点があります ただし コードは実行されないため テストレポートには表示されません 可視性の低下により 解決が必要な問題として 追跡することが困難になります この機能 どのテストを有効または無効に するかを選択する機能 が優れているのは 特定の目的のために テストの集合をキュレート するためです しかし これが既知の障害に対処 する最善策であることは決してない XCTSkipは失敗したテストを 管理するもう1つの方法です この方法では コードは テストとともに ビルドされ続けるだけでなく XCTSkipが呼び出されるまで 実行されます つまり テストレポートに 含まれているため 問題をより明確に把握できます ただし すべてのテストが 実行されるわけではありません つまり 新しい問題や既存の問題に 対する変更という形で 潜在的に有用な情報を 失うことになります XCTSkipは 特定の OSバージョンや デバイスタイプが必要な場合など 設定に基づくテストの制限を 管理するための優れたツールです この例では iPad上で実行されていない テストはスキップされます XCTExpectFailure は 既知の障害を管理するために 特別に設計された XCTestの関数群です Swiftには さまざまなユースケースに対応する 多数のオーバーロードがあり Objective-Cは複数の 異なる機能を 備えた同じ機能を提供する このAPIを使用すると テストは正常に実行されますが 結果は次のように変更されます テストの失敗は 予想される 失敗として報告されます そのテストを含むテストスイート での失敗は もちろん他のテストが 失敗しない限り 合格として報告されます これにより 障害によって 発生するノイズが排除され テストで他の問題が 発生していないかどうかを 確認しやすくなります もちろん ノイズを抑制しても 根本的な問題は解決しません そのため追跡しやすくするために APIには失敗の理由が必要です このストリングはコード内の 問題を文書化し 課題追跡システムのURLを 埋め込むこともできます XcodeのテストレポートUIは 通常の失敗や スキップされたテストと同じように 予想される失敗を示します マウスオーバーすると 失敗理由にURLが含まれて いる場合は リンクにジャンプするための 課題追跡ボタンが表示されます これがどのように機能するか 見てみましょう ここでは VendorAccount クラスの単体テストを含む簡単な プロジェクトを紹介します テストを実行して テストが終了したら 片方が不合格で もう片方が 合格であることを確認します テストごとに1つずつ 3つのテスト結果 アイコンが表示されます 失敗したテストには赤のX 合格したテストには緑のチェック テストスイートには1つのチェック スイート内のテストの 1つが失敗したため 赤いXが表示されるのでスイート 自体が失敗したと考えられます 次に 失敗したテストの最初に XCTExpectFailure の呼び出しを追加します 失敗の理由は 私がこの失敗を追跡するために ファイルしたバグを参照する URLで始まることがわかります テストを再実行して 結果にどのような 影響があるかを確認します OK 失敗したテストの赤い Xアイコンが 予期される失敗の インジケータであるグレーの Xに変わります さらに興味深いのは テストスイートのアイコンが 赤いXから緑のダッシュに 変わったことだ このアイコンは テストスイートが混合状態で 合格したことを示します これは 1つ以上のテストが 合格しなかったが スキップされたことを意味します または予期される失敗です これが 失敗したテストを処理するために XCTExpectFailure を使うことの容易さです では APIについて 詳しく見ていきましょう
XCTExpectFailure を使用する際の最初の考慮事項は どのAPIバリアントを 呼び出すかです 2つの方法があります ステートフルなアプローチでは XCTExpectFailure を呼び出し その後のテストでの 失敗は期待通りに扱われる あるいは XCTExpectFailure に渡されるクロージャの中で 失敗したコードを ラップするスコープアプローチを 使用することもできます いくつか例を見てみましょう これは 私のプロジェクト内の 関数を呼び出す 非常に単純なテストです 関数が trueを返さなくなったため テストが失敗し始めます ここでは デモで行ったように ステートフルな期待障害 アプローチを 使用している様子を示します 別の方法として 失敗したコードをクロージャで ラップして XCTExpectFailure への呼び出しを続けるスコープ アプローチを使用できます これは クロージャ外のコードでの 障害が正常に報告されることを 意味します このAPIはネストも サポートしています つまり 別の呼び出しからの クロージャの内部を含めて テストでAPIを複数回 呼び出すことができます これは テストライブラリコードで APIを使用する場合の 重要な考慮事項です たとえば 一般的なユーティリティ関数が 失敗し始めると多くのテストが 影響を受ける可能性があります その中には別の問題ですでに XCTExpectFailure を使用しているテストもあります 失敗が XCTExpectFailureへの ネストされた呼び出しの コンテキストで発生した場合 問題は最初に最も近い呼び出し サイトにマッチされ マッチ機構によって拒否された場合 次の呼び出しなどに XCTExpectFailureへの 呼び出しのスタック セマンティクスで渡される このため コードを共有する場合は クローズベースのAPIを 使用してテスト状態への 影響を制限することをお勧めします 次に考慮すべきことは 問題にどの程度正確に 対応するかである デフォルトでは 影響を受けるスコープ内のすべての 障害がキャッチされますが 問題一致フィルタを 指定することによって より選択的に行うことができます この例では XCTExpectedFailure 型のオブジェクトを作成します issueMatcher のオプションと定義 matcherには 失敗の詳細を含むXCTIssue オブジェクトが渡されるので その情報に完全にアクセスして 一致するかどうかを判断できます 照合側が失敗を拒否した場合 予想される失敗として 処理されません これはテスト対象のコードに 新しい問題が発生したことを 検出するのに役立ちます optionsオブジェクトには 特定の構成で予想される障害を 無効にするために 使用できるプロパティもあります 例えば 私のテストは macOSではパスするが iOSでは失敗するかもしれない のでiOSでは失敗だけを期待する これを実現するために オプションを使用して予想される 障害を無効にしますが それが不要なプラットフォームの 場合に限ります では期待していた失敗が起こら なくなったらどうなるのだろうか? 通常これは根本的な問題が 解決されたことを意味しますが これは素晴らしいことです しかしXCTExpectFailureは どのように動作するのでしょうか? それでもAPIを呼び出していて エラーが発生していない場合は 新しく明確なエラーが生成されます これを 「unmatched expected failure」 と呼び XCTExpectFailureのデフォルトである 厳密な動作の一部です この動作は APIへの不要な 呼び出しを削除するように求める プロンプトを表示することで コードを維持するのに役立ちます しかし 一部の時間だけ失敗する テストについてはどうでしょうか テストが失敗することもあれば 失敗しないこともあります これらは2つのカテゴリに分類され 最初のカテゴリは決定論的であり 環境または特定の プラットフォームでのみ 失敗するテストの 以前の例のような他の 既知の条件を含みます 一方 一部の障害は本質的に 非決定的です これらは タイミングの問題 信頼できない順序依存性 または同時実行性の バグによって発生する 可能性があります 非決定的な失敗の場合 厳密な動作は役に立ちません ノイズを発生させるだけです 繰り返しますが optionsオブジェクトは これを制御する方法を提供します isStrictフラグは既定値で trueに設定されていますが オフにすることができます この場合 XCTExpectFailureが 失敗を検出しなければ テストは成功する Swiftでは XCTExpectFailureへの 直接パラメータとして厳密な 動作を指定することもできます 厳密な動作を無効にすることは プロジェクト内の不安定なテストや 不確定なテストを処理する ための優れた方法です 余談ですが 不確定なエラーを調査する必要が ある場合にはXcodeを使えば 簡単にテストを複数回実行する ことができテストが失敗した場合や その他の条件が満たされた場合に テストを停止することができます これは 不安定なテストの失敗を 追跡するのに非常に役立ちます 詳細については セッション 「テストの繰り返しによる 信頼性の低いコードの診断」 をご覧ください これがXCTExpectFailure です テストスイートの結果のシグナル 対ノイズを改善するための XCTestのAPI これにより 新しい問題をより効率的に特定でき コードの品質が向上します ご覧いただき ありがとうございました ♪
-
-
3:31 - XCTSkip unless device is iPad
try XCTSkipUnless(UIDevice.current.userInterfaceIdiom == .pad, "Only supported on iPad")
-
4:31 - XCTExpectFailure
XCTExpectFailure("<https://dev.myco.com/bugs/4923> myValidationFunction is returning false")
-
7:14 - Scoped XCTExpectFailure
XCTExpectFailure("<https://dev.myco.com/bugs/4923> fix myValidationFunction") { XCTAssert(myValidationFunction()) }
-
8:34 - XCTExpectFailure with issue matcher
let options = XCTExpectedFailure.Options() options.issueMatcher = { issue in return issue.type == .assertionFailure } XCTExpectFailure("<https://dev.myco.com/bugs/4923> fix myValidationFunction", options: options)
-
9:03 - Disable XCTExpectFailure for some platforms
let options = XCTExpectedFailure.Options() #if os(macOS) options.isEnabled = false #endif XCTExpectFailure("<https://dev.myco.com/bugs/4923> fix myValidationFunction", options: options) { XCTAssert(myValidationFunction()) }
-
10:39 - Disable strict XCTExpectFailure behavior via options
let options = XCTExpectedFailure.Options() options.isStrict = false XCTExpectFailure("<https://dev.myco.com/bugs/4923> fix myValidationFunction", options: options) { XCTAssert(myValidationFunction()) }
-
10:53 - Disable strict XCTExpectFailure behavior via parameter
XCTExpectFailure("<https://dev.myco.com/bugs/4923> fix myValidationFunction", strict: false) { XCTAssert(myValidationFunction()) }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。