

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# IDT を使用して独自のテストスイートを開発および実行する
<a name="idt-custom-tests"></a>

<a name="idt-byotc"></a>IDT v4.0.1 以降、IDT for AWS IoT Greengrass V2 は標準化された設定設定と結果形式をテストスイート環境と組み合わせ、デバイスとデバイスソフトウェア用のカスタムテストスイートを開発できます。独自の内部検証用のカスタムテストを追加したり、デバイス検証のためにこれらのテストを顧客に提供したりできます。

IDT を使用してカスタムテストスイートを開発および実行するには、次の手順を実行します。

**カスタムテストスイートを開発するには**  
+ テストする Greengrass デバイス用のカスタムテストロジックを使用して、テストスイートを作成します。
+ IDT と作成したカスタムテストスイートをテストの実行者に提供します。作成したテストスイートの構成設定に関する情報も提供します。

**カスタムテストスイートを実行するには**  
+ テストするデバイスをセットアップします。
+ 使用するテストスイートに必要な構成設定を実装します。
+ IDT を使用して、カスタムテストスイートを実行します。
+ IDT によって実行されたテストのテスト結果と実行ログを表示します。

## AWS IoT Device Tester for の最新バージョンをダウンロードする AWS IoT Greengrass
<a name="install-dev-tst-gg"></a>

IDT の[最新バージョン](idt-programmatic-download.md)をダウンロードし、ファイルシステム上で読み取り/書き込みのアクセス許可を持っている場所 (*<device-tester-extract-location>*) に抽出します。

**注記**  
<a name="unzip-package-to-local-drive"></a>複数のユーザーが NFS ディレクトリや Windows ネットワーク共有フォルダなどの共有場所から IDT を実行することはお勧めしません。IDT パッケージをローカルドライブに展開し、ローカルワークステーションで IDT バイナリを実行することをお勧めします。  
Windows では、パスの長さは 260 文字に制限されています。Windows を使用している場合は、パスが 260 文字以内になるようにして、IDT をルートディレクトリ (`C:\ ` または `D:\` など) に展開します。

## テストスイート作成ワークフロー
<a name="custom-test-workflow"></a>

テストスイートは 3 つのタイプのファイルで設定されます。
+ IDT にテストスイートの実行方法に関する情報を提供する設定ファイル。
+ IDT がテストケースの実行に使用するテスト実行可能ファイル。
+ テストの実行に必要な追加のファイル。

カスタム IDT テストを作成するには、次の基本的な手順を実行します。

1. テストスイート用の[設定ファイルを作成します](idt-json-config.md)。

1. テストスイート用のテストロジックが含まれる[テストケース実行可能ファイルを作成します](create-test-executables.md)。

1. テストスイートを実行するために[テストの実行者に必要な設定情報](set-custom-idt-config.md)を検証し、文書化します。

1. IDT が予想通りにテストスイートを実行し、[テスト結果](run-debug-custom-tests.md)を生成できることを確認します。

サンプルカスタムスイートを迅速に構築して実行するには、[チュートリアル: サンプル IDT テストスイートを構築して実行する](build-sample-suite.md)の手順に従ってください。

Python でカスタムテストスイートの作成を開始するには、[チュートリアル: シンプルな IDT テストスイートの開発](create-custom-tests.md)を参照してください。

# チュートリアル: サンプル IDT テストスイートを構築して実行する
<a name="build-sample-suite"></a>

 AWS IoT Device Tester ダウンロードには、サンプルテストスイートのソースコードが含まれています。このチュートリアルを完了すると、サンプルテストスイートを構築して実行し、IDT for を使用してカスタムテストスイート AWS IoT Greengrass を実行する方法を理解できます。

 このチュートリアルでは、次の手順を実行します。

1. [サンプルテストスイートを構築する](#build-sample)

1. [IDT を使用してサンプルテストスイートを実行する](#run-sample)

## 前提条件
<a name="prereqs-tutorial-sample"></a><a name="prereqs-list"></a>

このチュートリアルを完了するには、以下が必要です。
+ 

**ホストコンピュータの要件**
  + の最新バージョン AWS IoT Device Tester
  + [Python](https://www.python.org/downloads/) 3.7 以降

    コンピュータにインストールされている Python のバージョンを確認するには、次のコマンドを実行します。

    ```
    python3 --version
    ```

    Windows で、このコマンドを使用してエラーが返された場合は、代わりに `python --version` を使用してください。返されたバージョン番号が 3.7 以上の場合は、Powershell ターミナルで次のコマンドを実行し、`python3` を `python` コマンドのエイリアスとして設定します。

    ```
    Set-Alias -Name "python3" -Value "python"
    ```

    バージョン情報が返されない場合や、バージョン番号が 3.7 未満 の場合は、[Python のダウンロード](https://wiki.python.org/moin/BeginnersGuide/Download)の手順に従って Python 3.7 以上をインストールしてください。詳細については、[Python のドキュメント](https://docs.python.org)を参照してください。
  + [urllib3](https://urllib3.readthedocs.io/en/latest/)

    `urllib3` が正しくインストールされていることを確認するには、次のコマンドを実行します。

    ```
    python3 -c 'import urllib3'
    ```

    `urllib3` がインストールされていない場合は、次のコマンドを実行してインストールします。

    ```
    python3 -m pip install urllib3
    ```
+ 

**デバイスの要件**
  + Linux オペレーティングシステムが搭載され、ホストコンピュータと同じネットワークにネットワーク接続するデバイス。

    Raspberry Pi OS が搭載された [Raspberry Pi](https://www.raspberrypi.org/) を使用することをお勧めします。Raspberry Pi に [SSH](https://www.raspberrypi.org/documentation/remote-access/ssh/) をセットアップし、リモートから接続できることを確認します。

## IDT 用のデバイス情報を設定する
<a name="configure-idt-sample"></a>

IDT がテストを実行するためのデバイス情報を設定します。次の情報を使用して、`<device-tester-extract-location>/configs` フォルダに含まれている `device.json` テンプレートを更新する必要があります。

```
[
  {
    "id": "pool",
    "sku": "N/A",
    "devices": [
      {
        "id": "<device-id>",
        "connectivity": {
          "protocol": "ssh",
          "ip": "<ip-address>",
          "port": "<port>",
          "auth": {
            "method": "pki | password",
            "credentials": {
              "user": "<user-name>",
              "privKeyPath": "/path/to/private/key",
              "password": "<password>"
            }
          }
        }
      }
    ]
  }
]
```

`devices` オブジェクトで、次の情報を指定します。

`id`  
自分のデバイスのユーザー定義の一意の識別子。

`connectivity.ip`  
自分のデバイスの IP アドレス。

`connectivity.port`  
オプション。デバイスへの SSH 接続に使用するポート番号。

`connectivity.auth`  
接続の認証情報。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。    
`connectivity.auth.method`  
指定された接続プロトコルを介してデバイスにアクセスするために使用される認証方法。  
サポートされている値は以下のとおりです。  
+ `pki`
+ `password`  
`connectivity.auth.credentials`  
認証に使用される認証情報。    
`connectivity.auth.credentials.user`  
デバイスへのサインインに使用するユーザー名。  
`connectivity.auth.credentials.privKeyPath`  
デバイスへのサインインに使用するプライベートキーへの完全パス。  
この値は、`connectivity.auth.method` が `pki` に設定されている場合にのみ適用されます。  
`devices.connectivity.auth.credentials.password`  
自分のデバイスにサインインするためのパスワード。  
この値は、`connectivity.auth.method` が `password` に設定されている場合にのみ適用されます。

**注記**  
`method` が `pki` に設定されている場合のみ `privKeyPath` を指定します。  
`method` が `password` に設定されている場合のみ `password` を指定します。

## サンプルテストスイートを構築する
<a name="build-sample"></a>

`<device-tester-extract-location>/samples/python` フォルダには、サンプル設定ファイル、ソースコード、および提供されたビルドスクリプトを使用してテストスイートに結合できる IDT クライアント SDK が含まれています。次のディレクトリツリーは、これらのサンプルファイルの場所を示しています。

```
<device-tester-extract-location>
├── ...
├── tests
├── samples
│   ├── ...
│   └── python
│       ├── configuration
│       ├── src
│       └── build-scripts
│           ├── build.sh
│           └── build.ps1
└── sdks
    ├── ...
    └── python
        └── idt_client
```

テストスイートを構築するには、ホストコンピュータで次のコマンドを実行します。

------
#### [ Windows ]

```
cd <device-tester-extract-location>/samples/python/build-scripts
./build.ps1
```

------
#### [ Linux, macOS, or UNIX ]

```
cd <device-tester-extract-location>/samples/python/build-scripts
./build.sh
```

------

これにより、`<device-tester-extract-location>/tests` フォルダ内の `IDTSampleSuitePython_1.0.0` フォルダにサンプルテストスイートが作成されます。`IDTSampleSuitePython_1.0.0` フォルダのファイルを確認して、サンプルテストスイートの構造を理解し、テストケースの実行可能ファイルとテスト設定 JSON ファイルのさまざまな例を参照してください。

**注記**  
サンプルテストスイートには python ソースコードが含まれます。テストスイートのコードには機密情報を入力しないでください。

次のステップ: IDT を使用して、作成した[サンプルテストスイートを実行](#run-sample)します。

## IDT を使用してサンプルテストスイートを実行する
<a name="run-sample"></a>

サンプルテストスイートを実行するには、ホストコンピュータで次のコマンドを実行します。

```
cd <device-tester-extract-location>/bin
./devicetester_[linux | mac | win_x86-64] run-suite --suite-id IDTSampleSuitePython
```

IDT はサンプルテストスイートを実行し、結果をコンソールにストリーミングします。テストの実行が完了すると、次の情報が表示されます。

```
========== Test Summary ==========
Execution Time:         5s
Tests Completed:        4
Tests Passed:           4
Tests Failed:           0
Tests Skipped:          0
----------------------------------
Test Groups:
    sample_group:       PASSED
----------------------------------
Path to IoT Device Tester Report: /path/to/devicetester/results/87e673c6-1226-11eb-9269-8c8590419f30/awsiotdevicetester_report.xml
Path to Test Execution Logs: /path/to/devicetester/results/87e673c6-1226-11eb-9269-8c8590419f30/logs
Path to Aggregated JUnit Report: /path/to/devicetester/results/87e673c6-1226-11eb-9269-8c8590419f30/IDTSampleSuitePython_Report.xml
```

## トラブルシューティング
<a name="tutorial-troubleshooting-custom"></a>

次の情報は、チュートリアルの実行に関連する問題の解決に役立ちます。

**テストケースが正常に実行されない**  
テストが正常に実行されない場合、IDT はエラーログをコンソールにストリーミングします。このログはテスト実行のトラブルシューティングに役立ちます。このチュートリアルのすべての[前提条件](#prereqs-tutorial-sample)を満たしていることを確認してください。

**テスト対象のデバイスに接続できない**

以下について確認します。
+ `device.json` ファイルに、正しい IP アドレス、ポート、および認証情報が含まれている。
+ ホストコンピュータから SSH 経由でデバイスに接続できる。

# チュートリアル: シンプルな IDT テストスイートの開発
<a name="create-custom-tests"></a>

テストスイートは、以下を組み合わせたものです。
+ テストロジックが含まれるテスト実行可能ファイル
+ テストスイートについて記述する設定ファイル

このチュートリアルでは、IDT for AWS IoT Greengrass を使用して、単一のテストケースを含む Python テストスイートを開発する方法を示します。このチュートリアルでは、次の手順を実行します。

1. [テストスイートディレクトリを作成する](#test-suite-dir)

1. [設定ファイルを作成する](#test-suite-json)

1. [テストケース実行可能ファイルを作成する](#test-suite-exe)

1. [テストスイートを実行する](#run-test-suite)

## 前提条件
<a name="prereqs-tutorial-custom"></a><a name="prereqs-list"></a>

このチュートリアルを完了するには、以下が必要です。
+ 

**ホストコンピュータの要件**
  + の最新バージョン AWS IoT Device Tester
  + [Python](https://www.python.org/downloads/) 3.7 以降

    コンピュータにインストールされている Python のバージョンを確認するには、次のコマンドを実行します。

    ```
    python3 --version
    ```

    Windows で、このコマンドを使用してエラーが返された場合は、代わりに `python --version` を使用してください。返されたバージョン番号が 3.7 以上の場合は、Powershell ターミナルで次のコマンドを実行し、`python3` を `python` コマンドのエイリアスとして設定します。

    ```
    Set-Alias -Name "python3" -Value "python"
    ```

    バージョン情報が返されない場合や、バージョン番号が 3.7 未満 の場合は、[Python のダウンロード](https://wiki.python.org/moin/BeginnersGuide/Download)の手順に従って Python 3.7 以上をインストールしてください。詳細については、[Python のドキュメント](https://docs.python.org)を参照してください。
  + [urllib3](https://urllib3.readthedocs.io/en/latest/)

    `urllib3` が正しくインストールされていることを確認するには、次のコマンドを実行します。

    ```
    python3 -c 'import urllib3'
    ```

    `urllib3` がインストールされていない場合は、次のコマンドを実行してインストールします。

    ```
    python3 -m pip install urllib3
    ```
+ 

**デバイスの要件**
  + Linux オペレーティングシステムが搭載され、ホストコンピュータと同じネットワークにネットワーク接続するデバイス。

    Raspberry Pi OS が搭載された [Raspberry Pi](https://www.raspberrypi.org/) を使用することをお勧めします。Raspberry Pi に [SSH](https://www.raspberrypi.org/documentation/remote-access/ssh/) をセットアップし、リモートから接続できることを確認します。

## テストスイートディレクトリを作成する
<a name="test-suite-dir"></a>

IDT は、テストケースを、各テストスイート内のテストグループに論理的に分離します。各テストケースはテストグループ内に存在する必要があります。このチュートリアルでは、`MyTestSuite_1.0.0` という名前のフォルダを作成し、このフォルダ内に次のディレクトリツリーを作成します。

```
MyTestSuite_1.0.0
└── suite
    └── myTestGroup
        └── myTestCase
```

## 設定ファイルを作成する
<a name="test-suite-json"></a>

テストスイートには、次の必須の[設定ファイル](idt-json-config.md)が含まれている必要があります。<a name="required-json"></a>必要な設定ファイル

`suite.json`  
テストスイートに関する情報が含まれています。「[suite.json を設定する](idt-json-config.md#suite-json)」を参照してください。

`group.json`  
テストグループに関する情報が含まれています。テストスイート内のテストグループごとに `group.json` ファイルを作成する必要があります。「[group.json を設定する](idt-json-config.md#group-json)」を参照してください。

`test.json`  
テストケースに関する情報が含まれています。テストスイート内のテストケースごとに `test.json` ファイルを作成する必要があります。「[test.json を設定する](idt-json-config.md#test-json)」を参照してください。

1. `MyTestSuite_1.0.0/suite` フォルダで、次の構造の `suite.json` ファイルを作成します。

   ```
   {
       "id": "MyTestSuite_1.0.0",
       "title": "My Test Suite",
       "details": "This is my test suite.",
       "userDataRequired": false
   }
   ```

1. `MyTestSuite_1.0.0/myTestGroup` フォルダで、次の構造の `group.json` ファイルを作成します。

   ```
   {
       "id": "MyTestGroup",
       "title": "My Test Group",
       "details": "This is my test group.",
       "optional": false
   }
   ```

1. `MyTestSuite_1.0.0/myTestGroup/myTestCase` フォルダで、次の構造の `test.json` ファイルを作成します。

   ```
   {
       "id": "MyTestCase",
       "title": "My Test Case",
       "details": "This is my test case.",
       "execution": {
           "timeout": 300000,
           "linux": {
               "cmd": "python3",
               "args": [
                   "myTestCase.py"
               ]
           },
           "mac": {
               "cmd": "python3",
               "args": [
                   "myTestCase.py"
               ]
           },
           "win": {
               "cmd": "python3",
               "args": [
                   "myTestCase.py"
               ]
           }
       }
   }
   ```

`MyTestSuite_1.0.0` フォルダのディレクトリツリーは次のようになります。

```
MyTestSuite_1.0.0
└── suite
    ├── suite.json
    └── myTestGroup
        ├── group.json
        └── myTestCase
            └── test.json
```

## IDT クライアント SDK を入手する
<a name="add-idt-sdk"></a>

IDT がテスト対象のデバイスとやり取りし、テスト結果をレポートできるようにするには、[IDT クライアント SDK](create-test-executables.md#idt-client-sdk) を使用します。このチュートリアルでは、Python バージョンの SDK を使用します。

`<device-tester-extract-location>/sdks/python/` フォルダから、`idt_client` フォルダを自分の `MyTestSuite_1.0.0/suite/myTestGroup/myTestCase` フォルダにコピーします。

SDK が正常にコピーされたことを確認するには、次のコマンドを実行します。

```
cd MyTestSuite_1.0.0/suite/myTestGroup/myTestCase
python3 -c 'import idt_client'
```

## テストケース実行可能ファイルを作成する
<a name="test-suite-exe"></a>

テストケース実行可能ファイルには、実行するテストロジックが含まれています。テストスイートには、複数のテストケース実行可能ファイルを含めることができます。このチュートリアルでは、テストケース実行可能ファイルを 1 つだけ作成します。

1. テストスイートファイルを作成します。

   `MyTestSuite_1.0.0/suite/myTestGroup/myTestCase` フォルダで、次の内容の `myTestCase.py` ファイルを作成します。

   ```
   from idt_client import *
   
   def main():
       # Use the client SDK to communicate with IDT
       client = Client()
   
   if __name__ == "__main__":
       main()
   ```

1. クライアント SDK 関数を使用して、自分の `myTestCase.py` ファイルに次のテストロジックを追加します。

   1. テスト対象のデバイスで SSH コマンドを実行します。

      ```
      from idt_client import *
      
      def main():
          # Use the client SDK to communicate with IDT
          client = Client()
          
          # Create an execute on device request
          exec_req = ExecuteOnDeviceRequest(ExecuteOnDeviceCommand("echo 'hello world'"))
          
          # Run the command
          exec_resp = client.execute_on_device(exec_req)
          
          # Print the standard output
          print(exec_resp.stdout)
      
      if __name__ == "__main__":
          main()
      ```

   1. テスト結果を IDT に送信します。

      ```
      from idt_client import *
      
      def main():
          # Use the client SDK to communicate with IDT
          client = Client()
          
          # Create an execute on device request
          exec_req = ExecuteOnDeviceRequest(ExecuteOnDeviceCommand("echo 'hello world'"))
          
          # Run the command
          exec_resp = client.execute_on_device(exec_req)
          
          # Print the standard output
          print(exec_resp.stdout)
      
          # Create a send result request
          sr_req = SendResultRequest(TestResult(passed=True))
           
          # Send the result
          client.send_result(sr_req)
             
      if __name__ == "__main__":
          main()
      ```

## IDT 用のデバイス情報を設定する
<a name="configure-idt-sample"></a>

IDT がテストを実行するためのデバイス情報を設定します。次の情報を使用して、`<device-tester-extract-location>/configs` フォルダに含まれている `device.json` テンプレートを更新する必要があります。

```
[
  {
    "id": "pool",
    "sku": "N/A",
    "devices": [
      {
        "id": "<device-id>",
        "connectivity": {
          "protocol": "ssh",
          "ip": "<ip-address>",
          "port": "<port>",
          "auth": {
            "method": "pki | password",
            "credentials": {
              "user": "<user-name>",
              "privKeyPath": "/path/to/private/key",
              "password": "<password>"
            }
          }
        }
      }
    ]
  }
]
```

`devices` オブジェクトで、次の情報を指定します。

`id`  
自分のデバイスのユーザー定義の一意の識別子。

`connectivity.ip`  
自分のデバイスの IP アドレス。

`connectivity.port`  
オプション。デバイスへの SSH 接続に使用するポート番号。

`connectivity.auth`  
接続の認証情報。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。    
`connectivity.auth.method`  
指定された接続プロトコルを介してデバイスにアクセスするために使用される認証方法。  
サポートされている値は以下のとおりです。  
+ `pki`
+ `password`  
`connectivity.auth.credentials`  
認証に使用される認証情報。    
`connectivity.auth.credentials.user`  
デバイスへのサインインに使用するユーザー名。  
`connectivity.auth.credentials.privKeyPath`  
デバイスへのサインインに使用するプライベートキーへの完全パス。  
この値は、`connectivity.auth.method` が `pki` に設定されている場合にのみ適用されます。  
`devices.connectivity.auth.credentials.password`  
自分のデバイスにサインインするためのパスワード。  
この値は、`connectivity.auth.method` が `password` に設定されている場合にのみ適用されます。

**注記**  
`method` が `pki` に設定されている場合のみ `privKeyPath` を指定します。  
`method` が `password` に設定されている場合のみ `password` を指定します。

## テストスイートを実行する
<a name="run-test-suite"></a>

テストスイートを作成したら、テストスイートが期待どおりに機能することを確認します。そのために、次の手順に従って、既存のデバイスプールを使用してテストスイートを実行します。

1. 自分の `MyTestSuite_1.0.0` フォルダを `<device-tester-extract-location>/tests` にコピーします。

1. 以下の コマンドを実行します。

   ```
   cd <device-tester-extract-location>/bin
   ./devicetester_[linux | mac | win_x86-64] run-suite --suite-id MyTestSuite
   ```

IDT はテストスイートを実行し、結果をコンソールにストリーミングします。テストの実行が完了すると、次の情報が表示されます。

```
time="2020-10-19T09:24:47-07:00" level=info msg=Using pool: pool
time="2020-10-19T09:24:47-07:00" level=info msg=Using test suite "MyTestSuite_1.0.0" for execution
time="2020-10-19T09:24:47-07:00" level=info msg=b'hello world\n' suiteId=MyTestSuite groupId=myTestGroup testCaseId=myTestCase deviceId=my-device executionId=9a52f362-1227-11eb-86c9-8c8590419f30
time="2020-10-19T09:24:47-07:00" level=info msg=All tests finished. executionId=9a52f362-1227-11eb-86c9-8c8590419f30
time="2020-10-19T09:24:48-07:00" level=info msg=

========== Test Summary ==========
Execution Time:         1s
Tests Completed:        1
Tests Passed:           1
Tests Failed:           0
Tests Skipped:          0
----------------------------------
Test Groups:
    myTestGroup:        PASSED
----------------------------------
Path to IoT Device Tester Report: /path/to/devicetester/results/9a52f362-1227-11eb-86c9-8c8590419f30/awsiotdevicetester_report.xml
Path to Test Execution Logs: /path/to/devicetester/results/9a52f362-1227-11eb-86c9-8c8590419f30/logs
Path to Aggregated JUnit Report: /path/to/devicetester/results/9a52f362-1227-11eb-86c9-8c8590419f30/MyTestSuite_Report.xml
```

## トラブルシューティング
<a name="tutorial-troubleshooting"></a>

次の情報は、チュートリアルの実行に関連する問題の解決に役立ちます。

**テストケースが正常に実行されない**

テストが正常に実行されない場合、IDT はエラーログをコンソールにストリーミングします。このログはテスト実行のトラブルシューティングに役立ちます。エラーログを確認する前に、次の点を確認してください。
+ IDT クライアント SDK が、[このステップ](#add-idt-sdk)で説明された通りの正しいフォルダにある。
+ このチュートリアルのすべての[前提条件](#prereqs-tutorial-custom)を満たしている。

**テスト対象のデバイスに接続できない**

以下について確認します。
+ `device.json` ファイルに、正しい IP アドレス、ポート、および認証情報が含まれている。
+ ホストコンピュータから SSH 経由でデバイスに接続できる。

# IDT テストスイート設定ファイルを作成する
<a name="idt-json-config"></a>

このセクションでは、カスタムテストスイートの作成時、これに含める設定ファイルを作成する際の形式について説明します。<a name="required-json"></a>必要な設定ファイル

`suite.json`  
テストスイートに関する情報が含まれています。「[suite.json を設定する](#suite-json)」を参照してください。

`group.json`  
テストグループに関する情報が含まれています。テストスイート内のテストグループごとに `group.json` ファイルを作成する必要があります。「[group.json を設定する](#group-json)」を参照してください。

`test.json`  
テストケースに関する情報が含まれています。テストスイート内のテストケースごとに `test.json` ファイルを作成する必要があります。「[test.json を設定する](#test-json)」を参照してください。オプションの設定ファイル

`test_orchestrator.yaml`-または-`state_machine.json`  
IDT がテストスイートを実行するときのテストの実行方法を定義します。「[test\$1orchestrator.yaml を設定する](#test-orchestrator-config)」を参照してください。  
IDT v4.5.1 以降では、テストワークフローの定義に `test_orchestrator.yaml` ファイルを使用します。IDT のそれより前のバージョンでは、`state_machine.json`ファイルを開きます。ステートマシンの詳細については、「[IDT ステートマシンを設定する](idt-state-machine.md)」を参照してください。

`userdata_schema.json`  
テストの実行者が構成設定に含めることができる [`userdata.json` ファイル](set-custom-idt-config.md#userdata-config-custom)のスキーマを定義します。`userdata.json` ファイルは、テストの実行に必要であるものの、`device.json` ファイルに含まれていない、追加の設定情報用に使用します。「[userdata\$1schema.json を設定する](#userdata-schema-json)」を参照してください。

設定ファイルは、以下に示すように `<custom-test-suite-folder>` に配置します。

```
<custom-test-suite-folder>
└── suite
    ├── suite.json
    ├── test_orchestrator.yaml
    ├── userdata_schema.json
    ├── <test-group-folder>
        ├── group.json
        ├── <test-case-folder>
            └── test.json
```

## suite.json を設定する
<a name="suite-json"></a>

`suite.json` ファイルは、環境変数を設定し、テストスイートの実行にユーザーデータが必要かどうかを決定します。以下のテンプレートを使用して、`<custom-test-suite-folder>/suite/suite.json` ファイルを設定します。

```
{
    "id": "<suite-name>_<suite-version>",
    "title": "<suite-title>",
    "details": "<suite-details>",
    "userDataRequired": true | false,
    "environmentVariables": [
        {
            "key": "<name>",
            "value": "<value>",
        },
        ...
        {
            "key": "<name>",
            "value": "<value>",
        }
    ]
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`id`  
テストスイートの一意のユーザー定義 ID。`id` の値は、`suite.json` ファイルが配置されているテストスイートフォルダ名と一致する必要があります。スイート名とスイートのバージョンは、次の要件も満たしている必要があります。  
+ `<suite-name>` にアンダースコアを含めることはできません。
+ `<suite-version>` が `x.x.x` として表されている (`x` は数字)。
ID は IDT によって生成されるテストレポートに表示されます。

`title`  
このテストスイートでテストされる製品または機能のユーザー定義名。この名前は、テストの実行者の IDT CLI に表示されます。

`details`  
テストスイートの目的の簡単な説明。

`userDataRequired`  
テストの実行者が `userdata.json` ファイルにカスタム情報を含める必要があるかどうかを定義します。この値を `true` に設定した場合は、テストスイートフォルダに [`userdata_schema.json` ファイル](#userdata-schema-json)も含める必要があります。

`environmentVariables`  
オプション。このテストスイートに設定する環境変数の配列。    
`environmentVariables.key`  
環境変数の名前。  
`environmentVariables.value`  
環境変数の値。

## group.json を設定する
<a name="group-json"></a>

`group.json` ファイルは、テストグループが必須かオプションかを定義します。以下のテンプレートを使用して、`<custom-test-suite-folder>/suite/<test-group>/group.json` ファイルを設定します。

```
{
    "id": "<group-id>",
    "title": "<group-title>",
    "details": "<group-details>",
    "optional": true | false,
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`id`  
テストグループの一意のユーザー定義 ID。`id` の値は、`group.json` ファイルが配置されているテストグループフォルダの名前と一致する必要があり、アンダースコア (`_`) は使用できません。ID は IDT によって生成されるテストレポートで使用されます。

`title`  
テストグループのわかりやすい名前。この名前は、テストの実行者の IDT CLI に表示されます。

`details`  
テストグループの目的の簡単な説明。

`optional`  
オプション。`true` に設定すると、IDT が必須テストの実行を完了した後に、このテストグループがオプショングループとして表示されます。デフォルト値は `false` です。

## test.json を設定する
<a name="test-json"></a>

`test.json` ファイルは、テストケースによって使用されるテストケース実行ファイルと環境変数を決定します。テストケース実行可能ファイルの作成の詳細については、[IDT テストケース実行可能ファイルを作成する](create-test-executables.md)を参照してください。

以下のテンプレートを使用して、`<custom-test-suite-folder>/suite/<test-group>/<test-case>/test.json` ファイルを設定します。

```
{
    "id": "<test-id>",
    "title": "<test-title>",
    "details": "<test-details>",
    "requireDUT": true | false,
    "requiredResources": [
        {
            "name": "<resource-name>",
            "features": [
                {
                    "name": "<feature-name>",
                    "version": "<feature-version>",
                    "jobSlots": <job-slots>
                }
            ]
        }
    ],
    "execution": {
        "timeout": <timeout>,
        "mac": {
            "cmd": "/path/to/executable",
            "args": [
                "<argument>"
            ],
        },
        "linux": {
            "cmd": "/path/to/executable",
            "args": [
                "<argument>"
            ],
        },
        "win": {
            "cmd": "/path/to/executable",
            "args": [
                "<argument>"
            ]
        }
    },
    "environmentVariables": [
        {
            "key": "<name>",
            "value": "<value>",
        }
    ]
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`id`  
テストケースの一意のユーザー定義 ID。`id` の値は、`test.json` ファイルが配置されているテストケースフォルダの名前と一致する必要があり、アンダースコア (`_`) は使用できません。ID は IDT によって生成されるテストレポートで使用されます。

`title`  
テストケースのわかりやすい名前。この名前は、テストの実行者の IDT CLI に表示されます。

`details`  
テストケースの目的の簡単な説明。

`requireDUT`  
オプション。このテストの実行にデバイスが必要な場合は `true` に設定します。必要ない場合は `false` に設定します。デフォルト値は `true` です。テストの実行者は、テストの実行に使用するデバイスを `device.json` ファイルに設定します。

`requiredResources`  
オプション。このテストの実行に必要なリソースデバイスに関する情報を指定する配列。    
`requiredResources.name`  
このテストの実行時にリソースデバイスに与える一意の名前。  
`requiredResources.features`  
ユーザー定義のリソースデバイス機能の配列。    
`requiredResources.features.name`  
機能の名前。このデバイスが使用するデバイス機能。この名前は、テストの実行者によって `resource.json` ファイルに指定される機能名に対してマッチングされます。  
`requiredResources.features.version`  
オプション。機能のバージョン。この値は、テストの実行者によって `resource.json` ファイルに指定される機能のバージョンに対してマッチングされます。バージョンが指定されていない場合、機能はチェックされません。機能にバージョン番号が必要ない場合は、このフィールドは空白のままにしてください。  
`requiredResources.features.jobSlots`  
オプション。この機能がサポートできる同時テストの数。デフォルト値は `1` です。IDT が機能ごとに異なるデバイスを使用する場合は、この値を `1` に設定することをお勧めします。

`execution.timeout`  
IDT がテスト実行終了まで待機する時間 (ミリ秒単位)。この値の設定の詳細については、[IDT テストケース実行可能ファイルを作成する](create-test-executables.md)を参照してください。

`execution.os`  
IDT を実行するホストコンピュータのオペレーティングシステムに基づいて実行されるテストケースの実行可能ファイル。サポートされている値は `linux`、`mac`、`win` です。    
`execution.os.cmd`  
指定されたオペレーティングシステムで実行するテストケース実行可能ファイルへのパス。この場所は、システムパス内に存在する必要があります。  
`execution.os.args`  
オプション。テストケースの実行可能ファイルを実行するために指定する引数。

`environmentVariables`  
オプション。このテストケース用に設定された環境変数の配列。    
`environmentVariables.key`  
環境変数の名前。  
`environmentVariables.value`  
環境変数の値。
`test.json` ファイルと `suite.json` ファイルに同じ環境変数を設定した場合は、`test.json` ファイルの値が優先されます。

## test\$1orchestrator.yaml を設定する
<a name="test-orchestrator-config"></a>

テストオーケストレーターは、テストスイートの実行フローを制御するコンストラクトです。テストスイートの開始ステートを決定し、ユーザー定義のルールに基づいてステートの移行を管理し、終了ステートに達するまでステートの移行を継続します。

テストスイートにユーザー定義のテストオーケストレーターが含まれていない場合は、IDT によってテストオーケストレーターが生成されます。

デフォルトのテストオーケストレーターには以下の機能があります。
+ テストの実行者に、テストスイート全体ではなく、特定のテストグループを選択して実行する機能を提供する。
+ 特定のテストグループが選択されていない場合、テストスイート内のすべてのテストグループをランダムな順序で実行する。
+ レポートを生成し、各テストグループおよびテストケースのテスト結果を示すコンソールサマリーを出力する。

IDT テストオーケストレーターの機能の詳細については、「[IDT テストオーケストレーターを設定する](idt-test-orchestrator.md)」を参照してください。

## userdata\$1schema.json を設定する
<a name="userdata-schema-json"></a>

`userdata_schema.json` ファイルは、テストの実行者がユーザーデータを指定するスキーマを決定します。ユーザーデータは、テストスイートが `device.json` ファイルに含まれていない情報を必要とする場合に必要になります。例えば、テストを実行するために、Wi-Fi ネットワークの認証情報、特定のオープンポート、またはユーザーが提供する証明書が必要になる場合があります。この情報は、`userdata` という入力パラメータとして IDT に提供できます。これは、ユーザーが `<device-tester-extract-location>/config` フォルダに作成する`userdata.json` ファイルの値です。`userdata.json` の形式は、テストケースに含まれている `userdata_schema.json` ファイルに基づきます。

テストの実行者が `userdata.json` ファイルを提供しなければならないことを示す方法

1. `suite.json` ファイルで、`userDataRequired` を `true` に設定します。

1. `<custom-test-suite-folder>` で、`userdata_schema.json` ファイルを作成します。

1. `userdata_schema.json` ファイルを編集して、有効な [IETF Draft v4 JSON Schema](https://json-schema.org/specification-links.html#draft-4) を作成します。

IDT は、テストスイートを実行するときに、このスキーマを自動的に読み込み、テストの実行者によって提供される `userdata.json` ファイルの検証に使用します。有効な場合、`userdata.json` ファイルのコンテンツは [IDT コンテキスト](idt-context.md)および、[テストオーケストレーターコンテキスト](idt-state-machine.md#state-machine-context)の両方で利用可能になります。

# IDT テストオーケストレーターを設定する
<a name="idt-test-orchestrator"></a>

IDT v4.5.1 以降、IDT には新しいテストオーケストレーターコンポーネントが追加されています。テストオーケストレーターは、テストスイートの実行フローを制御する IDT コンポーネントで、IDT がすべてのテストを実行した後にテストレポートを生成します。テストオーケストレーターは、ユーザー定義のルールに基づいて、テストの選択とテストの実行順序を決定します。

テストスイートにユーザー定義のテストオーケストレーターが含まれていない場合は、IDT によってテストオーケストレーターが生成されます。

デフォルトのテストオーケストレーターには以下の機能があります。
+ テストの実行者に、テストスイート全体ではなく、特定のテストグループを選択して実行する機能を提供する。
+ 特定のテストグループが選択されていない場合、テストスイート内のすべてのテストグループをランダムな順序で実行する。
+ レポートを生成し、各テストグループおよびテストケースのテスト結果を示すコンソールサマリーを出力する。

IDT テストオーケストレーターは、テストオーケストレーターに置き換えられます。テストスイートの開発には、IDT テストオーケストレーターではなくテストオーケストレータを使用することを強くお勧めします。テストオーケストレーターでは、以下の機能が改善されています。
+ IDT ステートマシンが命令型を使用するのに対し、宣言型を使用します。これにより、どのテストを実行するか、およびいつそれを実行するかを指定できます。
+ 特定のグループ処理、レポート生成、エラー処理、結果追跡を管理し、これらのアクションを手動管理する必要がないようにします。
+ デフォルトでコメントをサポートする YAML 形式を使用します。
+ 同じワークフローを定義するのに必要なディスク容量が、テストオーケストレーターより 80% 少なくなります。
+ テスト前検証を追加し、誤ったテスト ID や依存関係の循環がワークフロー定義に含まれていないことを検証します。

## テストオーケストレーター形式
<a name="idt-test-orchestrator-format"></a>

次のテンプレートを使用して、独自の `<custom-test-suite-folder>/suite/test_orchestrator.yaml` ファイルを設定できます。

```
Aliases:
  string: context-expression

ConditionalTests:
  - Condition: context-expression
    Tests:
      - test-descriptor

Order:
  - - group-descriptor
    - group-descriptor

Features:
  - Name: feature-name
    Value: support-description
    Condition: context-expression
    Tests:
        - test-descriptor
    OneOfTests:
        - test-descriptor
    IsRequired: boolean
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`Aliases`  
オプション。コンテキスト式にマップするユーザー定義の文字列。エイリアスを使用すると、テストオーケストレーター設定でコンテキスト式を識別するためのフレンドリ名を生成できます。これは、複雑なコンテキスト式や、複数の場所で使用する式を作成する場合に特に便利です。  
コンテキスト式を使用するとコンテキストクエリを保存でき、これにより他の IDT 設定からデータにアクセスできるようになります。詳細については、「[コンテキスト内のデータにアクセスする](idt-context.md#accessing-context-data)」を参照してください。  

**Example 例**  

```
Aliases:
    FizzChosen: "'{{$pool.features[?(@.name == 'Fizz')].value[0]}}' == 'yes'"    
    BuzzChosen: "'{{$pool.features[?(@.name == 'Buzz')].value[0]}}' == 'yes'"    
    FizzBuzzChosen: "'{{$aliases.FizzChosen}}' && '{{$aliases.BuzzChosen}}'"
```

`ConditionalTests`  
オプション。条件と、条件が満たされたときに実行される、対応するテストケースのリスト。各条件には複数のテストケースを割り当てることができますが、特定のテストケースを割り当てることができる条件は 1 つだけです。  
デフォルトでは、IDT はこのリストの条件に割り当てられていないテストケースをすべて実行します。このセクションを指定しない場合、IDT はテストスイートのすべてのテストグループを実行します。  
`ConditionalTests` リストの各項目には以下のパラメータが含まれます。    
`Condition`  
ブール値に評価されるコンテキスト式。評価値が true の場合、IDT は `Tests` パラメータで指定されたテストケースを実行します。  
`Tests`  
テスト記述子のリスト。  
各テスト記述子は、テストグループ ID と 1 つ以上のテストケース ID を使用して、特定のテストグループから実行する個々のテストを識別します。テスト記述子は以下の形式を使用します。  

```
GroupId: group-id
CaseIds: [test-id, test-id] # optional
```

**Example 例**  
次の例は、`Aliases` として定義できる汎用コンテキスト式を使用します。  

```
ConditionalTests:
    - Condition: "{{$aliases.Condition1}}"
      Tests:
          - GroupId: A
          - GroupId: B
    - Condition: "{{$aliases.Condition2}}"
      Tests:
          - GroupId: D
    - Condition: "{{$aliases.Condition1}} || {{$aliases.Condition2}}"
      Tests:
          - GroupId: C
```

定義された条件に基づき、IDT は次のようにテストグループを選択します。
+ `Condition1` が真の場合、IDT はテストグループ A、B、C のテストを実行します。
+ `Condition2` が真の場合、IDT はテストグループ C と D のテストを実行します。

`Order`  
オプション。テストを実行する順序。テストの順序はテストのグループレベルで指定します。このセクションを指定しない場合、IDT はすべての適用可能なテストグループをランダムな順序で実行します。`Order` の値は、グループ記述子リストのリストです。`Order` のリストに記載していないテストグループは、記載されている他のテストグループと並行して実行できます。  

各グループ記述子リストには 1 つ以上のグループ記述子が含まれ、各記述子で指定されたグループを実行する順序を特定します。個別のグループ記述子を定義するには、以下の形式を使用できます。
+ `group-id` - 既存のテストグループのグループ ID。
+ `[group-id, group-id]` - 相互に任意の順序で実行できるテストグループのリスト。
+ `"*"` - ワイルドカード これは、現在のグループ記述子リストにまだ指定されていないすべてのテストグループのリストに相当します。

`Order` の値は、次の要件も満たしている必要があります。
+ グループ記述子で指定するテストグループ ID は、テストスイートに存在する必要があります。
+ 各グループ記述子リストには、少なくとも 1 つのテストグループが含まれている必要があります。
+ 各グループ記述子リストには一意のグループ ID を含める必要があります。個々のグループ記述子内でテストグループ ID を繰り返すことはできません。
+ グループ記述子リストは、最大 1 つのワイルドカードグループ記述子を持つことができます。ワイルドカードグループ記述子は、リストの最初または最後の項目でなければなりません。

**Example 例**  
テストグループ A、B、C、D、E を含むテストスイートについて、次の例のリストに、IDT が最初にテストグループ A を実行し、次にテストグループ B を実行し、次いで C、D、E を任意の順序で実行するよう指定するためのさまざまな方法を示します。  
+ 

  ```
  Order:
      - - A
        - B
        - [C, D, E]
  ```
+ 

  ```
  Order:
      - - A
        - B
        - "*"
  ```
+ 

  ```
  Order:
      - - A
        - B
      
      - - B
        - C
      
      - - B
        - D
      
      - - B
        - E
  ```

`Features`  
オプション。IDT に `awsiotdevicetester_report.xml` ファイルに追加させる製品機能のリスト。このセクションを指定しない場合、IDT はレポートに製品機能を追加しません。  
製品機能とは、デバイスが満たしている可能性のある特定の基準に関するユーザー定義の情報です。例えば、MQTT 製品機能には、デバイスが MQTT メッセージを適切に公開することを指定できます。`awsiotdevicetester_report.xml` では、製品機能は指定されたテストが合格したかどうかに応じて、`supported`、`not-supported`、またはカスタムのユーザー定義値に設定されます。  
`Features` リストの各項目は以下のパラメータで設定されます。    
`Name`  
機能の名前。  
`Value`  
オプション。`supported` の代わりにレポートで使用するカスタム値。この値を指定しない場合、テスト結果に基づいて、IDT により機能値が `supported` または `not-supported` に設定されます。同じ機能を異なる条件でテストする場合、`Features` リストにおけるその機能のインスタンスごとにカスタム値を使用できます。IDT は、サポート条件の機能値を連結します。詳細については、以下を参照してください。  
`Condition`  
ブール値に評価されるコンテキスト式。評価値が true の場合、IDT はテストスイートを実行後、その機能をテストレポートに追加します。評価値が false の場合、テストはレポートに含まれません。  
`Tests`  
オプション。テスト記述子のリスト。機能をサポートするには、このリストで指定されるテストにすべて合格する必要があります。  
このリストの各テスト記述子は、テストグループ ID と 1 つ以上のテストケース ID を使用して、特定のテストグループから実行する個々のテストを識別します。テスト記述子は以下の形式を使用します。  

```
GroupId: group-id
CaseIds: [test-id, test-id] # optional
```
`Features` リストの各機能について、`Tests` か `OneOfTests` のどちらかを指定する必要があります。  
`OneOfTests`  
オプション。テスト記述子のリスト。機能をサポートするには、このリストで指定されているテストのうち少なくとも 1 つに合格する必要があります。  
このリストの各テスト記述子は、テストグループ ID と 1 つ以上のテストケース ID を使用して、特定のテストグループから実行する個々のテストを識別します。テスト記述子は以下の形式を使用します。  

```
GroupId: group-id
CaseIds: [test-id, test-id] # optional
```
`Features` リストの各機能について、`Tests` か `OneOfTests` のどちらかを指定する必要があります。  
`IsRequired`  
機能がテストレポートに必要かどうかを定義するブール値。デフォルト値は `false` です。

**Example**  

## テストオーケストレーターコンテキスト
<a name="idt-test-orchestrator-context"></a>

テストオーケストレーターコンテキストは、実行中のテストオーケストレーターに利用可能なデータが含まれている読み取り専用 JSON ドキュメントです。テストオーケストレーターコンテキストは、テストオーケストレーターからのみアクセス可能で、テストフローを決定する情報が含まれています。例えば、テストの実行者によって `userdata.json` ファイルに設定された情報を使用して、特定のテストを実行する必要があるかどうかを決定できます。

テストオーケストレーターコンテキストは次の形式を使用します。

```
{
    "pool": {
        <device-json-pool-element>
    },
    "userData": {
        <userdata-json-content>
    },
    "config": {
        <config-json-content>
    }
}
```

`pool`  
テスト実行用に選択されたデバイスプールに関する情報。選択されたデバイスプールのこの情報は、`device.json` ファイルで定義された、対応する最上位レベルのデバイスプール配列要素から取得されます。

`userData`  
`userdata.json` ファイル内の情報。

`config`  
`config.json` ファイル内の情報。

コンテキストは、JSONPath 表記法を使用してクエリできます。ステート定義における JSonPath クエリの構文は `{{query}}` です。テストオーケストレーターコンテキストからデータにアクセスする場合、各値が文字列、数値、またはブール値として評価されることを確認してください。

JSONPath 表記を使用してコンテキストのデータにアクセスする方法の詳細については、[IDT コンテキストを使用する](idt-context.md)を参照してください。

# IDT ステートマシンを設定する
<a name="idt-state-machine"></a>

**重要**  
IDT v4.5.1 以降、このステートマシンは非推奨です。新しいテストオーケストレーターを使用することを強くお勧めします。詳細については、「[IDT テストオーケストレーターを設定する](idt-test-orchestrator.md)」を参照してください。

ステートマシンは、テストスイートの実行フローを制御するコンストラクトです。テストスイートの開始ステートを決定し、ユーザー定義のルールに基づいてステートの移行を管理し、終了ステートに達するまでステートの移行を継続します。

テストスイートにユーザー定義のステートマシンが含まれていない場合は、IDT によってステートマシンが生成されます。デフォルトのステートマシンには、次の機能があります。
+ テストの実行者に、テストスイート全体ではなく、特定のテストグループを選択して実行する機能を提供する。
+ 特定のテストグループが選択されていない場合、テストスイート内のすべてのテストグループをランダムな順序で実行する。
+ レポートを生成し、各テストグループおよびテストケースのテスト結果を示すコンソールサマリーを出力する。

IDT テストスイートのステートマシンは、次の基準を満たす必要があります。
+ 各ステートが、IDT が実行する各アクション (テストグループの実行、レポートファイルの生成など) に対応する。
+ ステートが移行すると、そのステートに関連付けられたアクションを実行する。
+ 各ステートが、次のステートの移行ルールを定義する。
+ 終了ステートが `Succeed` または `Fail` である。

## ステートマシンの形式
<a name="state-machine-format"></a>

次のテンプレートを使用して、独自の `<custom-test-suite-folder>/suite/state_machine.json` ファイルを設定できます。

```
{
  "Comment": "<description>",
  "StartAt": "<state-name>",
  "States": {
    "<state-name>": {
      "Type": "<state-type>",
      // Additional state configuration
    }
    
    // Required states
    "Succeed": {
      "Type": "Succeed"
    },
    "Fail": {
      "Type": "Fail"
    }
  }
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`Comment`  
ステートマシンの説明。

`StartAt`  
IDT がテストスイートの実行を開始するステートの名前。`StartAt` の値は、`States` オブジェクトにリストされているいずれかのステートに設定する必要があります。

`States`  
ユーザー定義のステート名を有効な IDT ステートにマッピングするオブジェクト。各 States.*state-name* オブジェクトには、*state-name* にマッピングされた有効なステートの定義が含まれています。  
`States` オブジェクトには、`Succeed` ステートおよび `Fail` ステートを含める必要があります。有効なステートについては、[有効なステートとステートの定義](#valid-states)を参照してください。

## 有効なステートとステートの定義
<a name="valid-states"></a>

このセクションでは、IDT ステートマシンで使用可能なすべての有効なステートのステート定義について説明します。以下に示すステートの一部は、テストケースレベルでの設定をサポートしています。ただし、絶対に必要な場合を除き、テストケースレベルではなく、テストグループレベルでステート移行ルールを設定することをお勧めします。

**Topics**
+ [RunTask](#state-runtask)
+ [選択](#state-choice)
+ [並行](#state-parallel)
+ [AddProductFeatures](#state-addproductfeatures)
+ [レポートを行う](#state-report)
+ [LogMessage](#state-logmessage)
+ [SelectGroup](#state-selectgroup)
+ [失敗](#state-fail)
+ [成功](#state-succeed)

### RunTask
<a name="state-runtask"></a>

`RunTask` ステートは、テストスイートで定義されているテストグループからテストケースを実行します。

```
{
    "Type": "RunTask",
    "Next": "<state-name>",
    "TestGroup": "<group-id>",
    "TestCases": [
        "<test-id>"
    ],
    "ResultVar": "<result-name>"
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`Next`  
現在のステートのアクションを実行した後に移行するステートの名前。

`TestGroup`  
オプション。実行するテストグループの ID。この値を指定しない場合、IDT はテストの実行者が選択するテストグループを実行します。

`TestCases`  
オプション。`TestGroup` に指定されたグループのテストケース ID の配列。IDT は、`TestGroup` と `TestCases` の値に基づいて、次のようにテストの実行動作を決定します。  
+ `TestGroup` と `TestCases` 両方が指定されている場合、IDT はテストグループから指定されたテストケースを実行します。
+ `TestCases` が指定され、`TestGroup` が指定されていない場合、IDT は指定されたテストケースを実行します。
+ `TestGroup` が指定され、`TestCases` が指定されていない場合は、IDT は指定されたテストグループ内のすべてのテストケースを実行します。
+ `TestGroup` も `TestCases` も指定されていない場合、IDT は、テストの実行者が IDT CLI から選択したテストグループからすべてのテストケースを実行します。テストの実行者がグループを選択できるようにするには、`state_machine.json` ファイルに `RunTask` ステートと `Choice`ステート両方を含める必要があります。これを行う方法の例については、[ステートマシンの例: ユーザーが選択したテストグループを実行する](#allow-specific-groups)を参照してください。

  テストの実行者向けの IDT CLI コマンドを有効にする方法については「[IDT CLI コマンドを有効にする](create-test-executables.md#idt-cli-coop)」を参照してください。

`ResultVar`  
テスト実行の結果によって設定するコンテキスト変数の名前。`TestGroup` の値を指定しなかった場合は、この値を指定しないでください。IDT は、以下に基づいて、`ResultVar` に定義された変数を `true` または `false` に設定します。  
+ 変数名の形式が `text_text_passed` の場合、この値は、最初のテストグループのすべてのテストが合格したか、スキップされたかに設定されます。
+ それ以外の場合、この値は、すべてのテストグループのすべてのテストが合格したか、スキップされたかに設定されます。

通常、`RunTask` ステートは、個々のテストケース ID を指定せずにテストグループ ID を指定するために使用されます。この指定により、IDT は指定されたテストグループ内のすべてのテストケースを実行します。このステートで実行されるすべてのテストケースは、ランダムな順序で並行して実行されます。ただし、すべてのテストケースが実行に 1 つのデバイスを必要とし、単一のデバイスしか使用できない場合は、テストケースは順次実行されます。

**エラー処理**

指定されたテストグループ ID またはテストケース ID のいずれかが有効でない場合、このステートは `RunTaskError` 実行エラーを発行します。またこのステートは、実行エラーに遭遇すると、ステートマシンコンテキスト内の `hasExecutionError` 変数を `true` に設定します。

### 選択
<a name="state-choice"></a>

`Choice` ステートでは、ユーザー定義の条件に基づいて、移行先の次のステートを動的に設定できます。

```
{
    "Type": "Choice",
    "Default": "<state-name>", 
    "FallthroughOnError": true | false,
    "Choices": [
        {
            "Expression": "<expression>",
            "Next": "<state-name>"
        }
    ]
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`Default`  
`Choices` に定義されているいずれの式も `true` に評価されない場合に移行先になるデフォルトのステート。

`FallthroughOnError`  
オプション。このステートが式評価エラーに遭遇したときの動作を指定します。評価結果がエラーになったときに式をスキップしたい場合は `true` に設定します。一致する式がない場合、ステートマシンは `Default` ステートに移行します。`FallthroughOnError` 値は、指定されない場合、デフォルトで `false` になります。

`Choices`  
現在のステートのアクションを実行した後に移行するステートを決定する式とステートの配列。    
`Choices.Expression`  
ブール値に評価される式文字列。式が `true` と評価された場合、ステートマシンは `Choices.Next` に定義されているステートに移行します。式文字列は、ステートマシンコンテキストから値を取得し、オペレーションを実行してブール値に到達します。ステートマシンコンテキストへのアクセスについては、「[ステートマシンコンテキスト](#state-machine-context)」を参照してください。  
`Choices.Next`  
`Choices.Expression` で定義されている式が `true` に評価された場合の移行先のステート名。

**エラー処理**

以下に示すケースでは、`Choice` ステートでエラー処理が必要になることがあります。
+ choice 式の一部の変数が、ステートマシンのコンテキストに存在しない。
+ 式の結果がブール値ではない。
+ JSON 検索の結果が、文字列、数値、またはブール値ではない。

このステートのエラー処理に `Catch` ブロックを使用することはできません。ステートマシンがエラーに遭遇したときに、その実行を停止するには、`FallthroughOnError` を `false` に設定する必要があります。ただし、`FallthroughOnError` は `true` に設定し、ユースケースに応じて、次のいずれかの操作を実行することをお勧めします。
+ アクセスしている変数が一部のケースに存在しないと考えられる場合は、`Default` の値と追加の `Choices` ブロックを使用して次のステートを指定します。
+ 使用している変数が必ず存在するものである場合は、`Default` ステートを `Fail` に設定します。

### 並行
<a name="state-parallel"></a>

`Parallel` ステートでは、新しいステートマシンを互いに並列に定義して実行できます。

```
{
    "Type": "Parallel",
    "Next": "<state-name>",
    "Branches": [
        <state-machine-definition>
    ]
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`Next`  
現在のステートのアクションを実行した後に移行するステートの名前。

`Branches`  
実行するステートマシン定義の配列。各ステートマシン定義には、それぞれの `StartAt`、`Succeed`、および `Fail` ステートを含める必要があります。この配列内のステートマシン定義は、各自の定義外のステートを参照することはできません。  
各ブランチステートマシンは同じステートマシンコンテキストを共有するため、あるブランチに変数を設定し、別のブランチからそれらの変数を読み込むと、予期しない動作が発生する可能性があります。

`Parallel` ステートは、すべてのブランチステートマシンを実行してから次のステートに移行します。デバイスを必要とする各ステートは、デバイスが利用可能になるまで実行を待ちます。複数のデバイスが利用可能な場合、このステートは並行して複数のグループからテストケースを実行します。十分な数のデバイスが利用できない場合、テストケースは順次実行されます。テストケースは、並列して実行される場合、ランダムな順序で実行されるため、同じテストグループからのテストの実行に異なるデバイスが使用されることがあります。

**エラー処理**

実行エラーを処理するには、ブランチステートマシンと親ステートマシンの両方が、`Fail` ステートに移行していることを確認します。

ブランチステートマシンは親ステートマシンに実行エラーを送信しないため、ブランチステートマシンの実行エラーを処理するために `Catch` ブロックを使用することはできません。代わりに、共有ステートマシンコンテキストの `hasExecutionErrors` 値を使用します。これを行う方法の例については、[ステートマシンの例: 2 つのテストグループを並行して実行する](#run-in-parallel)を参照してください。

### AddProductFeatures
<a name="state-addproductfeatures"></a>

`AddProductFeatures` ステートでは、IDT によって生成される `awsiotdevicetester_report.xml` ファイルに製品機能を追加できます。

製品機能とは、デバイスが満たしている可能性のある特定の基準に関するユーザー定義の情報です。例えば、`MQTT` 製品機能には、デバイスが MQTT メッセージを適切に公開することを指定できます。レポートでは、製品機能は指定されたテストが合格したかどうかに応じて、`supported`、`not-supported`、カスタム値に設定されます。



**注記**  
`AddProductFeatures` ステートだけではレポートは生成されません。レポートを生成するには、このステートが [`Report` ステート](#state-report)に移行する必要があります。

```
{
    "Type": "Parallel",
    "Next": "<state-name>",
    "Features": [
        {
            "Feature": "<feature-name>", 
            "Groups": [
                "<group-id>"
            ],
            "OneOfGroups": [
                "<group-id>"
            ],
            "TestCases": [
                "<test-id>"
            ],
            "IsRequired": true | false,
            "ExecutionMethods": [
                "<execution-method>"
            ]
        }
    ]
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`Next`  
現在のステートのアクションを実行した後に移行するステートの名前。

`Features`  
`awsiotdevicetester_report.xml` ファイルに表示される製品機能の配列。    
`Feature`  
機能の名前。  
`FeatureValue`  
オプション。`supported` の代わりにレポートで使用するカスタム値。この値を指定しない場合、テスト結果に基づいて、機能値は `supported` または `not-supported` に設定されます。  
`FeatureValue` にカスタム値を使用する場合は、同じ機能を異なる条件でテストできます。IDT は、サポート条件の機能値を連結します。例えば、以下の抜粋は、`MyFeature` 機能と 2 つの異なる機能値を示しています。  

```
...
{
    "Feature": "MyFeature",
    "FeatureValue": "first-feature-supported",
    "Groups": ["first-feature-group"]
},
{
    "Feature": "MyFeature",
    "FeatureValue": "second-feature-supported",
    "Groups": ["second-feature-group"]
},
...
```
両方のテストグループが合格した場合、機能値は `first-feature-supported, second-feature-supported` に設定されます。  
`Groups`  
オプション。テストグループ ID の配列。機能をサポートするには、指定された各テストグループ内のすべてのテストが合格である必要があります。  
`OneOfGroups`  
オプション。テストグループ ID の配列。機能をサポートするには、指定されたテストグループうち、少なくとも 1 つのグループに含まれるすべてのテストが合格である必要があります。  
`TestCases`  
オプション。テストケース ID の配列。この値を指定すると、次のことが適用されます。  
+ 機能をサポートするには、指定されたすべてのテストケースが合格である必要があります。
+ `Groups` には、テストグループ ID を 1 つだけ含める必要があります。
+ `OneOfGroups` は指定できません。  
`IsRequired`  
オプション。この機能をレポートでオプション機能としてマークするには、`false` に設定します。デフォルト値は `true` です。  
`ExecutionMethods`  
オプション。`device.json` ファイルに指定された `protocol` 値と一致する実行メソッドの配列。この値を指定した場合、この機能をレポートに含めるには、テストの実行者はこの配列の値の 1 つに一致する `protocol` 値を指定する必要があります。この値を指定しない場合、この機能は常にレポートに含まれます。

`AddProductFeatures` ステートを使用するには、`RunTask` ステートの `ResultVar` の値を以下のいずれかの値に指定する必要があります。
+ 個々のテストケース ID を指定した場合は、`ResultVar` を`group-id_test-id_passed` に指定します。
+ 個々のテストケース ID を指定しなかった場合は、`ResultVar` を`group-id_passed` に指定します。

`AddProductFeatures` ステートは、次の方法でテスト結果をチェックします。
+ テストケース ID を指定しなかった場合は、各テストグループの結果は、ステートマシンコンテキスト内の `group-id_passed` 変数の値から決定されます。
+ テストケース ID を指定した場合は、各テストの結果は、ステートマシンコンテキスト内の `group-id_test-id_passed` 変数の値から決定されます。

**エラー処理**

このステートで指定されたグループ ID が有効なグループ ID でない場合、このステートで `AddProductFeaturesError` 実行エラーが発生します。またこのステートは、実行エラーに遭遇すると、ステートマシンコンテキスト内の `hasExecutionErrors` 変数を `true` に設定します。

### レポートを行う
<a name="state-report"></a>

`Report` ステートでは、`suite-name_Report.xml` ファイルと `awsiotdevicetester_report.xml` ファイルが生成されます。またこのステートでは、レポートがコンソールにストリーミングされます。

```
{
    "Type": "Report",
    "Next": "<state-name>"
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`Next`  
現在のステートのアクションを実行した後に移行するステートの名前。

テストの実行者がテスト結果を確認できるように、テスト実行フローの終了ステートの前に `Report` ステートに移行する必要があります。通常、このステートの次のステートは `Succeed` です。

**エラー処理**

このステートは、レポート生成時に問題に遭遇した場合、`ReportError` 実行エラーを発行します。

### LogMessage
<a name="state-logmessage"></a>

`LogMessage` ステートでは、`test_manager.log` ファイルが生成され、ログメッセージがコンソールにストリーミングされます。

```
{
    "Type": "LogMessage",
    "Next": "<state-name>"
    "Level": "info | warn | error"
    "Message": "<message>"
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`Next`  
現在のステートのアクションを実行した後に移行するステートの名前。

`Level`  
ログメッセージを作成するエラーレベル。有効でないレベルを指定すると、エラーメッセージが生成され、そのレベルは破棄されます。

`Message`  
ログに記録するメッセージ。

### SelectGroup
<a name="state-selectgroup"></a>

`SelectGroup` ステートでは、ステートマシンコンテキストを更新して選択されたグループを示します。このステートで設定した値は、後続のすべての `Choice` ステートによって使用されます。

```
{
    "Type": "SelectGroup",
    "Next": "<state-name>"
    "TestGroups": [
        <group-id>"
    ]
}
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`Next`  
現在のステートのアクションを実行した後に移行するステートの名前。

`TestGroups`  
選択済みとしてマークされるテストグループの配列。この配列の各テストグループ ID について、`group-id_selected` 変数がコンテキストで `true` に設定されます。IDT は、指定されたグループが存在するかどうかを検証しないため、有効なテストグループ ID を指定するようにしてください。

### 失敗
<a name="state-fail"></a>

`Fail` ステートは、ステートマシンが正しく実行されなかったことを示します。これはステートマシンの終了ステートです。各ステートマシンの定義にこのステートを含める必要があります。

```
{
    "Type": "Fail"
}
```

### 成功
<a name="state-succeed"></a>

`Succeed` ステートは、ステートマシンが正しく実行されたことを示します。これはステートマシンの終了ステートです。各ステートマシンの定義にこのステートを含める必要があります。

```
{
    "Type": "Succeed"
}
```

## ステートマシンコンテキスト
<a name="state-machine-context"></a>

ステートマシンコンテキストは、実行中のステートマシンに利用可能なデータが含まれている読み取り専用 JSON ドキュメントです。ステートマシンコンテキストは、ステートマシンからのみアクセス可能で、テストフローを決定する情報が含まれています。例えば、テストの実行者によって `userdata.json` ファイルに設定された情報を使用して、特定のテストを実行する必要があるかどうかを決定できます。

ステートマシンコンテキストでは、次の形式が使用されます。

```
{
    "pool": {
        <device-json-pool-element>
    },
    "userData": {
        <userdata-json-content>
    },
    "config": {
        <config-json-content>
    },
    "suiteFailed": true | false,
    "specificTestGroups": [
        "<group-id>"
    ],
    "specificTestCases": [
        "<test-id>"
    ],
    "hasExecutionErrors": true
}
```

`pool`  
テスト実行用に選択されたデバイスプールに関する情報。選択されたデバイスプールのこの情報は、`device.json` ファイルで定義された、対応する最上位レベルのデバイスプール配列要素から取得されます。

`userData`  
`userdata.json` ファイル内の情報。

`config`  
`config.json` ファイル内の情報。

`suiteFailed`  
この値は、ステートマシンが起動すると `false` に設定されます。テストグループが `RunTask` ステートで失敗した場合、この値はステートマシン実行の残りの時間の間 `true` に設定されます。

`specificTestGroups`  
テストの実行者がテストスイート全体ではなく特定のテストグループを選択して実行する場合に、このキーが作成され、特定のテストグループ ID のリストが格納されます。

`specificTestCases`  
テストの実行者がテストスイート全体ではなく特定のテストケースを選択して実行する場合に、このキーが作成され、特定のテストケース ID のリストが格納されます。

`hasExecutionErrors`  
ステートマシンの起動時には存在しません。いずれかのステートが実行エラーに遭遇した場合に、この変数が作成され、ステートマシンの実行の残りの時間の間 `true` に設定されます。

コンテキストは、JSONPath 表記法を使用してクエリできます。ステート定義における JSonPath クエリの構文は `{{$.query}}` です。JSONPath クエリは、一部のステートではプレースホルダー文字列として使用できます。IDT は、プレースホルダー文字列をコンテキストから評価された JSONPath クエリの値に置き換えます。プレースホルダーは、次の値に使用できます。
+ `RunTask` ステートの `TestCases` 値。
+ `Choice` ステートの `Expression` 値。

ステートマシンコンテキストからデータにアクセスする場合は、次の条件を満たしていることを確認します。
+ JSON パスが `$.` で始まっている。
+ 各値が、文字列、数値、またはブール値として評価される。

JSONPath 表記を使用してコンテキストのデータにアクセスする方法の詳細については、[IDT コンテキストを使用する](idt-context.md)を参照してください。

## 実行エラー
<a name="execution-errors"></a>

実行エラーとは、ステートの実行時にステートマシンが遭遇する、ステートマシン定義内のエラーです。IDT は、各エラーに関する情報を `test_manager.log` ファイルに記録し、ログメッセージをコンソールにストリーミングします。

実行エラーは、次の方法を使用して処理できます。
+ ステート定義内に [`Catch`ブロック](#catch) を追加する。
+ ステートマシンコンテキストで [`hasExecutionErrors` 値](#context) の値を確認する。

### Catch
<a name="catch"></a>

`Catch` を使用するには、ステート定義に以下を追加します。

```
"Catch": [
    {    
        "ErrorEquals": [
            "<error-type>"
        ]
        "Next": "<state-name>" 
    }
]
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`Catch.ErrorEquals`  
キャッチするエラータイプの配列。実行エラーが指定された値のいずれかと一致する場合、ステートマシンは、`Catch.Next` に指定されているステートに移行します。生成されるエラーのタイプの詳細については、各ステート定義を参照してください。

`Catch.Next`  
現在のステートが、`Catch.ErrorEquals` に指定されている値のいずれかと一致する実行エラーに遭遇した場合に、移行する次のステート。

キャッチブロックは、いずれかが一致するまで順番に処理されます。どのエラーもキャッチブロックに指定されているエラーと一致しない場合、ステートマシンは実行を継続します。実行エラーは誤ったステート定義によって発生するため、ステートが実行エラーに遭遇したときは Fail ステートに移行することをお勧めします。

### hasExecutionError
<a name="context"></a>

一部のステートは、実行エラーに遭遇した場合、エラーを発行するだけでなく、ステートマシンコンテキストの `hasExecutionError` 値も `true` に設定します。この値を使用して、エラーがいつ発生したかを特定してから、`Choice` ステートを使用してステートマシンを `Fail` ステートに移行することができます。

この方法には次の特徴があります。
+ ステートマシンは、`hasExecutionError` に値が割り当てられていると開始しません。またこの値は、特定のステートによって設定されるまで得られません。つまり、明示的に `FallthroughOnError` の値を `false` に設定することによって、実行エラーが発生していない場合に、この値にアクセスする `Choice` ステートがステートマシンを停止しないようにする必要があります。
+ `hasExecutionError` は、一度 `true` に設定されると、false に設定されることも、コンテキストから削除されることもありません。つまり、この値は `true` に設定された初回のみ有効であり、以降のすべてのステートに対して意味のある値を提供しないことを意味します。
+ `hasExecutionError` 値は `Parallel` ステート内のすべてのブランチステートマシンで共有されるため、アクセスされる順序によっては、予期せぬ結果が発生する可能性があります。

これらの特性から、代わりに Catch ブロックを使用できる場合は、この方法を使用することはお勧めしません。

## ステートマシンの例
<a name="state-machine-examples"></a>

このセクションでは、ステートマシンの設定の例を紹介します。

**Topics**
+ [ステートマシンの例: 1 つのテストグループを実行する](#single-test-group)
+ [ステートマシンの例: ユーザーが選択したテストグループを実行する](#allow-specific-groups)
+ [ステートマシンの例: 製品機能が含まれる 1 つのテストグループを実行する](#run-with-product-features)
+ [ステートマシンの例: 2 つのテストグループを並行して実行する](#run-in-parallel)

### ステートマシンの例: 1 つのテストグループを実行する
<a name="single-test-group"></a>

このステートマシンの動作:
+ ID `GroupA` のテストグループを実行します。このテストグループは、`group.json` ファイルのスイート内に存在している必要があります。
+ 実行エラーをチェックし、エラーが見つかった場合は `Fail` に移行します。
+ エラーがない場合には、レポートを生成し、`Succeed` に移行します。エラーがある場合は、`Fail` に移行します。

```
{
    "Comment": "Runs a single group and then generates a report.",
    "StartAt": "RunGroupA",
    "States": {
        "RunGroupA": {
            "Type": "RunTask",
            "Next": "Report",
            "TestGroup": "GroupA",
            "Catch": [
                {
                    "ErrorEquals": [
                        "RunTaskError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Report": {
            "Type": "Report",
            "Next": "Succeed",
            "Catch": [
                {
                    "ErrorEquals": [
                        "ReportError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Succeed": {
            "Type": "Succeed"
        },
        "Fail": {
            "Type": "Fail"
        }
    }
}
```

### ステートマシンの例: ユーザーが選択したテストグループを実行する
<a name="allow-specific-groups"></a>

このステートマシンの動作:
+ テストの実行者が特定のテストグループを選択したかどうかをチェックします。テストの実行者がテストケースを選択するには、テストグループも選択する必要があるため、ステートマシンは特定のテストケースはチェックしません。
+ テストグループが選択されている場合: 
  + 選択されたテストグループ内のテストケースを実行します。そのために、ステートマシンは、`RunTask` ステートでは、テストグループまたはテストケースを明示的に指定しません。
  + すべてのテストを実行した後にレポートを生成し、終了します。
+ テストグループが選択されていない場合:
  + テストグループ `GroupA` のテストを実行します。
  + レポートを生成して終了します。

```
{
    "Comment": "Runs specific groups if the test runner chose to do that, otherwise runs GroupA.",
    "StartAt": "SpecificGroupsCheck",
    "States": {
        "SpecificGroupsCheck": {
            "Type": "Choice",
            "Default": "RunGroupA",
            "FallthroughOnError": true,
            "Choices": [
                {
                    "Expression": "{{$.specificTestGroups[0]}} != ''",
                    "Next": "RunSpecificGroups"
                }
            ]
        },
        "RunSpecificGroups": {
            "Type": "RunTask",
            "Next": "Report",
            "Catch": [
                {
                    "ErrorEquals": [
                        "RunTaskError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "RunGroupA": {
            "Type": "RunTask",
            "Next": "Report",
            "TestGroup": "GroupA",
            "Catch": [
                {
                    "ErrorEquals": [
                        "RunTaskError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Report": {
            "Type": "Report",
            "Next": "Succeed",
            "Catch": [
                {
                    "ErrorEquals": [
                        "ReportError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Succeed": {
            "Type": "Succeed"
        },
        "Fail": {
            "Type": "Fail"
        }
    }
}
```

### ステートマシンの例: 製品機能が含まれる 1 つのテストグループを実行する
<a name="run-with-product-features"></a>

このステートマシンの動作:
+ テストグループ `GroupA` を実行します。
+ 実行エラーをチェックし、エラーが見つかった場合は `Fail` に移行します。
+ `FeatureThatDependsOnGroupA` 機能を `awsiotdevicetester_report.xml` ファイルに追加します。
  + `GroupA` が合格である場合、機能を `supported` に設定します。
  + レポートでこの機能をオプションとしてマークしません。
+ エラーがない場合には、レポートを生成し、`Succeed` に移行します。エラーがある場合は、`Fail` に移行します。

```
{
    "Comment": "Runs GroupA and adds product features based on GroupA",
    "StartAt": "RunGroupA",
    "States": {
        "RunGroupA": {
            "Type": "RunTask",
            "Next": "AddProductFeatures",
            "TestGroup": "GroupA",
            "ResultVar": "GroupA_passed",
            "Catch": [
                {
                    "ErrorEquals": [
                        "RunTaskError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "AddProductFeatures": {
            "Type": "AddProductFeatures",
            "Next": "Report",
            "Features": [
                {
                    "Feature": "FeatureThatDependsOnGroupA",
                    "Groups": [
                        "GroupA"
                    ],
                    "IsRequired": true
                }
            ]
        },
        "Report": {
            "Type": "Report",
            "Next": "Succeed",
            "Catch": [
                {
                    "ErrorEquals": [
                        "ReportError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Succeed": {
            "Type": "Succeed"
        },
        "Fail": {
            "Type": "Fail"
        }
    }
}
```

### ステートマシンの例: 2 つのテストグループを並行して実行する
<a name="run-in-parallel"></a>

このステートマシンの動作:
+ `GroupA` および `GroupB` テストグループを並行して実行します。ブランチステートマシンの `RunTask` ステートによってコンテキストに格納された `ResultVar` 変数が `AddProductFeatures` ステートに利用可能になります。
+ 実行エラーをチェックし、エラーが見つかった場合は `Fail` に移行します。このステートマシンは、`Catch` ブロックを使用しません。この方法では、ブランチステートマシンの実行エラーが検出されないためです。
+ 合格したグループに基づいて、`awsiotdevicetester_report.xml` ファイルに機能を追加します。
  + `GroupA` が合格である場合、機能を `supported` に設定します。
  + レポートでこの機能をオプションとしてマークしません。
+ エラーがない場合には、レポートを生成し、`Succeed` に移行します。エラーがある場合は、`Fail` に移行します。

デバイスプールに 2 つのデバイスが設定されている場合、`GroupA` と `GroupB` 両方を同時に実行できます。ただし、`GroupA` または `GroupB` のどちらかに複数のテストが含まれている場合は、両方のデバイスがそれらのテストに割り当てられることがあります。デバイスが 1 つだけ設定されている場合、テストグループは順次実行されます。

```
{
    "Comment": "Runs GroupA and GroupB in parallel",
    "StartAt": "RunGroupAAndB",
    "States": {
        "RunGroupAAndB": {
            "Type": "Parallel",
            "Next": "CheckForErrors",
            "Branches": [
                {
                    "Comment": "Run GroupA state machine",
                    "StartAt": "RunGroupA",
                    "States": {
                        "RunGroupA": {
                            "Type": "RunTask",
                            "Next": "Succeed",
                            "TestGroup": "GroupA",
                            "ResultVar": "GroupA_passed",
                            "Catch": [
                                {
                                    "ErrorEquals": [
                                        "RunTaskError"
                                    ],
                                    "Next": "Fail"
                                }
                            ]
                        },
                        "Succeed": {
                            "Type": "Succeed"
                        },
                        "Fail": {
                            "Type": "Fail"
                        }
                    }
                },
                {
                    "Comment": "Run GroupB state machine",
                    "StartAt": "RunGroupB",
                    "States": {
                        "RunGroupA": {
                            "Type": "RunTask",
                            "Next": "Succeed",
                            "TestGroup": "GroupB",
                            "ResultVar": "GroupB_passed",
                            "Catch": [
                                {
                                    "ErrorEquals": [
                                        "RunTaskError"
                                    ],
                                    "Next": "Fail"
                                }
                            ]
                        },
                        "Succeed": {
                            "Type": "Succeed"
                        },
                        "Fail": {
                            "Type": "Fail"
                        }
                    }
                }
            ]
        },
        "CheckForErrors": {
            "Type": "Choice",
            "Default": "AddProductFeatures",
            "FallthroughOnError": true,
            "Choices": [
                {
                    "Expression": "{{$.hasExecutionErrors}} == true",
                    "Next": "Fail"
                }
            ]
        },
        "AddProductFeatures": {
            "Type": "AddProductFeatures",
            "Next": "Report",
            "Features": [
                {
                    "Feature": "FeatureThatDependsOnGroupA",
                    "Groups": [
                        "GroupA"
                    ],
                    "IsRequired": true
                },
                {
                    "Feature": "FeatureThatDependsOnGroupB",
                    "Groups": [
                        "GroupB"
                    ],
                    "IsRequired": true
                }
            ]
        },
        "Report": {
            "Type": "Report",
            "Next": "Succeed",
            "Catch": [
                {
                    "ErrorEquals": [
                        "ReportError"
                    ],
                    "Next": "Fail"
                }
            ]
        },
        "Succeed": {
            "Type": "Succeed"
        },
        "Fail": {
            "Type": "Fail"
        }
    }
}
```

# IDT テストケース実行可能ファイルを作成する
<a name="create-test-executables"></a>

テストケース実行可能ファイルは、次の方法でテストスイートフォルダ内に作成して配置できます。
+ `test.json` ファイル内の引数または環境変数を使用して実行するテストを決定するテストスイートの場合は、テストスイート全体に対して 1 つのテストケース実行可能ファイルを作成することも、テストスイート内のテストグループごとに 1 つのテスト実行可能ファイルを作成することもできます。
+ 指定したコマンドに基づいて特定のテストを実行するテストスイートの場合は、テストスイート内のテストケースごとに 1 つのテストケース実行可能ファイルを作成します。

テストを作成するユーザーは、ユースケースに適したアプローチを決定し、それに応じてテストケースの実行可能ファイルを設定できます。各 `test.json` ファイルに、正しいテストケース実行可能ファイルのパスを指定していること、および指定した実行可能ファイルが正常に実行されることを確認してください。

すべてのデバイスにテストケースを実行する準備が整うと、IDT は以下のファイルを読み取ります。
+ `test.json`。選択されたテストケースが、開始するプロセスと設定する環境変数を決定するために使用します。
+ `suite.json`。テストスイートが、設定する環境変数を決定するために使用します。

IDT は、`test.json` ファイルで指定されているコマンドと引数に基づいて、必要なテスト実行可能プロセスを開始し、必要な環境変数をプロセスに渡します。

## IDT クライアント SDK を使用する
<a name="idt-client-sdk"></a>

IDT クライアント SDK を使用すると、IDT とテスト対象のデバイスとのやり取りに使用できる API コマンドを使用して、テスト実行可能ファイルにテストロジックを簡単に記述できます。現在、IDT では次の SDK が用意されています。
+ IDT クライアント SDK for Python
+ IDT クライアント SDK for Go
+ IDT Client SDK for Java

これらの SDK は、`<device-tester-extract-location>/sdks` フォルダにあります。新しいテストケース実行可能ファイルを作成するときは、使用する SDK をテストケース実行可能ファイルが含まれるフォルダにコピーし、コード内で SDK を参照する必要があります。このセクションでは、テストケースの実行可能ファイルで使用できる API コマンドについて簡単に説明します。

**Topics**
+ [デバイスとのやり取り](#api-device-interaction)
+ [IDT とのやり取り](#api-idt-interaction)
+ [ホストとのやり取り](#api-host-interaction)

### デバイスとのやり取り
<a name="api-device-interaction"></a>

次のコマンドを使用すると、デバイスとのやり取りや接続管理のための追加の関数を実装せずに、テスト対象デバイスと通信することができます。

`ExecuteOnDevice`  
テストスイートが、SSH または Docker シェル接続をサポートするデバイス上で、シェルコマンドを実行できるようにします。

`CopyToDevice`  
テストスイートが、IDT を実行するホストマシンから、SSH または Docker シェル接続をサポートするデバイス上の指定された場所にローカルファイルをコピーできるようにします。

`ReadFromDevice`  
テストスイートが、UART 接続をサポートするデバイスのシリアルポートから読み取りできるようにします。

**注記**  
IDT は、コンテキストからのデバイスアクセス情報を使用して確立されたデバイスへの直接接続を管理しないため、テストケース実行可能ファイルでは、デバイスとやり取り用のこれらの API コマンドを使用することをお勧めします。ただし、これらのコマンドがテストケースの要件を満たしていない場合は、IDT コンテキストからデバイスアクセス情報を取得し、この情報を使用してテストスイートからデバイスに直接接続できます。  
直接接続するには、テスト対象デバイスとリソースデバイスそれぞれの `device.connectivity` フィールドと `resource.devices.connectivity` フィールドの情報を取得します。IDT コンテキスト使用の詳細については、[IDT コンテキストを使用する](idt-context.md)を参照してください。

### IDT とのやり取り
<a name="api-idt-interaction"></a>

次のコマンドを使用すると、テストスイートが IDT と通信できるようになります。

`PollForNotifications`  
テストスイートが IDT からの通知をチェックできるようにします。

`GetContextValue ` および `GetContextString`   
テストスイートが IDT コンテキストから値を取得できるようにします。詳細については、[IDT コンテキストを使用する](idt-context.md) を参照してください。

`SendResult`  
テストスイートがテストケースの結果を IDT にレポートできるようにします。このコマンドは、テストスイートの各テストケースの最後に呼び出す必要があります。

### ホストとのやり取り
<a name="api-host-interaction"></a>

次のコマンドを使用すると、テストスイートがホストマシンと通信できるようになります。

`PollForNotifications`  
テストスイートが IDT からの通知をチェックできるようにします。

`GetContextValue ` および `GetContextString`   
テストスイートが IDT コンテキストから値を取得できるようにします。詳細については、[IDT コンテキストを使用する](idt-context.md) を参照してください。

`ExecuteOnHost`  
テストスイートがローカルマシン上でコマンドを実行できるようにし、IDT がテストケース実行可能ファイルのライフサイクルを管理できるようにします。

## IDT CLI コマンドを有効にする
<a name="idt-cli-coop"></a>

`run-suite` コマンド IDT CLI には、テストの実行者がテスト実行をカスタマイズするためのいくつかのオプションがあります。テストの実行者がこれらのオプションを使用してカスタムテストスイートを実行できるようにするには、IDT CLI のサポートを実装します。サポートを実装しなくてもテストは実行できますが、一部の CLI オプションは正しく機能しません。理想的なカスタマーエクスペリエンスを提供するために、IDT CLI で `run-suite` コマンドの次の引数のサポートを実装することをお勧めします。

`timeout-multiplier`  
テストの実行中にすべてのタイムアウトに適用される 1.0 より大きい値を指定します。  
テストの実行者は、この引数を使用して、実行するテストケースのタイムアウトを増やすことができます。テストの実行者が `run-suite` コマンドにこの引数を指定すると、IDT はこの値を使用して IDT\$1TEST\$1TIMEOUT 環境変数の値を計算し、IDT コンテキストの `config.timeoutMultiplier` フィールドを設定します。この引数をサポートするには、以下の手順を実行する必要があります。  
+ `test.json` ファイルのタイムアウト値を直接使用する代わりに、IDT\$1TEST\$1TIMEOUT 環境変数を読み取り、正しく計算されたタイムアウト値を取得します。
+ IDT コンテキストから `config.timeoutMultiplier` 値を取得し、長時間実行されるタイムアウトに適用します。
タイムアウトイベントによる早期終了の詳細については、[終了動作を指定する](#test-exec-exiting)を参照してください。

`stop-on-first-failure`  
障害が発生した場合に、IDT がすべてのテスト実行を停止するように指定します。  
テストの実行者がこの引数を `run-suite` コマンドを指定すると、IDT は障害が発生するとすぐにテストの実行を停止します。ただし、テストケースが並行して実行されている場合、この設定によって予期しない結果につながる可能性があります。このサポートを実装するには、テストロジックを使用して、IDT がこのイベントに遭遇した場合に、実行中のすべてのテストケースに対して、実行を停止し、一時リソースをクリーンアップし、テスト結果を IDT にレポートするように指示します。障害発生時の早期終了の詳細については、[終了動作を指定する](#test-exec-exiting)を参照してください。

`group-id` および `test-id`   
IDT が選択されたテストグループまたはテストケースのみを実行するように指定します。  
テストの実行者は、`run-suite` コマンドでこれらの引数を使用して、以下のテスト実行可能ファイルの動作を指定できます。  
+ 指定されたテストスイート内のすべてのテストグループを実行する。
+ 指定されたテストグループ内から選択したテストを実行する。
これらの引数をサポートするには、テストスイート用のステートオーケストレーターに、自分のテストオーケストレーターの `RunTask` ステートおよび `Choice` ステートのセットが含まれている必要があります。カスタムステートマシンを使用しない場合は、デフォルトの IDT テストオーケストレーターに必要なステートが含まれているため、追加のアクションを行う必要はありません。ただし、カスタムテストオーケストレーターを使用している場合は、サンプルとして [ステートマシンの例: ユーザーが選択したテストグループを実行する](idt-state-machine.md#allow-specific-groups) を使用して、自分のテストオーケストレーターに必要なステートを追加してください。

IDT CLI コマンドの詳細については、[カスタムテストスイートのデバッグと実行](run-debug-custom-tests.md)を参照してください。

## イベントログの書き込み
<a name="test-exec-logs"></a>

テストの実行中は、イベントログとエラーメッセージをコンソールに書き込むために `stdout` と `stderr` にデータを送信します。コンソールメッセージの形式の詳細については、[コンソールメッセージの形式](idt-review-results-logs.md#idt-console-format)を参照してください。

IDT がテストスイートの実行を終了すると、この情報は `<devicetester-extract-location>/results/<execution-id>/logs` フォルダにある `test_manager.log` ファイルでも利用可能になります。

各テストケースは、テスト実行のログ (テスト対象デバイスのログを含む) を `<device-tester-extract-location>/results/execution-id/logs` フォルダにある `<group-id>_<test-id>` ファイルに書き込むように設定できます。これを行うには、`testData.logFilePath` クエリを使用して IDT コンテキストからログファイルへのパスを取得し、そのパスにファイルを作成し、必要なコンテンツをそのファイルに書き込みます。IDT は、実行中のテストケースに基づいてこのパスを自動的に更新します。テストケースのログファイルを作成しないことを選択すると、そのテストケースのファイルは生成されません。

また、必要に応じて `<device-tester-extract-location>/logs` フォルダに追加のログファイルを作成するようにテキスト実行可能ファイルをセットアップすることもできます。ファイルが上書きされないように、ログファイル名に一意のプレフィックスを指定することをお勧めします。

## IDT に結果をレポートする
<a name="test-exec-results"></a>

IDT は、テスト結果を `awsiotdevicetester_report.xml` ファイルと `suite-name_report.xml` ファイルに書き込みます。これらのレポートファイルは、`<device-tester-extract-location>/results/<execution-id>/` にあります。両レポートとも、テストスイート実行の結果をキャプチャします。IDT がこれらのレポートに使用するスキーマの詳細については、[IDT テストの結果とログを確認する](idt-review-results-logs.md)を参照してください。

`suite-name_report.xml` ファイルのコンテンツを取得するには、`SendResult` コマンドを使用して、テスト実行が終了する前に、テスト結果を IDT にレポートする必要があります。IDT は、テスト結果を見つけられない場合、テストケースのエラーを発行します。次の Python の抜粋は、テスト結果を IDT に送信するコマンドを示しています。

```
request-variable = SendResultRequest(TestResult(result))
client.send_result(request-variable)
```

API を使用して結果をレポートしない場合、IDT はテストアーティファクトフォルダでテスト結果を検索します。このフォルダのパスは、IDT コンテキストの `testData.testArtifactsPath` フィールドに格納されています。このフォルダで、IDT は、アルファベット順にソートされた最初の XML ファイルをテスト結果として使用します。

テストロジックが JUnit XML 結果を生成する場合は、結果を解析してから API を使用して IDT に送信する代わりに、アーティファクトフォルダ内の XML ファイルにテスト結果を書き込んで、直接 IDT に提供することができます。

この方法を使用する場合は、テストロジックによってテスト結果が正確に要約されていること、および `suite-name_report.xml` ファイルと同じ形式で結果ファイルがフォーマットされていることを確認してください。IDT は、次の例外を除き、提供されたデータの検証を実行しません。
+ IDT は `testsuites` タグのすべてのプロパティを無視します。代わりに、レポートされた他のテストグループ結果からタグのプロパティを計算します。
+ `testsuite` 内に少なくとも 1 つの `testsuites` タグが存在する必要があります。

IDT はすべてのテストケースで同じアーティファクトフォルダを使用し、テスト実行の終了後、次のテスト実行までに結果ファイルを削除しないため、この方法を使用すると、IDT が正しくないファイルを読み取った場合に、誤ったレポートが行われる可能性もあります。IDT が適切な結果を読み取れるように、すべてのテストケースで生成される XML 結果ファイルに同じ名前を使用して、各テストケースの結果を上書きすることをお勧めします。テストスイートのレポート作成に複合的なアプローチ (一部のテストケースには XML 結果ファイルを使用し、他のテストケースには API を使用して結果を送信する) を使用することもできますが、このアプローチはお勧めしません。

## 終了動作を指定する
<a name="test-exec-exiting"></a>

テキスト実行可能ファイルは、テストケースが障害やエラー結果をレポートした場合でも、常に終了コード 0 で終了するように設定します。ゼロ以外の終了コードは、テストケースが実行されなかったこと、またはテストケース実行可能ファイルが結果を IDT に通知できなかったことを示す場合にのみ使用します。IDT は、0 以外の終了コードを受信すると、テスト実行を妨げるエラーが発生したとしてテストケースをマークします。

IDT は、以下に示すイベントが発生すると、終了前にテストケースに実行の停止を要求 (または想定) することがあります。以下の情報を使用して、テストケースから以下の各イベントを検出するようにテストケース実行可能ファイルを設定します。

**タイムアウト**  
テストケースが、`test.json` ファイルで指定されたタイムアウト値よりも長く実行されたときに発生します。テストの実行者が `timeout-multiplier` 引数を使用してタイムアウト乗数を指定すると、IDT はこの乗数を使用してタイムアウト値を計算します。  
このイベントを検出するには、IDT\$1TEST\$1TIMEOUT 環境変数を使用します。テストの実行者がテストを起動すると、IDT は IDT\$1TEST\$1TIMEOUT 環境変数の値を計算されたタイムアウト値 (秒単位) に設定し、その変数をテストケース実行可能ファイルに渡します。この変数の値を読み取って適切なタイマーを設定します。

**割り込み**  
テストの実行者が IDT に割り込むと発生します。例えば、Ctrl\$1C を押した時です。  
ターミナルはすべての子プロセスに通知を伝播するため、割り込み通知を検出する通知ハンドラをテストケースに簡単に設定できます。  
または、API を定期的にポーリングして、`PollForNotifications` API 応答の `CancellationRequested` ブール値をチェックできます。IDT は割り込み通知を受信すると、`CancellationRequested` ブールの値を `true` に設定します。

**最初の失敗時に停止する**  
現在のテストケースと並行して実行中のテストケースが失敗し、テストの実行者が `stop-on-first-failure` 引数を使用して、障害の発生時に IDT が実行を停止するように設定しているときに発生します。  
このイベントを検出するには、`PollForNotifications` API を定期的にポーリングして、API レスポンスの `CancellationRequested` ブールの値をチェックします。IDT は、最初の障害発生時に停止するように設定されている場合、障害に遭遇すると、`CancellationRequested` ブールの値を `true` に設定します。

これらのいずれかのイベントが発生すると、IDT は現在実行中のテストケースの実行が終了するまで 5 分間待機します。実行中のすべてのテストケースが 5 分以内に終了しない場合、IDT は各プロセスを強制的に停止させます。IDT は、プロセスの終了前にテスト結果を受け取らなかった場合、テストケースをタイムアウトしたとしてマークします。ベストプラクティスとして、いずれかのイベントが発生したときは、テストケースが以下のアクションを実行するようにします。

1. 通常のテストロジックの実行を停止する。

1. テスト対象デバイスのテストアーティファクトなど、すべての一時的なリソースをクリーンアップする。

1. テスト結果 (テストの失敗やエラーなど) を IDT にレポートする。

1. 終了する。

# IDT コンテキストを使用する
<a name="idt-context"></a>

IDT がテストスイートを実行するとき、テストスイートは、各テストの実行方法の決定に使用できる一連のデータにアクセスできます。このデータは IDT コンテキストと呼ばれます。例えば、テストの実行者によって `userdata.json` ファイルに提供されるユーザーデータ設定は、IDT コンテキスト内でテストスイートに提供されます。

IDT コンテキストは、読み取り専用の JSON ドキュメントと考えることができます。テストスイートは、オブジェクト、配列、数値などの標準 JSON データ型を使用して、コンテキストからデータを取得することや、コンテキストにデータを書き込むことができます。

## コンテキストスキーマ
<a name="idt-context-schema"></a>

IDT コンテキストは次の形式を使用します。

```
{
    "config": {
        <config-json-content>
        "timeoutMultiplier": timeout-multiplier
    },
    "device": {
        <device-json-device-element>
    },
    "devicePool": {
        <device-json-pool-element>
    },
    "resource": {
        "devices": [
            {
                <resource-json-device-element>
                "name": "<resource-name>"
            }
        ]
    },
    "testData": {
        "awsCredentials": {
            "awsAccessKeyId": "<access-key-id>",
            "awsSecretAccessKey": "<secret-access-key>",
            "awsSessionToken": "<session-token>"
        },
        "logFilePath": "/path/to/log/file"
    },
    "userData": {
        <userdata-json-content>
    }
}
```

`config`  
[`config.json` ファイル](set-custom-idt-config.md#config-json-custom) からの情報。`config` フィールドには、次の追加フィールドも含まれます。    
`config.timeoutMultiplier`  
テストスイートによって使用される任意のタイムアウト値の乗数。この値は、IDT CLI からテストの実行者によって指定されます。デフォルト値は `1` です。

`device`  
テスト実行用に選択されたデバイスに関する情報。この情報は、選択されたデバイスの [`device.json` ファイル](set-custom-idt-config.md#device-config-custom) の `devices` 配列要素に相当します。

`devicePool`  
テスト実行用に選択されたデバイスプールに関する情報。この情報は、選択されたデバイスプールの `device.json` ファイルに定義されている最上位レベルのデバイスプール配列要素に相当します。

`resource`  
`resource.json` ファイルからのリソースデバイスに関する情報。    
`resource.devices`  
この情報は、`devices` ファイルに定義されている `resource.json` 配列に相当します。各 `devices` 要素には、以下の追加フィールドが含まれています。    
`resource.device.name`  
リソースデバイスの名前。この値は、`test.json` ファイルで `requiredResource.name` 値に設定されます。

`testData.awsCredentials`  
AWS クラウドに接続するためにテストによって使用される AWS 認証情報。この情報は、`config.json` ファイルから取得されます。

`testData.logFilePath`  
テストケースがログメッセージを書き込むログファイルへのパス。このファイルは、存在しない場合、テストスイートによって作成されます。

`userData`  
テストの実行者によって [`userdata.json` ファイル](set-custom-idt-config.md#userdata-config-custom) に提供された情報。

## コンテキスト内のデータにアクセスする
<a name="accessing-context-data"></a>

コンテキストは、JSONPath 表記を使用して JSON ファイルからクエリすることも、`GetContextValue` および `GetContextString` API を使用してテキスト実行可能ファイルからクエリすることもできます。IDT コンテキストにアクセスするための JSONPath 文字列の構文は、次のように異なります。
+ `suite.json` および `test.json` では、`{{query}}` を使用します。つまり、式を開始するためにルート要素 `$.` を使用しません。
+ `test_orchestrator.yaml` では `{{query}}` を使用します。

  非推奨のステートマシンを使用する場合、`state_machine.json` では `{{$.query}}` を使用します。
+ API コマンドでは、コマンドに応じて `query` または `{{$.query}}` を使用します。詳細については、SDK のインラインドキュメントを参照してください。

次の表に、一般的な JSONPath 式の演算子を示します。


| Operator  | Description  | 
| --- |--- |
| \$1 | The root element. Because the top-level context value for IDT is an object, you will typically use \$1. to start your queries. | 
| .childName | Accesses the child element with name childName from an object. If applied to an array, yields a new array with this operator applied to each element. The element name is case sensitive. For example, the query to access the awsRegion value in the config object is \$1.config.awsRegion. | 
| [start:end] | Filters elements from an array, retrieving items beginning from the 開始 index and going up to the 終了 index, both inclusive. | 
| [index1, index2, ... , indexN] | Filters elements from an array, retrieving items from only the specified indices. | 
| [?(expr)] | Filters elements from an array using the expr expression. This expression must evaluate to a boolean value. | 

フィルター式を作成するには、次の構文を使用します。

```
<jsonpath> | <value> operator <jsonpath> | <value> 
```

この構文の説明は次のとおりです。
+ `jsonpath` は、標準 JSON 構文を使用する JSONPath です。
+ `value` は、標準 JSON 構文を使用するカスタム値です。
+ `operator` は、以下のいずれかの演算子です。
  + `<` (未満)
  + `<=` (以下)
  + `==` (等しい)

    式内の JSONPath または値が配列、ブール値、またはオブジェクト値である場合は、これがユーザーに使用可能な唯一の二項演算子です。
  + `>=` (以上)
  + `>` (次より大きい)
  + `=~` (正規表現の一致)。この演算子をフィルター式で使用するには、式の左側の JSONPath または値が文字列に評価される必要があり、右側が [RE2 構文](https://github.com/google/re2/wiki/Syntax) に従ったパターン値である必要があります。

\$1\$1*query*\$1\$1 形式の JSONPath クエリは、プレースホルダ文字列として、`test.json` ファイルの `args` および `environmentVariables` フィールド内と、`suite.json` ファイルの `environmentVariables` フィールド内で使用できます。IDT はコンテキスト検索を実行し、クエリの評価値をフィールドに入力します。例えば、`suite.json` ファイルでは、プレースホルダー文字列を使用して、各テストケースとともに変化する環境変数の値を指定できます。IDT は、環境変数に各テストケースの正しい値を入力します。ただし、`test.json` ファイルおよび `suite.json` ファイルでプレースホルダー文字列を使用する場合は、クエリに次の考慮事項が適用されます。
+ クエリに含まれる各 `devicePool` キーは、すべて小文字にする必要があります。つまり、代わりに `devicepool` を使用します。
+ 配列には、文字列の配列のみを使用できます。さらに、配列は非標準の `item1, item2,...,itemN` の形式を使用します。配列は、要素が 1 つしか含まれていない場合、`item` としてシリアル化され、文字列フィールドと区別がつかなくなります。
+ プレースホルダーを使用してコンテキストからオブジェクトを取得することはできません。

これらの事項を考慮して、テストロジックのコンテキストへのアクセスには、`test.json` ファイルおよび `suite.json` ファイルのプレースホルダー文字列ではなく、可能な限り API を使用することをお勧めします。ただし、環境変数として設定する単一の文字列を取得するときは、JSONPath プレースホルダーを使用する方が便利な場合があります。

# テストの実行者向けの設定の設定
<a name="set-custom-idt-config"></a>

カスタムテストスイートを実行するには、テストの実行者は、実行するテストスイートに基づいて設定を設定する必要があります。設定は、`<device-tester-extract-location>/configs/` フォルダにある設定ファイルテンプレートに基づいて指定します。必要に応じて、テストの実行者は、IDT が AWS クラウドへの接続に使用する AWS 認証情報も設定する必要があります。

テストを作成するユーザーは、[テストスイートをデバッグする](run-debug-custom-tests.md)ために、以下に示すファイルの設定が必要になります。また、テストスイートを実行するために必要な以下の設定を設定できるように、テストの実行者に指示を提供する必要があります。

## device.json の設定
<a name="device-config-custom"></a>

`device.json` ファイルには、テストが実行されるデバイスに関する情報 (IP アドレス、ログイン情報、オペレーティングシステム、CPU アーキテクチャなど) が含まれています。

テストの実行者は、`<device-tester-extract-location>/configs/` フォルダにある次のテンプレート `device.json` ファイルを使用してこの情報を指定できます。

```
[
    {
        "id": "<pool-id>",
        "sku": "<pool-sku>",
        "features": [
            {
                "name": "<feature-name>",             
                "value": "<feature-value>",                
                "configs": [
                    {
                        "name": "<config-name>",                    
                        "value": "<config-value>"
                    }
                ],
            }
        ],     
        "devices": [
            {
                "id": "<device-id>",              
                "connectivity": {
                    "protocol": "ssh | uart | docker",                   
                    // ssh
                    "ip": "<ip-address>",
                    "port": <port-number>,
                    "auth": {
                        "method": "pki | password",
                        "credentials": {
                            "user": "<user-name>", 
                            // pki
                            "privKeyPath": "/path/to/private/key",
                                         
                            // password
                            "password": "<password>",
                        }
                    },
                    
                    // uart
                    "serialPort": "<serial-port>",
                    
                    // docker
                    "containerId": "<container-id>",
                    "containerUser": "<container-user-name>",
                }
            }
        ]
    }
]
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`id`  
*デバイスプール*と呼ばれるデバイスのコレクションを一意に識別するユーザー定義の英数字の ID。プールに属するデバイスには、同一のハードウェアが必要です。テストスイートを実行する場合、プールのデバイスを使用してワークロードを並列化します。複数のデバイスを使用して異なるテストを実行します。

`sku`  
テスト対象デバイスを一意に識別する英数字の値。SKU は、認定されたデバイスの追跡に使用されます。  
AWS Partner Device Catalog にボードを出品する場合は、ここで指定する SKU と出品プロセスで使用する SKU が一致しなければなりません。

`features`  
オプション。デバイスでサポートされている機能を含む配列。デバイス機能は、テストスイートに設定するユーザー定義の値です。テストの実行者に、`device.json` ファイルに含める機能名および値に関する情報を提供する必要があります。例えば、他のデバイスの MQTT サーバーとして機能するデバイスをテストする場合は、`MQTT_QOS` という名前の機能に対する特定のサポートレベルを検証するようにテストロジックを設定します。テストの実行者は、この機能名を指定し、デバイスによってサポートされる QOS レベルにその機能値を設定します。指定された情報は、`devicePool.features` クエリを使用して [[IDT context]](idt-context.md) (IDT コンテキスト) から、または `pool.features` クエリを使用して[[test orchestrator context]](idt-state-machine.md#state-machine-context) (テストオーケストレーターコンテキスト) から取得できます。    
`features.name`  
機能の名前。  
`features.value`  
サポートされている機能値。  
`features.configs`  
機能の構成設定 (必要な場合)。    
`features.config.name`  
構成設定の名前。  
`features.config.value`  
サポートされている設定値。

`devices`  
テスト対象のプール内のデバイスの配列。少なくとも 1 つのデバイスが必要です。  <a name="device-array-fields"></a>  
`devices.id`  
テスト対象のデバイスのユーザー定義の一意の識別子。  
`connectivity.protocol`  
このデバイスと通信するために使用される通信プロトコル。プール内の各デバイスは、同じプロトコルを使用する必要があります。  
現在、サポートされている値は、物理デバイス用の `ssh` および `uart` と、Docker コンテナ用の `docker` のみです。  
`connectivity.ip`  
テスト対象のデバイスの IP アドレス。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。  
`connectivity.port`  
オプション。SSH 接続に使用するポート番号。  
デフォルト値は 22 です。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。  
`connectivity.auth`  
接続の認証情報。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。    
`connectivity.auth.method`  
指定された接続プロトコルを介してデバイスにアクセスするために使用される認証方法。  
サポートされている値は以下のとおりです。  
+ `pki`
+ `password`  
`connectivity.auth.credentials`  
認証に使用される認証情報。    
`connectivity.auth.credentials.password`  
テスト中のデバイスにサインインするためのパスワード。  
この値は、`connectivity.auth.method` が `password` に設定されている場合にのみ適用されます。  
`connectivity.auth.credentials.privKeyPath`  
テスト中のデバイスにサインインするためのプライベートキーへの完全パス。  
この値は、`connectivity.auth.method` が `pki` に設定されている場合にのみ適用されます。  
`connectivity.auth.credentials.user`  
テスト対象デバイスにサインインするためのユーザー名。  
`connectivity.serialPort`  
オプション。デバイスが接続されているシリアルポート。  
このプロパティは、`connectivity.protocol` が `uart` に設定されている場合にのみ適用されます。  
`connectivity.containerId`  
テスト対象の Docker コンテナのコンテナ ID または名前。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。  
`connectivity.containerUser`  
オプション。コンテナ内のユーザー名。デフォルト値は Dockerfile で指定されたユーザーです。  
デフォルト値は 22 です。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。
テストの実行者がテストに対して誤ったデバイス接続を設定しているかどうかを確認するには、テストオーケストレーターコンテキストから `pool.Devices[0].Connectivity.Protocol` を取得し、この値を `Choice` ステート内の予想値と比較します。正しくないプロトコルが使用されている場合は、`LogMessage` ステートを使用してメッセージを出力し、`Fail` ステートに移行します。  
または、エラー処理コードを使用して、誤ったデバイスタイプによるテスト失敗をレポートすることもできます。

## (オプション) userdata.json の設定
<a name="userdata-config-custom"></a>

`userdata.json` ファイルには、`device.json` ファイルには指定されていない、テストスイートに必要とされる追加情報が含まれています。このファイルの形式は、テストスイートに定義されている [`userdata_scheme.json` ファイル](idt-json-config.md#userdata-schema-json)によって異なります。テストを作成するユーザーは、作成したテストスイートを実行するユーザーにこの情報を提供してください。

## (オプション) resource.json の設定
<a name="resource-config-custom"></a>

`resource.json` ファイルには、リソースデバイスとして使用されるすべてのデバイスに関する情報が含まれています。リソースデバイスは、テスト対象のデバイスの特定の機能をテストするために必要なデバイスです。例えば、デバイスの Bluetooth 機能をテストするには、リソースデバイスを使用して、デバイスがリソースデバイスに正常に接続できるかどうかをテストできます。リソースデバイスはオプションで、必要な数だけリソースデバイスを要求できます。テストを作成するユーザーは、[test.json ファイル](idt-json-config.md#test-json) を使用して、テストに必要なリソースデバイスの機能を定義します。テストの実行者は、`resource.json` ファイルを使用して、必要な機能を持つリソースデバイスのプールを指定します。作成したテストスイートを実行するユーザーに、以下の情報を提供してください。

テストの実行者は、`<device-tester-extract-location>/configs/` フォルダにある次のテンプレート `resource.json` ファイルを使用してこの情報を指定できます。

```
[
    {
        "id": "<pool-id>",
        "features": [
            {
                "name": "<feature-name>",             
                "version": "<feature-version>",                
                "jobSlots": <job-slots>
            }
        ],     
        "devices": [
            {
                "id": "<device-id>",              
                "connectivity": {
                    "protocol": "ssh | uart | docker",                   
                    // ssh
                    "ip": "<ip-address>",
                    "port": <port-number>,
                    "auth": {
                        "method": "pki | password",
                        "credentials": {
                            "user": "<user-name>", 
                            // pki
                            "privKeyPath": "/path/to/private/key",
                                         
                            // password
                            "password": "<password>",
                        }
                    },
                    
                    // uart
                    "serialPort": "<serial-port>",
                    
                    // docker
                    "containerId": "<container-id>",
                    "containerUser": "<container-user-name>",
                }
            }
        ]
    }
]
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

`id`  
デバイスプールと呼ばれるデバイスのコレクションを一意に識別するユーザー定義の英数字の ID。プールに属するデバイスには、同一のハードウェアが必要です。テストスイートを実行する場合、プールのデバイスを使用してワークロードを並列化します。複数のデバイスを使用して異なるテストを実行します。

`features`  
オプション。デバイスでサポートされている機能を含む配列。このフィールドに必要な情報は、テストスイートの [test.json ファイル](idt-json-config.md#test-json) に定義されています。この情報によって、実行するテストと、テストの実行方法が決まります。テストスイートに機能が必要ない場合は、このフィールドは必須ではありません。    
`features.name`  
機能の名前。  
`features.version`  
機能バージョン。  
`features.jobSlots`  
デバイスを同時に使用できるテストの数を示すための設定。デフォルト値は `1` です。

`devices`  <a name="device-array"></a>
テスト対象のプール内のデバイスの配列。少なくとも 1 つのデバイスが必要です。  <a name="device-array-fields"></a>  
`devices.id`  
テスト対象のデバイスのユーザー定義の一意の識別子。  
`connectivity.protocol`  
このデバイスと通信するために使用される通信プロトコル。プール内の各デバイスは、同じプロトコルを使用する必要があります。  
現在、サポートされている値は、物理デバイス用の `ssh` および `uart` と、Docker コンテナ用の `docker` のみです。  
`connectivity.ip`  
テスト対象のデバイスの IP アドレス。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。  
`connectivity.port`  
オプション。SSH 接続に使用するポート番号。  
デフォルト値は 22 です。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。  
`connectivity.auth`  
接続の認証情報。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。    
`connectivity.auth.method`  
指定された接続プロトコルを介してデバイスにアクセスするために使用される認証方法。  
サポートされている値は以下のとおりです。  
+ `pki`
+ `password`  
`connectivity.auth.credentials`  
認証に使用される認証情報。    
`connectivity.auth.credentials.password`  
テスト中のデバイスにサインインするためのパスワード。  
この値は、`connectivity.auth.method` が `password` に設定されている場合にのみ適用されます。  
`connectivity.auth.credentials.privKeyPath`  
テスト中のデバイスにサインインするためのプライベートキーへの完全パス。  
この値は、`connectivity.auth.method` が `pki` に設定されている場合にのみ適用されます。  
`connectivity.auth.credentials.user`  
テスト対象デバイスにサインインするためのユーザー名。  
`connectivity.serialPort`  
オプション。デバイスが接続されているシリアルポート。  
このプロパティは、`connectivity.protocol` が `uart` に設定されている場合にのみ適用されます。  
`connectivity.containerId`  
テスト対象の Docker コンテナのコンテナ ID または名前。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。  
`connectivity.containerUser`  
オプション。コンテナ内のユーザー名。デフォルト値は Dockerfile で指定されたユーザーです。  
デフォルト値は 22 です。  
このプロパティは、`connectivity.protocol` が `ssh` に設定されている場合にのみ適用されます。

## (オプション) config.json の設定
<a name="config-json-custom"></a>

`config.json` ファイルには、IDT 向けの設定情報が含まれています。通常、テストの実行者は、IDT 用の AWS ユーザー認証情報、AWS リージョン (オプション) を指定することを除き、このファイルを変更する必要はありません。必要なアクセス許可が付与される AWS 認証情報が指定されると、AWS IoT Device Tester は使用状況メトリクスを収集して AWS に送信します。これはオプトイン機能で、IDT 機能を改善するために使用されます。詳細については、[IDT 使用状況メトリクス](idt-usage-metrics.md) を参照してください。

テストの実行者は、以下のいずれかの方法で AWS 認証情報を入手します。
+ **認証情報ファイル**

  IDT では、AWS CLI と同じ認証情報ファイルが使用されます。詳細については、「[設定ファイルと認証情報ファイル](https://docs.aws.amazon.com/cli/latest/userguide/cli-config-files.html)」を参照してください。

  認証情報ファイルの場所は、使用しているオペレーティングシステムによって異なります。
  + macOS、Linux: `~/.aws/credentials`
  + Windows: `C:\Users\UserName\.aws\credentials`
+ **環境変数**

  環境変数は、オペレーティングシステムによって維持され、システムコマンドによって使用される変数です。SSH セッション中に定義された変数は、そのセッションの終了後は使用できません。IDT は、環境変数の `AWS_ACCESS_KEY_ID` と `AWS_SECRET_ACCESS_KEY` を使用して AWS 認証情報を保存します。

  これらの変数を Linux、macOS、または Unix で設定するには、 を使用します**export**

  ```
  export AWS_ACCESS_KEY_ID=<your_access_key_id>
  export AWS_SECRET_ACCESS_KEY=<your_secret_access_key>
  ```

  Windows でこれらの変数を設定するには、 を使用します**set**

  ```
  set AWS_ACCESS_KEY_ID=<your_access_key_id>
  set AWS_SECRET_ACCESS_KEY=<your_secret_access_key>
  ```

IDT 用の AWS 認証情報を設定するには、テストの実行者は、`auth` フォルダにある `config.json` ファイルの `<device-tester-extract-location>/configs/` セクションを編集します。

```
{
    "log": {
        "location": "logs"
    },
    "configFiles": {
        "root": "configs",
        "device": "configs/device.json"
    },
    "testPath": "tests",
    "reportPath": "results",
    "awsRegion": "<region>",
    "auth": {
        "method": "file | environment",
        "credentials": {
            "profile": "<profile-name>"
        }
    }
}
]
```

以下に説明するように、値が含まれているすべてのフィールドは必須です。

**注記**  
このファイル内のすべてのパスは、*<device-tester-extract-location>* に関連して定義されています。

`log.location`  
*<device-tester-extract-location>* のログフォルダへのパス。

`configFiles.root`  
設定ファイルが含まれるフォルダへのパス。

`configFiles.device`  
`device.json` ファイルへのパス。

`testPath`  
テストスイートが含まれるフォルダへのパス。

`reportPath`  
IDT がテストスイートを実行した後にテスト結果が含まれるフォルダへのパス。

`awsRegion`  
オプション。テストスイートが使用する AWS リージョン。設定されない場合、テストスイートは各テストスイートに指定されているデフォルトのリージョンを使用します。

`auth.method`  
IDT が AWS 認証情報の取得に使用する方法。サポートされる値は、`file` (認証情報ファイルから認証情報を取得) と `environment` (環境変数を使用して認証情報を取得) です。

`auth.credentials.profile`  
認証情報ファイルから使用する認証情報プロファイル。このプロパティは、`auth.method` が `file` に設定されている場合にのみ適用されます。

# カスタムテストスイートのデバッグと実行
<a name="run-debug-custom-tests"></a>

[必要な設定](set-custom-idt-config.md) を終了すると、IDT はテストスイートを実行することができます。完全なテストスイートの実行時間は、ハードウェアとテストスイートの設定によって異なります。参照として、Raspberry Pi 3B に完全な AWS IoT Greengrass 適合性確認テストスイートを完了するために約 30 分かかります。

テストスイートの作成中に、IDT を使用してテストスイートをデバッグモードで実行すると、テストスイートを実行する前やテストの実行者に提供する前に、コードをチェックすることができます。

## IDT をデバッグモードで実行する
<a name="idt-debug-mode"></a>

テストスイートは、IDT に依存してデバイスとやり取りし、コンテキストを提供し、結果を受け取るため、IDT と通信しないと、IDE でテストスイートを簡単にデバッグすることはできません。そのために、IDT CLI は IDT をデバッグモードで実行できるようにする `debug-test-suite` コマンドを提供します。`debug-test-suite` で使用可能なオプションを表示するには、次のコマンドを実行します。

```
devicetester_[linux | mac | win_x86-64] debug-test-suite -h
```

IDT をデバッグモードで実行するとき、IDT は実際にテストスイートを起動したり、テストオーケストレーターを実行したりしません。代わりに、IDE と対話して IDE で実行されているテストスイートによるリクエストに応答して、コンソールにログを出力します。IDT はタイムアウトせず、手動で中断されるまで待機してから終了します。デバッグモードでは、IDT はテストオーケストレーターも実行せず、レポートファイルも生成しません。テストスイートをデバッグするには、通常 IDT が設定 JSON ファイルから取得する情報を、IDE を使用して提供する必要があります。以下の情報を提供してください。
+ 各テストの環境変数と引数。IDT はこの情報を `test.json` または `suite.json` から読み込みません。
+ リソースデバイスを選択するための引数。IDT はこの情報を `test.json` から読み込みません。

テストスイートをデバッグするには、次の手順を実行します。

1.  テストスイートの実行に必要な構成設定ファイルを作成します。例えば、テストスイートが `device.json`、`resource.json`、および `user data.json` を必要とする場合は、必要に応じてこれらすべてを設定してください。

1. 次のコマンドを実行して IDT をデバッグモードにし、テストの実行に必要なデバイスを選択します。

   ```
   devicetester_[linux | mac | win_x86-64] debug-test-suite [options]
   ```

   このコマンドを実行すると、IDT はテストスイートからのリクエストを待機し、それらのリクエストに応答します。IDT は、IDT クライアント SDK がケースを処理するために必要な環境変数も生成します。

1. IDE で、`run` または `debug` 設定を使用して次の手順を実行します。

   1. IDT で生成された環境変数の値を設定します。

   1. `test.json` ファイルと `suite.json` ファイルに指定したすべての環境変数または引数の値を設定します。

   1. 必要に応じてブレークポイントを設定します。

1. IDE でテストスイートを実行します。

   テストスイートは、必要に応じて何度でもデバッグして再実行できます。IDT はデバッグモードではタイムアウトしません。

1.  デバッグが完了したら、IDT を中断してデバッグモードを終了します。

## テストを実行する IDT CLI コマンド
<a name="idt-cli-commands"></a>

次のセクションでは、IDT CLI コマンドについて説明します。

------
#### [ IDT v4.0.0 ]

`help`  <a name="idt-command-help"></a>
指定されたコマンドに関する情報を一覧表示します。

`list-groups`  <a name="idt-command-list-groups"></a>
特定のテストスイート内のグループを一覧表示します。

`list-suites`  <a name="idt-command-list-suites"></a>
使用可能なテストスイートを一覧表示します。

`list-supported-products`  
IDT バージョン (この場合は AWS IoT Greengrass バージョン) のサポート対象製品と、現在の IDT バージョンで利用可能な AWS IoT Greengrass 適合性確認テストスイートのバージョンを一覧表示します。

`list-test-cases`  
指定したテストグループのテストケースを一覧表示します。次のオプションがサポートされています。  
+ `group-id`。検索するテストグループ。このオプションは必須で、1 つのグループを指定する必要があります。

`run-suite`  
デバイスプールに対してテストスイートを実行します。以下に、一般的に使用されるオプションの一部を示します。  
+ `suite-id`。実行するテストスイートのバージョン。指定しない場合、IDT は `tests` フォルダにある最新バージョンを使用します。
+ `group-id`。実行するテストグループ (カンマ区切りリストとして)。指定しない場合、IDT はテストスイートのすべてのテストグループを実行します。
+ `test-id`。実行するテストケース (カンマ区切りリストとして)。指定した場合は、`group-id` は 1 つのグループを指定する必要があります。
+ `pool-id`。テストするデバイスプール。`device.json` ファイルに複数のデバイスプールが定義されている場合、テストの実行者は 1 つのプールを指定する必要があります。
+ `timeout-multiplier`。テスト用の `test.json` ファイルに指定されているテスト実行タイムアウトを、ユーザー定義乗数を使用して変更するように IDT を設定します。
+ `stop-on-first-failure`。最初に障害が発生した時点で実行を停止するように IDT を設定します。指定されたテストグループをデバッグするには、このオプションを `group-id` とともに使用する必要があります。
+ `userdata`。テストスイートの実行に必要なユーザーデータ情報を含むファイルを設定します。テストスイートの `suite.json` ファイルで、`userdataRequired` が true に設定されている場合にのみ必要です。
`run-suite` オプションの詳細については、次の `help` オプションを使用してください。  

```
devicetester_[linux | mac | win_x86-64] run-suite -h
```

`debug-test-suite`  
デバッグモードでテストスイートを実行します。詳細については、「[IDT をデバッグモードで実行する](#idt-debug-mode)」を参照してください。

------

# IDT テストの結果とログを確認する
<a name="idt-review-results-logs"></a>

このセクションでは、IDT がコンソールログとテストレポートを生成する形式について説明します。

## コンソールメッセージの形式
<a name="idt-console-format"></a>

AWS IoT Device Tester は、テストスイートを起動するときに、標準形式を使用してコンソールにメッセージを出力します。以下の抜粋は、IDT によって生成されるコンソールメッセージの例を示しています。

```
time="2000-01-02T03:04:05-07:00" level=info msg=Using suite: MyTestSuite_1.0.0 
executionId=9a52f362-1227-11eb-86c9-8c8590419f30
```

コンソールメッセージの大半は、次のフィールドで設定されます。

`time`  
ログに記録されたイベントの完全な ISO 8601 タイムスタンプ。

`level`  
ログに記録されたイベントのメッセージレベル。通常、ログに記録されるメッセージレベルは、`info`、`warn`、または `error` のいずれかです。IDT は、早期終了の原因となる予期されるイベントが発生した場合は、`fatal` または `panic` メッセージを発行します。

`msg`  
ログに記録されたメッセージ。

`executionId`  
現在の IDT プロセスの一意の ID 文字列。この ID は、個々の IDT 実行を区別するために使用されます。

テストスイートから生成されたコンソールメッセージは、テスト対象のデバイスとテストスイート、テストグループ、IDT が実行するテストケースに関する追加情報を提供します。次の抜粋は、テストスイートから生成されたコンソールメッセージの例を示しています。

```
time="2000-01-02T03:04:05-07:00" level=info msg=Hello world! suiteId=MyTestSuite
groupId=myTestGroup testCaseId=myTestCase deviceId=my-device
executionId=9a52f362-1227-11eb-86c9-8c8590419f30
```

コンソールメッセージのテストスイート固有の部分には、次のフィールドが含まれています。

`suiteId`  
現在実行中のテストスイートの名前。

`groupId`  
現在実行中のテストグループの ID。

`testCaseId`  
現在実行中のテストケースの ID。

`deviceId`  
現在のテストケースが使用しているテスト対象デバイスの ID。

IDT のテスト実行完了時にテストサマリーをコンソールに出力するには、テストオーケストレーターに [`Report` ステート](idt-state-machine.md#state-report)を含める必要があります。テストサマリーには、テストスイート、実行された各グループのテスト結果、生成されたログファイルとレポートファイルの場所に関する情報が含まれています。次の例は、テストサマリーメッセージを示しています。

```
========== Test Summary ==========
Execution Time:     5m00s
Tests Completed:    4
Tests Passed:       3
Tests Failed:       1
Tests Skipped:      0
----------------------------------
Test Groups:
    GroupA:         PASSED
    GroupB:         FAILED
----------------------------------
Failed Tests:
    Group Name: GroupB
        Test Name: TestB1
            Reason: Something bad happened
----------------------------------
Path to IoT Device Tester Report: /path/to/awsiotdevicetester_report.xml
Path to Test Execution Logs: /path/to/logs
Path to Aggregated JUnit Report: /path/to/MyTestSuite_Report.xml
```

## AWS IoT Device Tester のレポートスキーマ
<a name="idt-report"></a>

 `awsiotdevicetester_report.xml` は、次の情報が含まれる署名済みレポートです。
+ IDT バージョン。
+ テストスイートのバージョン。
+ レポートの署名に使用されるレポートの署名とキー。
+ `device.json` ファイルで指定されているデバイス SKU とデバイスプール。
+ テストされた製品のバージョンとデバイスの機能。
+ テスト結果の概要の集計。この情報は、`suite-name_report.xml` ファイルに含まれている情報と同じです。

```
<apnreport>
    <awsiotdevicetesterversion>idt-version</awsiotdevicetesterversion>
    <testsuiteversion>test-suite-version</testsuiteversion>
    <signature>signature</signature>
    <keyname>keyname</keyname>
    <session>
        <testsession>execution-id</testsession>
        <starttime>start-time</starttime>
        <endtime>end-time</endtime>
    </session>
    <awsproduct>
        <name>product-name</name>
        <version>product-version</version>
        <features>
            <feature name="<feature-name>" value="supported | not-supported | <feature-value>" type="optional | required"/>
        </features>
    </awsproduct>
    <device>
        <sku>device-sku</sku>
        <name>device-name</name>
        <features>
            <feature name="<feature-name>" value="<feature-value>"/>
        </features>
        <executionMethod>ssh | uart | docker</executionMethod>
    </device>
    <devenvironment>
        <os name="<os-name>"/>
    </devenvironment>
    <report>
        <suite-name-report-contents>
    </report>
</apnreport>
```

`awsiotdevicetester_report.xml` ファイルには、テスト対象の製品および一連のテストの実行後に検証された製品機能に関する情報を含む `<awsproduct>` タグが含まれています。`<awsproduct>` タグで使用される属性

`name`  
テスト対象の製品の名前。

`version`  
テスト対象の製品のバージョン。

`features`  
検証された機能です。`required` としてマークされている機能は、テストスイートがデバイスを検証するために必要です。次のスニペットは、この情報が `awsiotdevicetester_report.xml` ファイルで表示される方法を示します。  

```
<feature name="ssh" value="supported" type="required"></feature>
```
`optional` としてマークされている機能は、検証に必須ではありません。次のスニペットは、オプションの機能を示しています。  

```
<feature name="hsi" value="supported" type="optional"></feature> 
<feature name="mqtt" value="not-supported" type="optional"></feature>
```

## テストスイートのレポートスキーマ
<a name="suite-report"></a>

`suite-name_Result.xml` レポートは [JUnit XML 形式](https://llg.cubic.org/docs/junit/)です。[Jenkins](https://jenkins.io/)、[Bamboo](https://www.atlassian.com/software/bamboo) などのように継続的な統合 (CI) と継続的なデプロイ (CD) のプラットフォームに統合することができます。このレポートには、テスト結果の概要の集計が含まれています。

```
<testsuites name="<suite-name> results" time="<run-duration>" tests="<number-of-test>" failures="<number-of-tests>" skipped="<number-of-tests>" errors="<number-of-tests>" disabled="0">
    <testsuite name="<test-group-id>" package="" tests="<number-of-tests>" failures="<number-of-tests>" skipped="<number-of-tests>" errors="<number-of-tests>" disabled="0">
        <!--success-->
        <testcase classname="<classname>" name="<name>" time="<run-duration>"/>
        <!--failure-->
        <testcase classname="<classname>" name="<name>" time="<run-duration>">
            <failure type="<failure-type>">
                reason
            </failure>
        </testcase>
        <!--skipped-->
        <testcase classname="<classname>" name="<name>" time="<run-duration>">
            <skipped>
                reason
            </skipped>
        </testcase>
        <!--error-->
        <testcase classname="<classname>" name="<name>" time="<run-duration>">
            <error>
                reason
            </error>
        </testcase>
    </testsuite>
</testsuites>
```

`awsiotdevicetester_report.xml` と `suite-name_report.xml` 両方のレポートセクションには、実行されたテストとその結果が一覧表示されます。

最初の XML タグ `<testsuites>` には、テストの実行の概要が含まれています。例:

```
<testsuites name="MyTestSuite results" time="2299" tests="28" failures="0" errors="0" disabled="0">
````<testsuites>` タグで使用される属性

`name`  
テストスイートの名前。

`time`  
スイートの実行所要時間 (秒)。

`tests`  
実行されたテストの数。

`failures`  
実行されたテストのうち、合格しなかったものの数。

`errors`  
IDT で実行できなかったテストの数。

`disabled`  
この属性は使用されていないため無視できます。

テストに障害やエラーが発生した場合は、`<testsuites>` XML タグを確認することで、障害の生じたテストを特定できます。`<testsuite>` タグ内の `<testsuites>` XML タグは、テストグループのテスト結果の要約を示します。例:

```
<testsuite name="combination" package="" tests="1" failures="0" time="161" disabled="0" errors="0" skipped="0">
```

形式は `<testsuites>` タグと似ていますが、使用されていないため無視できる `skipped` という属性があります。各 `<testsuite>` XML タグ内には、テストグループの実行されたテスト別の `<testcase>` タグがあります。例:

```
<testcase classname="Security Test" name="IP Change Tests" attempts="1"></testcase>>
````<testcase>` タグで使用される属性

`name`  
テストの名前。

`attempts`  
IDT でテストケースを実行した回数。

テストに障害やエラーが発生した場合、`<failure>` タグまたは `<error>` タグがトラブルシューティングのための情報とともに `<testcase>` タグに追加されます。例:

```
<testcase classname="mcu.Full_MQTT" name="MQTT_TestCase" attempts="1">
	<failure type="Failure">Reason for the test failure</failure>
	<error>Reason for the test execution error</error>
</testcase>
```

# IDT 使用状況メトリクス
<a name="idt-usage-metrics"></a>

必要なアクセス許可を持つ AWS 認証情報を提供すると、 は使用状況メトリクスを AWS IoT Device Tester 収集して送信します AWS。これはオプトイン機能で、IDT 機能を改善するために使用されます。IDT は次のような情報を収集します。
+  AWS アカウント IDT の実行に使用される ID
+  テストの実行に使用される IDT AWS CLI コマンド
+ 実行されるテストスイート
+ *<device-tester-extract-location>* フォルダにあるテストスイート
+ デバイスプール内に設定されているデバイスの数
+ テストケース名と実行時間
+ テストに合格したか、失敗したか、エラーが発生したか、スキップされたかなどのテスト結果情報
+ テストされた製品の機能
+ 予期せぬ終了、早期終了などの IDT 終了動作 

 IDT が送信するすべての情報は、`<device-tester-extract-location>/results/<execution-id>/` フォルダの `metrics.log` ファイルにもログが記録されます。ログファイルを表示すると、テスト実行中に収集された情報を確認できます。このファイルは、使用状況メトリックを収集することを選択した場合にのみ生成されます。

メトリクスの収集を無効にするために、追加のアクションを実行する必要はありません。 AWS 認証情報を保存せず、 AWS 認証情報を保存している場合は、アクセスするように `config.json` ファイルを設定しないでください。

## AWS 認証情報を設定する
<a name="configure-aws-creds-for-metrics"></a>

をまだ作成していない場合は AWS アカウント、[作成](#idt-metrics-aws-account)する必要があります。が既にある場合は AWS アカウント、IDT が AWS ユーザーに代わって に使用状況メトリクスを送信できるようにするアカウント[に必要なアクセス許可を設定する](#idt-metrics-permissions)だけです。

### ステップ 1: を作成する AWS アカウント
<a name="idt-metrics-aws-account"></a>

このステップでは、 AWS アカウントを作成して設定します。 AWS アカウントを既にお持ちの場合は、[ステップ 2: IDT 用のアクセス許可を設定する](#idt-metrics-permissions) に進んでください。

がない場合は AWS アカウント、次の手順を実行して作成します。

**にサインアップするには AWS アカウント**

1. [https://portal.aws.amazon.com/billing/signup](https://portal.aws.amazon.com/billing/signup) を開きます。

1. オンラインの手順に従います。

   サインアップ手順の一環として、電話またはテキストメッセージを受け取り、電話キーパッドで検証コードを入力します。

   にサインアップすると AWS アカウント、 *AWS アカウントのルートユーザー* が作成されます。ルートユーザーには、アカウントのすべての AWS のサービス とリソースへのアクセス権があります。セキュリティベストプラクティスとして、ユーザーに管理アクセス権を割り当て、[ルートユーザーアクセスが必要なタスク](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#root-user-tasks)の実行にはルートユーザーのみを使用するようにしてください。

管理者ユーザーを作成するには、以下のいずれかのオプションを選択します。


****  

| 管理者を管理する方法を 1 つ選択します | 目的 | 方法 | 以下の操作も可能 | 
| --- | --- | --- | --- | 
| IAM アイデンティティセンター内 (推奨) | 短期の認証情報を使用して AWSにアクセスします。これはセキュリティのベストプラクティスと一致しています。ベストプラクティスの詳細については、「*IAM ユーザーガイド*」の「[IAM でのセキュリティのベストプラクティス](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#bp-users-federation-idp)」を参照してください。 | AWS IAM アイデンティティセンター ユーザーガイドの「[開始方法](https://docs.aws.amazon.com//singlesignon/latest/userguide/getting-started.html)」の手順に従います。 | AWS Command Line Interface ユーザーガイドの [を使用する AWS CLI ように を設定 AWS IAM アイデンティティセンター](https://docs.aws.amazon.com//cli/latest/userguide/cli-configure-sso.html)して、プログラムによるアクセスを設定します。 | 
| IAM 内 (非推奨) | 長期認証情報を使用して AWSにアクセスします。 | IAM ユーザーガイドの「[緊急アクセス用の IAM ユーザーを作成する](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started-emergency-iam-user.html)」の手順に従います。 | IAM ユーザーガイドの「[IAM ユーザーのアクセスキーを管理する](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_credentials_access-keys.html)」の手順に従って、プログラムによるアクセスを設定します。 | 

### ステップ 2: IDT 用のアクセス許可を設定する
<a name="idt-metrics-permissions"></a>

このステップでは、IDT がテストを実行して IDT 使用状況データを収集するために使用するアクセス許可を設定します。 AWS マネジメントコンソール または AWS Command Line Interface (AWS CLI) を使用して IDT の IAM ポリシーとユーザーを作成し、ユーザーにポリシーをアタッチできます。
+ [IDT 用のアクセス許可を設定するには (コンソール)](#idt-metrics-permissions-console)
+ [IDT 用のアクセス許可を設定するには (AWS CLI)](#idt-metrics-permissions-cli)<a name="idt-metrics-permissions-console"></a>

**IDT 用のアクセス許可を設定するには (コンソール)**

コンソールを使用して IDT for AWS IoT Greengrass用のアクセス許可を設定するには、次のステップに従ってください。

1. [IAM コンソール](https://console.aws.amazon.com/iam)にサインインします。

1. 特定のアクセス許可を持つロールを作成するためのアクセス許可を付与するカスタマー管理ポリシーを作成します。

   1. ナビゲーションペインで **ポリシー**を選択してから **ポリシーの作成**を選択します。

   1. **JSON** タブで、プレースホルダーコンテンツを以下のポリシーに置き換えます。

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot-device-tester:SendMetrics"
                  ],
                  "Resource": "*"
              }
          ]
      }
      ```

------

   1. **[ポリシーの確認]** を選択します。

   1. **[Name]** (名前) に **IDTUsageMetricsIAMPermissions** と入力します。[**概要**] で、ポリシーによって付与されたアクセス許可を確認します。

   1. [**Create policy**] (ポリシーの作成) を選択します。

1. IAM ユーザーを作成し、ユーザーにアクセス許可をアタッチします。

   1. IAM ユーザーを作成します。IAM ユーザーガイドの [IAM ユーザーの作成 (コンソール)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html#id_users_create_console) のステップ 1 ～ 5 に従います。**IAM ユーザーを作成済みの場合は、次のステップに進んでください。

   1. アクセス許可を IAM ユーザーにアタッチします。

      1. [**Set permissions**] ページで、[**Attach existing policies to user directly**] を選択します。

      1. 前のステップで作成した **IDTGreengrassIAMPermissions** ポリシーを検索します。チェックボックスをオンにします。

   1. **[Next: Tags]** (次へ: タグ) を選択します。

   1. [**Next: Review**] (次へ: レビュー) を選択して、選択内容の概要を表示します。

   1. **[ユーザーの作成]** を選択します。

   1. ユーザーのアクセスキー (アクセスキー ID とシークレットアクセスキー) を表示するには、パスワードとアクセスキーの横にある [**Show (表示)**] を選択します。アクセスキーを保存するには、[**Download .csv**] を選択し、安全な場所にファイルを保存します。後でこの情報を使用して認証情報 AWS ファイルを設定します。

 <a name="idt-metrics-permissions-cli"></a>

**IDT 用のアクセス許可を設定するには (AWS CLI)**

を使用して IDT for のアクセス許可を設定するには AWS CLI 、次の手順に従います AWS IoT Greengrass。

1. コンピュータで、まだインストール AWS CLI されていない場合は、 をインストールして設定します。AWS Command Line Interface ユーザーガイドの [AWS CLIのインストール](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)のステップに従います。**
**注記**  
 AWS CLI は、コマンドラインシェルから AWS サービスとやり取りするために使用できるオープンソースツールです。

1. IDT と AWS IoT Greengrass ロールを管理するアクセス許可を付与する次のカスタマー管理ポリシーを作成します。

------
#### [ Linux or Unix ]

   ```
   aws iam create-policy --policy-name IDTUsageMetricsIAMPermissions --policy-document '{
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "iot-device-tester:SendMetrics"
               ],
               "Resource": "*"
           }
       ]
   }'
   ```

------
#### [ Windows command prompt ]

   ```
   aws iam create-policy --policy-name IDTUsageMetricsIAMPermissions --policy-document
                                           '{\"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"iot-device-tester:SendMetrics\"], \"Resource": \"*\"}]}'
   ```

**注記**  
このステップには、Linux、macOS、または Unix のターミナルコマンドとは異なる JSON 構文を使用するため、Windows コマンドプロンプトの例が含まれています。

------
#### [ PowerShell ]

   ```
   aws iam create-policy --policy-name IDTUsageMetricsIAMPermissions --policy-document '{
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "iot-device-tester:SendMetrics"
               ],
               "Resource": "*"
           }
       ]
   }'
   ```

------

1. IAM ユーザーを作成し、IDT for AWS IoT Greengrassに必要なアクセス許可をアタッチします。

   1. IAM ユーザーを作成します。

      ```
      aws iam create-user --user-name user-name
      ```

   1. 作成した `IDTUsageMetricsIAMPermissions` ポリシーを IAM ユーザーにアタッチします。*user-name* を IAM ユーザー名に置き換え、コマンドの *<account-id>* を AWS アカウントの ID に置き換えます。

      ```
      aws iam attach-user-policy --user-name user-name --policy-arn arn:aws:iam::<account-id>:policy/IDTGreengrassIAMPermissions
      ```

1. ユーザーのシークレットアクセスキーを作成します。

   ```
   aws iam create-access-key --user-name user-name
   ```

   この出力は安全な場所に保存してください。後でこの情報を使用して認証情報 AWS ファイルを設定します。

## IDT に AWS 認証情報を提供する
<a name="idt-metrics-creds"></a>

IDT が AWS 認証情報にアクセスしてメトリクスを送信できるようにするには AWS、以下を実行します。

1. IAM ユーザーの AWS 認証情報を環境変数として、または認証情報ファイルに保存します。

   1. 環境変数を使用するには、次のコマンドを実行します。

------
#### [ Linux or Unix ]

      ```
      export AWS_ACCESS_KEY_ID=access-key
      export AWS_SECRET_ACCESS_KEY=secret-access-key
      ```

------
#### [ Windows Command Prompt (CMD) ]

      ```
      set AWS_ACCESS_KEY_ID=access-key
      set AWS_SECRET_ACCESS_KEY=secret-access-key
      ```

------
#### [ PowerShell ]

      ```
      $env:AWS_ACCESS_KEY_ID="access-key"
      $env:AWS_SECRET_ACCESS_KEY="secret-access-key"
      ```

------

   1. 認証情報ファイルを使用するには、`~/.aws/credentials` ファイルに次の情報を追加します。

      ```
      [profile-name]
      aws_access_key_id=access-key
      aws_secret_access_key=secret-access-key
      ```

1. `config.json` ファイルの `auth` セクションを設定します。詳細については、「[(オプション) config.json の設定](set-custom-idt-config.md#config-json-custom)」を参照してください。