記事


終了テスト


テストプロセスを終了する可能性のある機能をテストするには、終了テストを使用します。


Swift 6.2+ Xcode 26.0+   Beta  





概観


あなたのコードには、precondition()fatalError()、または現在のプロセスを終了させる可能性のあるその他の関数の呼び出しが含まれている可能性があります。例えば:


extension Customer {
  func eat(_ food: consuming some Food) {
    precondition(food.isDelicious, "Tasty food only!")
    precondition(food.isNutritious, "Healthy food only!")
    ...
  }
}

この関数では、food.isDelicious または food.isNutritiousfalse の場合、前提条件が満たされず、Swift はプロセスを強制的に終了します。上記のような前提条件を検証し、あなたの関数が無効な入力を正しく catch していることを確認するための終了テストを記述できます。


注意

終了テストは、macOS、Linux、FreeBSD、OpenBSD、Windows で利用できます。


終了テストを作成するには、expect(processExitsWith:observing:_:sourceLocation:performing:) または require(processExitsWith:observing:_:sourceLocation:performing:) マクロのいずれかを呼び出します。


@Test func `Customer won't eat food unless it's delicious`() async {
  let result = await #expect(processExitsWith: .failure) {
    var food = ...
    food.isDelicious = false
    Customer.current.eat(food)
  }
}

マクロにあなたが渡すクロージャまたは関数の参照は、終了テストの 本体 となります。実行時に終了テストが実行されると、テストライブラリは現在のプロセスと同じ実行ファイルを持つ新しいプロセスを開始します。その後、現在のタスクは (await と同様に) 一時停止され、子プロセスが終了するまで待機します。


注意

終了テストは別の終了テスト内では実行できません。


親プロセスは終了テストの本体を呼び出しません。代わりに、子プロセスは終了テストの本体を main() 関数として扱い、直接呼び出します。


注意

本体は新しいプロセスの main() 関数として機能するため、親プロセスやその語彙コンテキストで発生する状態をキャプチャすることはできません。例えば、以下の終了テストは、終了テスト自体の外で宣言された変数をキャプチャするため、コンパイルに失敗します。

@Test func `Customer won't eat food unless it's nutritious`() async {
  let isNutritious = false
  await #expect(processExitsWith: .failure) {
    var food = ...
    food.isNutritious = isNutritious // ❌ ERROR: trying to capture state here
    Customer.current.eat(food)
  }
}

子プロセスが終了する前に本体が戻った場合、プロセスは main() が正常に戻ったかのように終了します。本体がエラーを throw した場合、Swift はそれを main() から throw されたかのように処理し、プロセスを強制的に異常終了させます。


終了条件を指定する


終了テストを作成するときは、ExitTest.Condition のインスタンスを渡して、子プロセスがどのように終了するかを指定します。


  • 終了テスト本体が実行を完了するか、正常終了する (例えば、C 標準ライブラリの exit(EXIT_SUCCESS) を呼び出す) ことを期待する場合は、success を渡します。

  • 本体によって子プロセスが異常終了することをあなたは期待するが、システムから報告される正確なステータスは重要でない場合は、failure を渡します。

  • 特定の終了コードまたはシグナルをチェックする必要がある場合は、exitCode(_:) または signal(_:) を渡します。

  • 子プロセスが終了すると、親プロセスは再開し、子プロセスの終了ステータスと、あなたが渡した想定終了条件を比較します。一致した場合、終了テストは成功します。一致しない場合、終了テストは失敗し、テストライブラリは問題を記録します。


    子プロセスからの出力を収集する


    expect(processExitsWith:observing:_:sourceLocation:performing:) マクロと require(processExitsWith:observing:_:sourceLocation:performing:) マクロは、子プロセスの状態に関する情報を含む ExitTest.Result のインスタンスを返します。


    デフォルトでは、子プロセスは標準出力または標準エラーストリームなしで構成されます。あなたのテストでこれらのストリームの内容を確認する必要がある場合は、対応する ExitTest.Result プロパティへのキーパスをマクロに渡します。


    extension Customer {
      func eat(_ food: consuming some Food) {
        print("Let's see if I want to eat \(food)...")
        precondition(food.isDelicious, "Tasty food only!")
        precondition(food.isNutritious, "Healthy food only!")
        ...
      }
    }
    
    @Test func `Customer won't eat food unless it's delicious`() async {
      let result = await #expect(
        processExitsWith: .failure,
        observing: [\.standardOutputContent]
      ) {
        var food = ...
        food.isDelicious = false
        Customer.current.eat(food)
      }
      if let result {
        #expect(result.standardOutputContent.contains(UInt8(ascii: "L")))
      }
    }
    

    注意

    標準出力と標準エラーストリームの内容には、UTF-8 として有効でないシーケンスや String.init(cString:) で復号できないシーケンスなど、任意のバイトシーケンスが含まれる可能性があります。これらのストリームは子プロセス内でグローバルにアクセス可能であり、終了テストで実行されるすべてのコード (オペレーティングシステムや、パッケージの説明または Xcode プロジェクトで宣言したサードパーティの依存関係を含む) から書き込むことができます。


    テストライブラリは、\.exitStatus を監視しない場合でも、常に ExitStatus を子プロセスの実際の終了ステータス (システムによって報告されたとおり) に設定します。





    以下も見よ


    プロセスの終了方法を確認する


    終了テスト

    テストプロセスを終了する可能性のある機能をテストするには、テストの終了を使用します。


    macro expect(processExitsWith: ExitTest.Condition, observing: [any PartialKeyPath<ExitTest.Result> & Sendable], @autoclosure () -> Comment?, sourceLocation: SourceLocation, performing: () async throws -> Void) -> ExitTest.Result?

    式によってプロセスが与えられた方法で終了することを確認します。


    macro require(processExitsWith: ExitTest.Condition, observing: [any PartialKeyPath<ExitTest.Result> & Sendable], @autoclosure () -> Comment?, sourceLocation: SourceLocation, performing: () async throws -> Void) -> ExitTest.Result

    式によってプロセスが与えられた方法で終了することを確認し、終了しなかった場合はエラーを throw します。


    enum ExitStatus

    プロセスが終了時に報告する可能性のあるステータスを記述する列挙型。


    struct ExitTest

    終了テストを記述する型。



    <BETA SOFTWARE>
    このドキュメントには、開発中の API または技術に関する予備的な情報が含まれています。この情報は変更されることがあり、このドキュメントに従って実装されたソフトウェアは、最終的なオペレーティングシステムソフトウェアでテストする必要があります。

    Apple の Beta ソフトウエアについての詳細














    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ