

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 教程：开发一个简单的 IDT 测试套件
<a name="create-custom-tests"></a>

测试套件结合了以下内容：
+ 包含测试逻辑的测试可执行文件
+ 描述测试套件的配置文件

本教程向您展示如何使用 IDT 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\$1。有关更多信息，请参阅 [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 操作系统的 [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 客户端 SDK](create-test-executables.md#idt-client-sdk) 让 IDT 与被测设备进行交互并报告测试结果。在本教程中，您将使用 Python 版本的软件开发工具包。

从 `<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. 创建测试套件文件。

   在 `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 会将错误日志流式传输到控制台，以帮助您对测试运行进行故障排除。检查错误日志之前，请验证以下内容：
+ 如[本步骤](#add-idt-sdk)所述，IDT 客户端 SDK 位于正确的文件夹中。
+ 您已满足本教程的所有[先决条件](#prereqs-tutorial-custom)。

**无法连接到被测设备**

请验证以下内容：
+ 您的 `device.json` 文件包含正确的 IP 地址、端口和身份验证信息。
+ 您可以通过 SSH 从主机连接到您的设备。