

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

# AWS Device Farm 中的自定义测试环境
<a name="custom-test-environments"></a>

AWS Device Farm 支持配置用于自动测试的自定义环境（自定义模式），这是针对所有 Device Farm 用户的推荐方法。要详细了解 Device Farm 中的环境，请参阅[测试环境](https://docs.aws.amazon.com/devicefarm/latest/developerguide/test-environments.html)。

与标准模式相比，自定义模式的优势包括：
+ **更快地执行 end-to-end测试**：不会对测试包进行解析以检测套件中的每个测试，从而避免了 preprocessing/postprocessing 开销。
+ **实时日志和视频流**：使用自定义模式时，您的客户端测试日志和视频将进行实时流式传输。此功能在标准模式中不可用。
+ **捕获所有构件**：在主机和设备上，自定义模式允许您捕获所有测试构件。在标准模式下可能无法做到这一点。
+ **更一致且可复制的本地环境**：在标准模式下，将为每个单独的测试单独提供构件，这在某些情况下可能很有用。但是，您的本地测试环境可能会与原始配置有所不同，因为 Device Farm 对每个已执行的测试的处理方式不同。

  相比之下，借助自定义模式，您的 Device Farm 测试执行环境能够与本地测试环境保持一致。

 自定义环境是使用 YAML 格式的测试规范（测试规范）文件配置的。Device Farm 为每种支持的测试类型提供了一个默认的测试规范文件，可以按原样使用或自定义；测试筛选条件或配置文件等自定义项可以添加到测试规范中。可以保存编辑后的测试规格，以备将来的测试运行使用。

有关更多信息，请参阅[使用 AWS CLI](https://docs.aws.amazon.com/devicefarm/latest/developerguide/how-to-create-test-run.html#how-to-create-test-run-cli-step5) 和 [在 Device Farm 中创建测试运行](how-to-create-test-run.md) 上传自定义测试规范。

**Topics**
+ [测试规范参考和语法](custom-test-environment-test-spec.md)
+ [用于自定义测试环境的主机](custom-test-environments-hosts.md)
+ [使用 IAM 执行角色访问 AWS 资源](custom-test-environments-iam-roles.md)
+ [自定义测试环境的环境变量](custom-test-environment-variables.md)
+ [执行自定义测试环境的最佳实践](custom-test-environments-best-practices.md)
+ [将测试从标准测试环境迁移到自定义测试环境](custom-test-environment-migration.md)
+ [在 Device Farm 中扩展自定义测试环境](custom-test-environments-extending.md)

# 测试规范参考和语法
<a name="custom-test-environment-test-spec"></a>

 测试规范（测试规范）是用于在 Device Farm 中定义自定义测试环境的文件。

## 测试规范工作流程
<a name="custom-test-environment-test-spec-workflow"></a>

 Device Farm 测试规范按预先确定的顺序执行各阶段及其命令，允许您自定义环境的准备和执行方式。执行每个阶段时，其命令将按照测试规范文件中列出的顺序运行。阶段按以下顺序执行 

1. `install`-应在此处定义下载、安装和设置工具等操作。

1. `pre_test`-应在此处定义诸如启动后台进程之类的测试前操作。

1. `test`-应在此处定义调用测试的命令。

1. `post_test`-应在此处定义测试结束后需要运行的任何最终任务，例如测试报告生成和工件文件聚合。

## 测试规范语法
<a name="custom-test-environment-test-spec-syntax"></a>

以下是测试规范文件的 YAML 架构

```
version: 0.1

android_test_host: "string"
ios_test_host: "string"

phases:
  install:
    commands:
      - "string"
      - "string"
  pre_test:
    commands:
      - "string"
      - "string"
  test:
    commands:
      - "string"
      - "string"
  post_test:
    commands:
      - "string"
      - "string"

artifacts:
    - "string"
    - "string"
```

** `version` **  
 *（必填，数字）*   
 反映 Device Farm 支持的测试规范版本。当前版本号是` 0.1`。

** `android_test_host` **  
 *（可选，字符串）*   
 将为在 Android 设备上执行的测试运行选择的测试主机。要在 Android 设备上运行测试，此字段是必填字段。有关更多信息，请参阅 [自定义测试环境的可用测试主机](custom-test-environments-hosts.md#custom-test-environments-hosts-available)。

** `ios_test_host` **  
 *（可选，字符串）*   
 将为在 iOS 设备上执行的测试运行选择的测试主机。在主版本大于 26 的 iOS 设备上进行测试时，此字段为必填字段。有关更多信息，请参阅 [自定义测试环境的可用测试主机](custom-test-environments-hosts.md#custom-test-environments-hosts-available)。

** `phases` **  
本节包含在测试运行期间执行的命令组，其中每个阶段都是可选的。允许的测试阶段名称为：`install``pre_test`、`test`、和`post_test`。  
+ `install`-已经安装了 Device Farm 支持的测试框架的默认依赖项。此阶段包含 Device Farm 在安装期间运行的其他命令（如果有）。
+ `pre_test`-在自动测试之前执行的命令（如果有）。
+ `test`-在自动测试运行期间执行的命令。如果测试阶段的任何命令失败（这意味着它返回非零的退出代码），则测试将被标记为失败
+ `post_test`-在自动测试运行后执行的命令（如果有）。无论您在该`test`阶段的测试成功还是失败，都将执行此操作。  
** `commands` **  
 *（可选，列表 [字符串]）*   
 该阶段要作为 shell 命令执行的字符串列表。

** `artifacts` **  
 *（可选，列表 [字符串]）*   
 Device Farm 会从此处指定的位置收集自定义报告、日志文件和图像等构件。不支持在项目位置中使用通配符，因此，您必须为每个位置指定有效的路径。  
这些测试项目可用于测试运行中的每台设备。有关检索测试项目的更多信息，请参阅[在自定义测试环境中下载构件](using-artifacts-custom.md)。

**重要**  
测试规范必须格式化为有效的 YAML 文件。如果测试规范中的缩进或间距无效，测试运行可能会失败。YAML 文件中不允许使用制表符。您可以使用 YAML 验证程序测试您的测试规范是否为效的 YAML 文件。有关更多信息，请参阅 [YAML 网站](http://yaml.org/spec/1.2/spec.html)。

## 测试规范示例
<a name="custom-test-environment-test-spec-example"></a>

 以下示例显示了可以在 Device Farm 上执行的测试规范。

------
#### [ Simple Demo ]

 以下是一个测试规范文件示例，该文件仅`Hello world!`作为测试运行工件进行记录。

```
version: 0.1

android_test_host: amazon_linux_2
ios_test_host: macos_sequoia

phases:
  install:
    commands:
      # Setup your environment by installing and/or validating software
      - devicefarm-cli use python 3.11
      - python --version

  pre_test:
    commands:
      # Setup your tests by starting background tasks or setting up
      # additional environment variables.
      - OUTPUT_FILE="/tmp/hello.log"

  test:
    commands:
      # Run your tests within this phase.
      - python -c 'print("Hello world!")' &> $OUTPUT_FILE

  post_test:
    commands:
      # Perform any remaining tasks within this phase, such as copying
      # artifacts to the DEVICEFARM_LOG_DIR for upload
      - cp $OUTPUT_FILE $DEVICEFARM_LOG_DIR

artifacts:
  # By default, Device Farm will collect your artifacts from the $DEVICEFARM_LOG_DIR directory.
  - $DEVICEFARM_LOG_DIR
```

------
#### [  Appium 安卓  ]

 以下是配置在 Android 上运行的 Appium Java Testng 测试的测试规范文件示例...

```
version: 0.1

# The following fields(s) allow you to select which Device Farm test host is used for your test run. 
android_test_host: amazon_linux_2

phases:

  # The install phase contains commands for installing dependencies to run your tests.
  # Certain frequently used dependencies are preinstalled on the test host to accelerate and 
  # simplify your test setup. To find these dependencies, versions supported and additional 
  # software installation please see: 
  # https://docs.aws.amazon.com/devicefarm/latest/developerguide/custom-test-environments-hosts-software.html
  install:
    commands:
      # The Appium server is written using Node.js. In order to run your desired version of Appium,
      # you first need to set up a Node.js environment that is compatible with your version of Appium.
      - devicefarm-cli use node 20
      - node --version

      # Use the devicefarm-cli to select a preinstalled major version of Appium.
      - devicefarm-cli use appium 2
      - appium --version

      # The Device Farm service periodically updates the preinstalled Appium versions over time to
      # incorporate the latest minor and patch versions for each major version. If you wish to
      # select a specific version of Appium, you can use NPM to install it.
      # - npm install -g appium@2.19.0

      # When running Android tests with Appium version 2, the uiautomator2 driver is preinstalled using driver 
      # version 2.44.1 for Appium 2.5.1  If you want to install a different version of the driver, 
      # you can use the Appium extension CLI to uninstall the existing uiautomator2 driver
      # and install your desired version:
      # - |-
      #   if [ $DEVICEFARM_DEVICE_PLATFORM_NAME = "Android" ];
      #   then
      #     appium driver uninstall uiautomator2;
      #     appium driver install uiautomator2@2.34.0;
      #   fi;

      # Based on Appium framework's recommendation, we recommend setting the Appium server's 
      # base path explicitly for accepting commands. If you prefer the legacy base path of /wd/hub,
      # please set it here. 
      - export APPIUM_BASE_PATH=

      # Use the devicefarm-cli to setup a Java environment, with which you can run your test suite.
      - devicefarm-cli use java 17
      - java -version

  # The pre-test phase contains commands for setting up your test environment.
  pre_test:
    commands:
      # Setup the CLASSPATH so that Java knows where to find your test classes.
      - export CLASSPATH=$CLASSPATH:$DEVICEFARM_TEST_PACKAGE_PATH/*
      - export CLASSPATH=$CLASSPATH:$DEVICEFARM_TEST_PACKAGE_PATH/dependency-jars/*

      # We recommend starting the Appium server process in the background using the command below.
      # The Appium server log will be written to the $DEVICEFARM_LOG_DIR directory.
      # The environment variables passed as capabilities to the server will be automatically assigned
      # during your test run based on your test's specific device.
      # For more information about which environment variables are set and how they're set, please see
      # https://docs.aws.amazon.com/devicefarm/latest/developerguide/custom-test-environment-variables.html
      - |-
        appium --base-path=$APPIUM_BASE_PATH --log-timestamp \
          --log-no-colors --relaxed-security --default-capabilities \
          "{\"appium:deviceName\": \"$DEVICEFARM_DEVICE_NAME\", \
          \"platformName\": \"$DEVICEFARM_DEVICE_PLATFORM_NAME\", \
          \"appium:udid\":\"$DEVICEFARM_DEVICE_UDID\", \
          \"appium:platformVersion\": \"$DEVICEFARM_DEVICE_OS_VERSION\", \
          \"appium:chromedriverExecutableDir\": \"$DEVICEFARM_CHROMEDRIVER_EXECUTABLE_DIR\", \
          \"appium:automationName\": \"UiAutomator2\"}" \
          >> $DEVICEFARM_LOG_DIR/appium.log 2>&1 &;

      # This code snippet is to wait until the Appium server starts.
      - |-
        appium_initialization_time=0;
        until curl --silent --fail "http://0.0.0.0:4723${APPIUM_BASE_PATH}/status"; do
          if [[ $appium_initialization_time -gt 30 ]]; then
            echo "Appium did not start within 30 seconds. Exiting...";
            exit 1;
          fi;
          appium_initialization_time=$((appium_initialization_time + 1));
          echo "Waiting for Appium to start on port 4723...";
          sleep 1;
        done;

  # The test phase contains commands for running your tests.
  test:
    commands:
      # Your test package is downloaded and unpackaged into the $DEVICEFARM_TEST_PACKAGE_PATH directory.
      - echo "Navigate to test package directory"
      - cd $DEVICEFARM_TEST_PACKAGE_PATH
      - echo "Starting the Appium TestNG test"

      # The following command runs your Appium Java TestNG test.
      # For more information, please see TestNG's documentation here:
      # https://testng.org/#_running_testng
      - |-
        java -Dappium.screenshots.dir=$DEVICEFARM_SCREENSHOT_PATH org.testng.TestNG -testjar *-tests.jar \
          -d $DEVICEFARM_LOG_DIR/test-output -verbose 10

      # To run your tests with a testng.xml file that is a part of your test package, 
      # use the following commands instead:

      # - echo "Unzipping the tests JAR file"
      # - unzip *-tests.jar
      # - |-
      #   java -Dappium.screenshots.dir=$DEVICEFARM_SCREENSHOT_PATH org.testng.TestNG -testjar *-tests.jar \
      #     testng.xml -d $DEVICEFARM_LOG_DIR/test-output -verbose 10

  # The post-test phase contains commands that are run after your tests have completed.
  # If you need to run any commands to generating logs and reports on how your test performed,
  # we recommend adding them to this section.
  post_test:
    commands:

# Artifacts are a list of paths on the filesystem where you can store test output and reports.
# All files in these paths will be collected by Device Farm, with certain limits (see limit details
# here: https://docs.aws.amazon.com/devicefarm/latest/developerguide/limits.html#file-limits).
# These files will be available through the ListArtifacts API as your "Customer Artifacts".
artifacts:
  # By default, Device Farm will collect your artifacts from the $DEVICEFARM_LOG_DIR directory.
  - $DEVICEFARM_LOG_DIR
```

------
#### [  Appium iOS  ]

 以下是配置在 iOS 上运行的 Appium Java Testng 测试的测试规范文件示例。

```
version: 0.1

# The following fields(s) allow you to select which Device Farm test host is used for your test run. 
ios_test_host: macos_sequoia

phases:

  # The install phase contains commands for installing dependencies to run your tests.
  # Certain frequently used dependencies are preinstalled on the test host to accelerate and 
  # simplify your test setup. To find these dependencies, versions supported and additional 
  # software installation please see: 
  # https://docs.aws.amazon.com/devicefarm/latest/developerguide/custom-test-environments-hosts-software.html
  install:
    commands:
      # The Appium server is written using Node.js. In order to run your desired version of Appium,
      # you first need to set up a Node.js environment that is compatible with your version of Appium.
      - devicefarm-cli use node 20
      - node --version

      # Use the devicefarm-cli to select a preinstalled major version of Appium.
      - devicefarm-cli use appium 2
      - appium --version

      # The Device Farm service periodically updates the preinstalled Appium versions over time to
      # incorporate the latest minor and patch versions for each major version. If you wish to
      # select a specific version of Appium, you can use NPM to install it.
      # - npm install -g appium@2.19.0

      # When running iOS tests with Appium version 2, the XCUITest driver is preinstalled using driver 
      # version 9.10.5 for Appium 2.5.4. If you want to install a different version of the driver,
      # you can use the Appium extension CLI to uninstall the existing XCUITest driver
      # and install your desired version:
      # - |-
      #   if [ $DEVICEFARM_DEVICE_PLATFORM_NAME = "iOS" ];
      #   then
      #     appium driver uninstall xcuitest;
      #     appium driver install xcuitest@10.0.0;
      #   fi;

      # Based on Appium framework's recommendation, we recommend setting the Appium server's 
      # base path explicitly for accepting commands. If you prefer the legacy base path of /wd/hub,
      # please set it here. 
      - export APPIUM_BASE_PATH=

      # Use the devicefarm-cli to setup a Java environment, with which you can run your test suite.
      - devicefarm-cli use java 17
      - java -version

  # The pre-test phase contains commands for setting up your test environment.
  pre_test:
    commands:
      # Setup the CLASSPATH so that Java knows where to find your test classes.
      - export CLASSPATH=$CLASSPATH:$DEVICEFARM_TEST_PACKAGE_PATH/*
      - export CLASSPATH=$CLASSPATH:$DEVICEFARM_TEST_PACKAGE_PATH/dependency-jars/*

      # Device Farm provides multiple pre-built versions of WebDriverAgent (WDA), a required 
      # Appium dependency for iOS, where each version corresponds to the XCUITest driver version selected. 
      # If Device Farm cannot find a corresponding version of WDA for your XCUITest driver, 
      # the latest available version is selected by default.
      - |-
        APPIUM_DRIVER_VERSION=$(appium driver list --installed --json | jq -r ".xcuitest.version" | cut -d "." -f 1);
        CORRESPONDING_APPIUM_WDA=$(env | grep "DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH_V${APPIUM_DRIVER_VERSION}")
        if [[ ! -z "$APPIUM_DRIVER_VERSION" ]] && [[ ! -z "$CORRESPONDING_APPIUM_WDA" ]]; then
          echo "Using Device Farm's prebuilt WDA version ${APPIUM_DRIVER_VERSION}.x, which corresponds with your driver";
          DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH=$(echo $CORRESPONDING_APPIUM_WDA | cut -d "=" -f2)
        else
          LATEST_SUPPORTED_WDA_VERSION=$(env | grep "DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH_V" | sort -V -r | head -n 1)
          echo "Unknown driver version $APPIUM_DRIVER_VERSION; falling back to the Device Farm default version of $LATEST_SUPPORTED_WDA_VERSION";
          DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH=$(echo $LATEST_SUPPORTED_WDA_VERSION | cut -d "=" -f2)
        fi;

      # For iOS versions 16 and below only, the device unique identifier (UDID) needs to modified for Appium tests
      # on Device Farm to remove the hypens.
      - |-
        if [ $DEVICEFARM_DEVICE_PLATFORM_NAME = "iOS" ]; then
          DEVICEFARM_DEVICE_UDID_FOR_APPIUM=$DEVICEFARM_DEVICE_UDID;
          if [ $(echo $DEVICEFARM_DEVICE_OS_VERSION | cut -d "." -f 1) -le 16 ]; then
            DEVICEFARM_DEVICE_UDID_FOR_APPIUM=$(echo $DEVICEFARM_DEVICE_UDID | tr -d "-");
          fi;
        fi;

      # We recommend starting the Appium server process in the background using the command below.
      # The Appium server log will be written to the $DEVICEFARM_LOG_DIR directory.
      # The environment variables passed as capabilities to the server will be automatically assigned
      # during your test run based on your test's specific device.
      # For more information about which environment variables are set and how they're set, please see
      # https://docs.aws.amazon.com/devicefarm/latest/developerguide/custom-test-environment-variables.html
      - |-
        appium --base-path=$APPIUM_BASE_PATH --log-timestamp \
          --log-no-colors --relaxed-security --default-capabilities \
          "{\"appium:deviceName\": \"$DEVICEFARM_DEVICE_NAME\", \
          \"platformName\": \"$DEVICEFARM_DEVICE_PLATFORM_NAME\", \
          \"appium:app\": \"$DEVICEFARM_APP_PATH\", \
          \"appium:udid\":\"$DEVICEFARM_DEVICE_UDID_FOR_APPIUM\", \
          \"appium:platformVersion\": \"$DEVICEFARM_DEVICE_OS_VERSION\", \
          \"appium:derivedDataPath\": \"$DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH\", \
          \"appium:usePrebuiltWDA\": true, \
          \"appium:automationName\": \"XCUITest\"}" \
          >> $DEVICEFARM_LOG_DIR/appium.log 2>&1 &

      # This code snippet is to wait until the Appium server starts.
      - |-
        appium_initialization_time=0;
        until curl --silent --fail "http://0.0.0.0:4723${APPIUM_BASE_PATH}/status"; do
          if [[ $appium_initialization_time -gt 30 ]]; then
            echo "Appium did not start within 30 seconds. Exiting...";
            exit 1;
          fi;
          appium_initialization_time=$((appium_initialization_time + 1));
          echo "Waiting for Appium to start on port 4723...";
          sleep 1;
        done;

  # The test phase contains commands for running your tests.
  test:
    commands:
      # Your test package is downloaded and unpackaged into the $DEVICEFARM_TEST_PACKAGE_PATH directory.
      - echo "Navigate to test package directory"
      - cd $DEVICEFARM_TEST_PACKAGE_PATH
      - echo "Starting the Appium TestNG test"

      # The following command runs your Appium Java TestNG test.
      # For more information, please see TestNG's documentation here:
      # https://testng.org/#_running_testng
      - |-
        java -Dappium.screenshots.dir=$DEVICEFARM_SCREENSHOT_PATH org.testng.TestNG -testjar *-tests.jar \
          -d $DEVICEFARM_LOG_DIR/test-output -verbose 10

      # To run your tests with a testng.xml file that is a part of your test package, 
      # use the following commands instead:

      # - echo "Unzipping the tests JAR file"
      # - unzip *-tests.jar
      # - |-
      #   java -Dappium.screenshots.dir=$DEVICEFARM_SCREENSHOT_PATH org.testng.TestNG -testjar *-tests.jar \
      #     testng.xml -d $DEVICEFARM_LOG_DIR/test-output -verbose 10

  # The post-test phase contains commands that are run after your tests have completed.
  # If you need to run any commands to generating logs and reports on how your test performed,
  # we recommend adding them to this section.
  post_test:
    commands:

# Artifacts are a list of paths on the filesystem where you can store test output and reports.
# All files in these paths will be collected by Device Farm, with certain limits (see limit details
# here: https://docs.aws.amazon.com/devicefarm/latest/developerguide/limits.html#file-limits).
# These files will be available through the ListArtifacts API as your "Customer Artifacts".
artifacts:
  # By default, Device Farm will collect your artifacts from the $DEVICEFARM_LOG_DIR directory.
  - $DEVICEFARM_LOG_DIR
```

------
#### [ Appium (Both Platforms) ]

 以下是一个测试规范文件示例，用于配置在安卓和 iOS 上运行的 Appium Java Testng 测试。

```
version: 0.1

# The following fields(s) allow you to select which Device Farm test host is used for your test run. 
android_test_host: amazon_linux_2
ios_test_host: macos_sequoia

phases:

  # The install phase contains commands for installing dependencies to run your tests.
  # Certain frequently used dependencies are preinstalled on the test host to accelerate and 
  # simplify your test setup. To find these dependencies, versions supported and additional 
  # software installation please see: 
  # https://docs.aws.amazon.com/devicefarm/latest/developerguide/custom-test-environments-hosts-software.html
  install:
    commands:
      # The Appium server is written using Node.js. In order to run your desired version of Appium,
      # you first need to set up a Node.js environment that is compatible with your version of Appium.
      - devicefarm-cli use node 20
      - node --version

      # Use the devicefarm-cli to select a preinstalled major version of Appium.
      - devicefarm-cli use appium 2
      - appium --version

      # The Device Farm service periodically updates the preinstalled Appium versions over time to
      # incorporate the latest minor and patch versions for each major version. If you wish to
      # select a specific version of Appium, you can use NPM to install it.
      # - npm install -g appium@2.19.0

      # When running Android tests with Appium version 2, the uiautomator2 driver is preinstalled using driver 
      # version 2.44.1 for Appium 2.5.1  If you want to install a different version of the driver, 
      # you can use the Appium extension CLI to uninstall the existing uiautomator2 driver
      # and install your desired version:
      # - |-
      #   if [ $DEVICEFARM_DEVICE_PLATFORM_NAME = "Android" ];
      #   then
      #     appium driver uninstall uiautomator2;
      #     appium driver install uiautomator2@2.34.0;
      #   fi;

      # When running iOS tests with Appium version 2, the XCUITest driver is preinstalled using driver 
      # version 9.10.5 for Appium 2.5.4. If you want to install a different version of the driver,
      # you can use the Appium extension CLI to uninstall the existing XCUITest driver
      # and install your desired version:
      # - |-
      #   if [ $DEVICEFARM_DEVICE_PLATFORM_NAME = "iOS" ];
      #   then
      #     appium driver uninstall xcuitest;
      #     appium driver install xcuitest@10.0.0;
      #   fi;

      # Based on Appium framework's recommendation, we recommend setting the Appium server's 
      # base path explicitly for accepting commands. If you prefer the legacy base path of /wd/hub,
      # please set it here. 
      - export APPIUM_BASE_PATH=

      # Use the devicefarm-cli to setup a Java environment, with which you can run your test suite.
      - devicefarm-cli use java 17
      - java -version

  # The pre-test phase contains commands for setting up your test environment.
  pre_test:
    commands:
      # Setup the CLASSPATH so that Java knows where to find your test classes.
      - export CLASSPATH=$CLASSPATH:$DEVICEFARM_TEST_PACKAGE_PATH/*
      - export CLASSPATH=$CLASSPATH:$DEVICEFARM_TEST_PACKAGE_PATH/dependency-jars/*

      # Device Farm provides multiple pre-built versions of WebDriverAgent (WDA), a required 
      # Appium dependency for iOS, where each version corresponds to the XCUITest driver version selected. 
      # If Device Farm cannot find a corresponding version of WDA for your XCUITest driver, 
      # the latest available version is selected by default.
      - |-
        if [ $DEVICEFARM_DEVICE_PLATFORM_NAME = "iOS" ]; then
          APPIUM_DRIVER_VERSION=$(appium driver list --installed --json | jq -r ".xcuitest.version" | cut -d "." -f 1);
          CORRESPONDING_APPIUM_WDA=$(env | grep "DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH_V${APPIUM_DRIVER_VERSION}")
          if [[ ! -z "$APPIUM_DRIVER_VERSION" ]] && [[ ! -z "$CORRESPONDING_APPIUM_WDA" ]]; then
            echo "Using Device Farm's prebuilt WDA version ${APPIUM_DRIVER_VERSION}.x, which corresponds with your driver";
            DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH=$(echo $CORRESPONDING_APPIUM_WDA | cut -d "=" -f2)
          else
            LATEST_SUPPORTED_WDA_VERSION=$(env | grep "DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH_V" | sort -V -r | head -n 1)
            echo "Unknown driver version $APPIUM_DRIVER_VERSION; falling back to the Device Farm default version of $LATEST_SUPPORTED_WDA_VERSION";
            DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH=$(echo $LATEST_SUPPORTED_WDA_VERSION | cut -d "=" -f2)
          fi;
        fi;

      # For iOS versions 16 and below only, the device unique identifier (UDID) needs to modified for Appium tests
      # on Device Farm to remove the hypens.
      - |-
        if [ $DEVICEFARM_DEVICE_PLATFORM_NAME = "iOS" ]; then
          DEVICEFARM_DEVICE_UDID_FOR_APPIUM=$DEVICEFARM_DEVICE_UDID;
          if [ $(echo $DEVICEFARM_DEVICE_OS_VERSION | cut -d "." -f 1) -le 16 ]; then
            DEVICEFARM_DEVICE_UDID_FOR_APPIUM=$(echo $DEVICEFARM_DEVICE_UDID | tr -d "-");
          fi;
        fi;

      # We recommend starting the Appium server process in the background using the command below.
      # The Appium server log will be written to the $DEVICEFARM_LOG_DIR directory.
      # The environment variables passed as capabilities to the server will be automatically assigned
      # during your test run based on your test's specific device.
      # For more information about which environment variables are set and how they're set, please see
      # https://docs.aws.amazon.com/devicefarm/latest/developerguide/custom-test-environment-variables.html
      - |-
        if [ $DEVICEFARM_DEVICE_PLATFORM_NAME = "Android" ]; then
          appium --base-path=$APPIUM_BASE_PATH --log-timestamp \
            --log-no-colors --relaxed-security --default-capabilities \
            "{\"appium:deviceName\": \"$DEVICEFARM_DEVICE_NAME\", \
            \"platformName\": \"$DEVICEFARM_DEVICE_PLATFORM_NAME\", \
            \"appium:udid\":\"$DEVICEFARM_DEVICE_UDID\", \
            \"appium:platformVersion\": \"$DEVICEFARM_DEVICE_OS_VERSION\", \
            \"appium:chromedriverExecutableDir\": \"$DEVICEFARM_CHROMEDRIVER_EXECUTABLE_DIR\", \
            \"appium:automationName\": \"UiAutomator2\"}" \
            >> $DEVICEFARM_LOG_DIR/appium.log 2>&1 &
        else
          appium --base-path=$APPIUM_BASE_PATH --log-timestamp \
            --log-no-colors --relaxed-security --default-capabilities \
            "{\"appium:deviceName\": \"$DEVICEFARM_DEVICE_NAME\", \
            \"platformName\": \"$DEVICEFARM_DEVICE_PLATFORM_NAME\", \
            \"appium:udid\":\"$DEVICEFARM_DEVICE_UDID_FOR_APPIUM\", \
            \"appium:platformVersion\": \"$DEVICEFARM_DEVICE_OS_VERSION\", \
            \"appium:derivedDataPath\": \"$DEVICEFARM_WDA_DERIVED_DATA_PATH\", \
            \"appium:usePrebuiltWDA\": true, \
            \"appium:automationName\": \"XCUITest\"}" \
            >> $DEVICEFARM_LOG_DIR/appium.log 2>&1 &
        fi;

      # This code snippet is to wait until the Appium server starts.
      - |-
        appium_initialization_time=0;
        until curl --silent --fail "http://0.0.0.0:4723${APPIUM_BASE_PATH}/status"; do
          if [[ $appium_initialization_time -gt 30 ]]; then
            echo "Appium did not start within 30 seconds. Exiting...";
            exit 1;
          fi;
          appium_initialization_time=$((appium_initialization_time + 1));
          echo "Waiting for Appium to start on port 4723...";
          sleep 1;
        done;

  # The test phase contains commands for running your tests.
  test:
    commands:
      # Your test package is downloaded and unpackaged into the $DEVICEFARM_TEST_PACKAGE_PATH directory.
      - echo "Navigate to test package directory"
      - cd $DEVICEFARM_TEST_PACKAGE_PATH
      - echo "Starting the Appium TestNG test"

      # The following command runs your Appium Java TestNG test.
      # For more information, please see TestNG's documentation here:
      # https://testng.org/#_running_testng
      - |-
        java -Dappium.screenshots.dir=$DEVICEFARM_SCREENSHOT_PATH org.testng.TestNG -testjar *-tests.jar \
          -d $DEVICEFARM_LOG_DIR/test-output -verbose 10

      # To run your tests with a testng.xml file that is a part of your test package, 
      # use the following commands instead:

      # - echo "Unzipping the tests JAR file"
      # - unzip *-tests.jar
      # - |-
      #   java -Dappium.screenshots.dir=$DEVICEFARM_SCREENSHOT_PATH org.testng.TestNG -testjar *-tests.jar \
      #     testng.xml -d $DEVICEFARM_LOG_DIR/test-output -verbose 10

  # The post-test phase contains commands that are run after your tests have completed.
  # If you need to run any commands to generating logs and reports on how your test performed,
  # we recommend adding them to this section.
  post_test:
    commands:

# Artifacts are a list of paths on the filesystem where you can store test output and reports.
# All files in these paths will be collected by Device Farm, with certain limits (see limit details
# here: https://docs.aws.amazon.com/devicefarm/latest/developerguide/limits.html#file-limits).
# These files will be available through the ListArtifacts API as your "Customer Artifacts".
artifacts:
  # By default, Device Farm will collect your artifacts from the $DEVICEFARM_LOG_DIR directory.
  - $DEVICEFARM_LOG_DIR
```

------

# 用于自定义测试环境的主机
<a name="custom-test-environments-hosts"></a>

 Device Farm 通过使用测试主机环境支持一组带有预配置软件的操作系统。在测试执行期间，Device Farm 使用亚马逊管理的实例（主机），这些实例（主机）动态连接到所选的被测设备。此实例已完全清理，不会在两次运行之间重复使用，并在测试运行结束后以其生成的工件终止。

**Topics**
+ [自定义测试环境的可用测试主机](#custom-test-environments-hosts-available)
+ [为自定义测试环境选择测试主机](#test-host-selection)
+ [自定义测试环境中支持的软件](custom-test-environments-hosts-software.md)
+ [安卓设备的测试环境](custom-test-environments-hosts-android.md)
+ [iOS 设备的测试环境](custom-test-environments-hosts-ios.md)

## 自定义测试环境的可用测试主机
<a name="custom-test-environments-hosts-available"></a>

 测试主机完全由 Device Farm 管理。下表列出了用于自定义测试环境的当前可用和支持的 Device Farm 测试主机。


| 设备平台 | 测试主机 | 操作系统 | 架构 | 支持的设备 | 
| --- | --- | --- | --- | --- | 
|  Android  |  amazon\$1linux\$12  |  Amazon Linux 2  |  x86\$164  |  Android6 及以上  | 
|  iOS  |  macos\$1sequoia  |  macOS Sequoia（第 15 版）  |  arm64  |  iOS15 到 26  | 

**注意**  
Device Farm 会定期为设备平台添加新的测试主机，以支持较新的设备操作系统版本及其依赖项。发生这种情况时，相应设备平台的较旧测试主机将终止支持。

### 操作系统版本
<a name="test-host-os"></a>

 每台可用的测试主机都使用当时 Device Farm 支持的特定版本的操作系统。尽管我们尝试使用最新的操作系统版本，但这可能不是最新的公开发行版本。Device Farm 将使用次要版本更新和安全补丁定期更新操作系统。

 要了解测试运行期间使用的操作系统的特定版本（包括次要版本），可以将以下代码片段添加到测试规范文件的任何阶段。

**Example**  

```
phases:
  install:
    commands:
      # The following example prints the instance's operating system version details
      - |-
        if [[ "Darwin" == "$(uname)" ]]; then
          echo "$(sw_vers --productName) $(sw_vers --productVersion) ($(sw_vers --buildVersion))";
        else
          echo "$(. /etc/os-release && echo $PRETTY_NAME) ($(uname -r))";
        fi
```

## 为自定义测试环境选择测试主机
<a name="test-host-selection"></a>

 您可以在测试[规范文件的相应`ios_test_host`变量中指定 Android `android_test_host` 和 iOS 测试](custom-test-environment-test-spec.md#custom-test-environment-test-spec-syntax)主机。

 如果您没有为给定设备平台指定测试主机选择，则测试将在Device Farm设置为指定设备和测试配置的默认设置的测试主机上运行。

**重要**  
在 iOS 18 及更低版本上进行测试时，如果未选择主机，则将使用旧版测试主机。有关更多信息，请参阅上的主题[旧版 iOS 测试主机](custom-test-environments-hosts-ios.md#legacy-ios-host)。

 例如，请查看以下代码片段：

**Example**  

```
version: 0.1
android_test_host: amazon_linux_2
ios_test_host: macos_sequoia

phases:
  # ...
```

# 自定义测试环境中支持的软件
<a name="custom-test-environments-hosts-software"></a>

 Device Farm 使用预先安装了许多必需软件库的主机来运行我们服务支持的测试框架，从而在启动时提供现成的测试环境。Device Farm 通过使用我们的软件选择机制支持多种语言，并将定期更新环境中包含的语言版本。

对于任何其他必需的软件，您可以修改测试规范文件以从测试包中安装、从 Internet 下载或访问 VPC 内的私有来源（有关更多信息，请参阅 [VPC ENI](https://docs.aws.amazon.com//devicefarm/latest/developerguide/vpc-eni.html)）。有关更多信息，请参阅 [测试规范示例](custom-test-environment-test-spec.md#custom-test-environment-test-spec-example)。

## 预先配置的软件
<a name="custom-test-environments-hosts-software-configured"></a>

 为了便于在每个平台上进行设备测试，测试主机上提供了以下工具：


| 工具 | 设备平台 | 
| --- | --- | 
|   Android SDK Build-Tools   |   Android   | 
|   Android SDK Platform-Tools（包括`adb`）   |   Android   | 
|   Xcode   |   iOS   | 

## 可选软件
<a name="custom-test-environments-hosts-software-selection"></a>

 除了主机上预先配置的软件外，Device Farm 还提供了一种通过`devicefarm-cli`工具选择特定版本的支持软件的方法。

 下表包含可选软件和包含这些软件的测试主机。


| 软件/工具 | 支持该软件的主机 | 要在测试规范中使用的命令 | 
| --- | --- | --- | 
|   Java 17   |   amazon\$1linux\$12   macos\$1sequoia   |   `devicefarm-cli use java 17`   | 
|   Java 11   |   amazon\$1linux\$12   macos\$1sequoia   |   `devicefarm-cli use java 11`   | 
|   Java 8   |   amazon\$1linux\$12   macos\$1sequoia   |   `devicefarm-cli use java 8`   | 
|   Node.js 20   |   amazon\$1linux\$12   macos\$1sequoia   |   `devicefarm-cli use node 20`   | 
|   Node.js 18   |   amazon\$1linux\$12   macos\$1sequoia   |   `devicefarm-cli use node 18`   | 
|   Node.js 16   |   amazon\$1linux\$12   |   `devicefarm-cli use node 16`   | 
|   Python 3.11   |   amazon\$1linux\$12   macos\$1sequoia   |   `devicefarm-cli use python 3.11`   | 
|   Python 3.10   |   amazon\$1linux\$12   macos\$1sequoia   |   `devicefarm-cli use python 3.10`   | 
|   Python 3.9   |   amazon\$1linux\$12   macos\$1sequoia   |   `devicefarm-cli use python 3.9`   | 
|   Python 3.8   |   amazon\$1linux\$12   |   `devicefarm-cli use python 3.8`   | 
|   Ruby 3.2   |   amazon\$1linux\$12   macos\$1sequoia   |   `devicefarm-cli use ruby 3.2`   | 
|   Ruby 2.7   |   amazon\$1linux\$12   |   `devicefarm-cli use ruby 2.7`   | 
|   Appium 3   |   amazon\$1linux\$12   |   `devicefarm-cli use appium 3`   | 
|   Appium 2   |   amazon\$1linux\$12   macos\$1sequoia   |   `devicefarm-cli use appium 2`   | 
|   Appium 1   |   amazon\$1linux\$12   |   `devicefarm-cli use appium 1`   | 
|   Xcode 26   |   macos\$1sequoia   |   `devicefarm-cli use xcode 26`   | 
|   Xcode 16   |   macos\$1sequoia   |   `devicefarm-cli use xcode 16`   | 

测试主机还包括每个软件版本的常用支持工具，例如`pip`和`npm`包管理器（分别包含在 Python 和 Node.js 中）以及 Appium 等工具的依赖项（例如 Appium UIAutomator2 驱动程序）。这可确保您拥有使用支持的测试框架所需的工具。

# 在自定义测试环境中使用 devicefarm-cli 工具
<a name="custom-test-environments-hosts-software-cli"></a>

测试主机使用名为的标准化版本管理工具` devicefarm-cli`来选择软件版本。此工具与 Device Farm 分开， AWS CLI 且仅在 Device Farm 测试主机上可用。使用 `devicefarm-cli`，您可以切换到测试主机上预安装的任何软件版本。这提供了一种随时间推移维护 Device Farm 测试规范文件的简单方法，并为您提供了将来升级软件版本的可预测机制。

**重要**  
 此命令行工具在旧版 iOS 主机上不可用。有关更多信息，请参阅上的主题[旧版 iOS 测试主机](custom-test-environments-hosts-ios.md#legacy-ios-host)。

以下片段显示了 `devicefarm-cli` 的 `help` 页面：

```
$ devicefarm-cli help
 Usage: devicefarm-cli COMMAND [ARGS]
     
     Commands:
         help                         Prints this usage message.
         list                         Lists all versions of software configurable
                                      via this CLI.
         use <software> <version>     Configures the software for usage within the
                                      current shell's environment.
```

让我们来看几个使用 `devicefarm-cli` 的示例。要使用该工具将测试规范文件*3.9*中的 Python 版本从*3.10*更改为，请运行以下命令：

```
$ python --version
Python 3.10.12
$ devicefarm-cli use python 3.9
$ python --version
Python 3.9.17
```

要将 Appium 版本从*1*更改为，请执行以下操作：*2*

```
$ appium --version
1.22.3
$ devicefarm-cli use appium 2
$ appium --version
2.1.2
```

**提示**  
请注意，在选择软件版本时，`devicefarm-cli` 还会切换这些语言的支持工具，例如适用于 Python 的 `pip` 和适用于 NodeJS 的 `npm`。

有关测试主机上预安装的软件的更多信息，请参见[自定义测试环境中支持的软件](custom-test-environments-hosts-software.md)。

# 安卓设备的测试环境
<a name="custom-test-environments-hosts-android"></a>

AWS Device Farm 利用运行 Amazon Linux 2 的 Amazon Elastic Compute Cloud (EC2) 主机来执行 Android 测试。当您安排测试运行时，Device Farm 会为每台设备分配一台专属主机，以独立运行测试。在测试运行后，主机将与生成的构件一起终止运行。

Amazon Linux 2 主机具有以下优点：
+ **更快、更可靠的测试**：与传统主机相比，新的测试主机显著提高了测试速度，尤其是缩短了测试开始时间。Amazon Linux 2 主机在测试期间还表现出更高的稳定性和可靠性。
+ **增强了用于手动测试的远程访问功能**：升级到最新的测试主机并进行了改进，从而降低了延迟，提高了 Android 手动测试的视频性能。
+ **标准软件版本选择**：Device Farm 现在标准化了测试主机上的主要编程语言支持以及 Appium 框架版本。对于支持的语言（目前是 Java、Python、Node.js 和 Ruby）和 Appium，新的测试主机在发布后不久就会提供长期稳定的版本。通过 `devicefarm-cli` 工具进行集中式版本管理可实现跨框架一致的测试规范文件开发。

**Topics**
+ [Device Farm 中 Amazon Linux 2 测试环境支持的 IP 范围](amazon-linux-2-ip-ranges.md)

# Device Farm 中 Amazon Linux 2 测试环境支持的 IP 范围
<a name="amazon-linux-2-ip-ranges"></a>

客户通常需要知道 Device Farm 流量来源的 IP 范围，尤其是在配置防火墙和安全设置时。对于 Amazon EC2 测试主机，IP 范围包括整个 `us-west-2` 区域。对于 Amazon Linux 2 测试主机（新 Android 运行的默认选项），IP 范围已受到限制。现在，流量来自一组特定的 NAT 网关，将 IP 范围限制为以下地址：


****  

| IP 范围 | 
| --- | 
|  **44.236.137.143**  | 
|  **52.13.151.244**  | 
|  **52.35.189.191**  | 
|  **54.201.250.26**  | 

有关 Device Farm 中 Android 测试环境的更多信息，请参阅 [安卓设备的测试环境](custom-test-environments-hosts-android.md)。

# iOS 设备的测试环境
<a name="custom-test-environments-hosts-ios"></a>

 Device Farm 使用亚马逊管理的 macOS 实例（主机），这些实例（主机）在测试运行期间动态连接到 iOS 设备。每台主机都预先配置了软件，可以在各种流行的测试平台（例如 XCTest用户界面和Appium）上进行设备测试。

 与之前的版本相比，iOS 测试主机的当前版本在测试体验的基础上有所改进，包括：
+  **iOS 15 到 iOS 26 的一致主机操作系统和工具体验以**前，测试主机是由使用的设备决定的，因此在多个 iOS 版本上执行时会导致软件环境分散。当前的体验允许简单的主机选择，从而实现跨设备一致的环境。这将使每台 iOS 设备都可以使用相同的 macOS 版本和工具（例如 Xcode）。
+  **iOS 15 和 16 测试的性能改进**使用更新的基础架构，iOS 15 和 16 测试的设置时间已大大缩短。
+  **支持依赖项的标准化可选软件版本**我们现在在 iOS 和 Android 测试主机上都`devicefarm-cli`安装了软件选择系统，使您能够选择我们支持的依赖项的首选版本。对于支持的依赖项（例如 Java、Python、Node.js、Ruby 和 Appium），可以通过测试规范选择版本。要了解此功能的工作原理，请参阅上的主题[自定义测试环境中支持的软件](custom-test-environments-hosts-software.md)。

**重要**  
 如果在 iOS 18 及更低版本上执行，则默认情况下，您的测试将在旧版测试主机上执行。有关如何迁移出旧版主机的信息，请参阅以下主题。

## 旧版 iOS 测试主机
<a name="legacy-ios-host"></a>

 对于 iOS 18 及更低版本上的现有测试，默认情况下会为自定义测试环境选择传统测试主机。下表包含由 iOS 设备版本执行的测试主机版本。


| 操作系统 | 架构 | 设备的默认值 | 
| --- | --- | --- | 
|  macOS Sonoma（第 14 版）  |  arm64  |  iOS 18  | 
|  macOS Ventura（第 13 版） |  arm64  |  iOS 17  | 
|  macOS Monterey（第 12 版） |  x86\$164  |  iOS 16及以下 | 

 要选择较新的测试主机，请参阅相关主题[将您的自定义测试环境迁移到新的 iOS 测试主机](ios-host-migration.md)。

## iOS 设备支持的软件
<a name="ios-host-software-support"></a>

 为了支持 iOS 设备测试，适用于 iOS 设备的 Device Farm 测试主机预先配置了 Xcode 及其相关的命令行工具。有关其他可用软件，请查看相关主题[自定义测试环境中支持的软件](custom-test-environments-hosts-software.md)。

# 将您的自定义测试环境迁移到新的 iOS 测试主机
<a name="ios-host-migration"></a>

 要将现有测试从旧版主机迁移到新的 macOS 测试主机，您需要根据先前存在的测试规范文件开发新的测试规范文件。

 推荐的方法是从所需测试类型的示例测试规范文件开始，然后将相关命令从旧的测试规范文件迁移到新的测试规范文件中。这使您可以利用新主机的示例测试规范的新功能和优化，同时重复使用现有代码片段。

**Topics**
+ [教程：使用控制台迁移 iOS 测试规范文件](#ios-host-migration-console-tutorial)
+ [新测试主机和旧版测试主机之间的差异](#ios-host-migration-differences)

## 教程：使用控制台迁移 iOS 测试规范文件
<a name="ios-host-migration-console-tutorial"></a>

 在此示例中，Device Farm 控制台将用于载入现有 iOS 设备测试规范，以使用新的测试主机。

### 步骤 1：使用控制台创建新的测试规范文件
<a name="ios-host-migration-console-tutorial-step1"></a>

1. 登录 [AWS Device Farm 控制台](https://console.aws.amazon.com/devicefarm)。

1. 导航到包含您的自动化测试的 Device Farm 项目。

1. 下载一份您希望加入的现有测试规范的副本。

   1. 单击 “项目设置” 选项，然后导航到 “**上传**” 选项卡。

   1. 导航到您要使用的测试规范文件。

   1. 单击 “**下载**” 按钮制作此文件的本地副本。

1. 返回到 “项目” 页面，然后单击 “**创建”、“运行**”。

1. 填写向导上的选项，就像开始新的运行一样，但**在 “选择测试规范**” 选项处停下来。

1. 使用默认选择的 iOS 测试规范，单击 “**创建测试规范**” 按钮。

1. 修改文本编辑器中*默认*选择的测试规范。

   1.  如果尚不存在，请使用以下命令修改测试规范文件以选择新主机：

      ```
      ios_test_host: macos_sequoia
      ```

   1. 从上一步中下载的测试规范副本中，查看每份规范` phase`。

   1.  将旧测试规范阶段的命令复制到新测试规范的每个相应阶段，忽略与安装或选择 Java、Python、Node.js、Ruby、Appium 或 Xcode 相关的命令。

1.  在**另存为**文本框中输入新的文件名。

1.  单击 “**另存为新**内容” 按钮以保存您的更改。

 有关可用作参考的测试规范文件的示例，请参阅中提供的示例[测试规范示例](custom-test-environment-test-spec.md#custom-test-environment-test-spec-example)。

### 第 2 步：选择软件预安装的软件
<a name="ios-host-migration-console-tutorial-step2"></a>

 在新的测试主机中，使用名`devicefarm-cli`为的新标准化版本管理工具选择预安装的软件版本。现在，推荐使用此工具来使用我们在测试主机上提供的各种软件。

 例如，您可以添加以下行来使用不同的 JDK 17 测试环境：

```
- devicefarm-cli use java 17
```

 有关可用软件支持的更多信息，请查看：[自定义测试环境中支持的软件](custom-test-environments-hosts-software.md)。

### 第 3 步：通过软件选择工具使用 Appium 及其依赖项
<a name="ios-host-migration-console-tutorial-step3"></a>

 新的测试主机仅支持 Appium 2.x 及更高版本。请使用明确选择 Appium 版本`devicefarm-cli`，同时移除传统工具，例如。` avm`例如：

```
# This line using 'avm' should be removed
# - avm 2.3.1

# And the following lines should be added
- devicefarm-cli use appium 2 # Selects the version
- appium --version            # Prints the version
```

所选的 Appium 版本预`devicefarm-cli`装了适用于 iOS 的驱动程序 XCUITest 的兼容版本。

 此外，你还需要更新测试规范才能使用，` DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH_V9`而不是` DEVICEFARM_WDA_DERIVED_DATA_PATH`。新的环境变量指向 WebDriverAgent 9.x 的预构建版本，这是 Appium 2 测试支持的最新版本。

欲了解更多信息，请查看[为 iOS 测试选择 WebDriverAgent 版本](test-types-appium.md#test-types-appium-select-wda)和[Appium 测试的环境变量](custom-test-environment-variables.md#custom-test-environment-variables-appium)。

## 新测试主机和旧版测试主机之间的差异
<a name="ios-host-migration-differences"></a>

 在编辑测试规范文件以使用新的 iOS 测试主机并从旧版测试主机过渡测试时，请注意以下主要环境差异：
+  **Xcode 版本：**在旧版测试主机环境中，可用的 Xcode 版本基于用于测试的设备的 iOS 版本。例如，在 iOS 18 设备上进行的测试在旧版主机上使用 Xcode 16，而在 iOS 17 上进行的测试则使用 Xcode 15。在新的主机环境中，所有设备都可以访问相同版本的 Xcode，从而为不同版本的设备上的测试提供了一致的环境。有关当前可用的 Xcode 版本的列表，请参阅[支持的软件](custom-test-environments-hosts-software.md)。
+  **选择软件版本：**在许多情况下，默认软件版本已更改，因此，如果您之前没有在旧版测试主机中明确选择软件版本，则可能需要使用立即在新测试主机中指定该版本[`devicefarm-cli`](custom-test-environments-hosts-software-cli.md)。在绝大多数用例中，我们建议客户明确选择他们使用的软件版本。通过选择软件版本，`devicefarm-cli`您将获得可预测且一致的使用体验，并且如果 Device Farm 计划从测试主机中删除该版本，则会收到大量警告。

   此外，诸如 `nvm`、`pyenv`、` avm` 和 `rvm` 之类的软件选择工具已被删除，取而代之的是新的 ` devicefarm-cli` 软件选择系统。
+  **可用的软件版本：**以前预安装的软件的许多版本已被删除，并添加了许多新版本。因此，请确保在使用 `devicefarm-cli` 选择软件版本时，选择[支持的版本列表](custom-test-environments-hosts-software.md)中的版本。
+  **该工具`libimobiledevice`套件已被删除**，转而使用较新的/第一方工具来跟踪当前的iOS设备测试和行业标准。对于 iOS 17 及更高版本，你可以迁移大部分命令以使用类似的 Xcode 工具，名为`devicectl`。有关信息`devicectl`，可以在安装了 Xcode 的计算机上运行`xcrun devicectl help`。
+  **在旧版主机测试规范文件中硬编码**为绝对路径的文件路径很可能无法在新测试主机中按预期工作，并且通常不建议将其用于测试规范文件。我们建议您对所有测试规范文件代码使用相对路径和环境变量。有关更多信息，请查看上的主题[执行自定义测试环境的最佳实践](custom-test-environments-best-practices.md)。
+  **操作系统版本和架构：**传统测试主机根据分配的设备使用各种 macOS 版本和 CPU 架构。因此，用户可能会注意到环境中可用的系统库存在一些差异。有关先前主机操作系统版本的更多信息，请查看[旧版 iOS 测试主机](custom-test-environments-hosts-ios.md#legacy-ios-host)。
+  **对于 Appium** 用户，选择的方式 WebDriverAgent 已更改为使用环境变量前缀，` DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH_V`而不是旧` DEVICEFARM_WDA_DERIVED_DATA_PATH_V`的前缀。有关更新后的变量的更多信息，请查看[Appium 测试的环境变量](custom-test-environment-variables.md#custom-test-environment-variables-appium)。
+  **对于 Appium Java** 用户，新的测试主机的类路径中不包含任何预安装的 JAR 文件，而之前的主机包含一个 TestNG 框架的 JAR 文件（通过环境变量）。`$DEVICEFARM_TESTNG_JAR`我们建议客户将测试框架所必需的 JAR 文件打包到测试包中，并从测试规范文件中删除 `$DEVICEFARM_TESTNG_JAR` 变量的实例。

 如果您从软件角度对测试主机之间的差异有任何反馈或疑问，我们建议您通过支持案例与服务团队联系。

# 使用 IAM 执行角色访问 AWS 资源
<a name="custom-test-environments-iam-roles"></a>

 Device Farm 支持指定将在测试执行期间由自定义测试运行时环境担任的 IAM 角色。此功能允许您的测试安全地访问您账户中的 AWS 资源，例如 Amazon S3 存储桶、DynamoDB 表或您的应用程序所依赖的其他 AWS 服务。

**Topics**
+ [概述](#iam-execution-role-overview)
+ [IAM 角色要求](#iam-role-requirements)
+ [配置 IAM 执行角色](#configuring-iam-execution-role)
+ [最佳实践](#iam-role-best-practices)
+ [问题排查](#troubleshooting-iam-roles)

## 概述
<a name="iam-execution-role-overview"></a>

 当您指定 IAM 执行角色时，Device Farm 将在测试执行期间担任此角色，从而允许您的测试使用角色中定义的权限与 AWS 服务进行交互。

 IAM 执行角色的常见用例包括：
+ 访问存储在 Amazon S3 存储桶中的测试数据
+ 将测试项目推送到 Amazon S3 存储桶
+ 从 AWS 检索应用程序配置 AppConfig
+ 将测试日志和指标写入 Amazon CloudWatch
+ 向 Amazon SQS 队列发送测试结果或状态消息
+ 在测试工作流程中调用 AWS Lambda 函数

## IAM 角色要求
<a name="iam-role-requirements"></a>

 要在 Device Farm 中使用 IAM 执行角色，您的角色必须满足以下要求：
+ **信任关系**：必须信任 Device Farm 服务主体才能担任该角色。信任策略必须包含`devicefarm.amazonaws.com`为可信实体。
+ **权限**：该角色必须具有访问测试所需的 AWS 资源所需的必要权限。
+ **会话时长**：角色的最大会话持续时间必须至少等于您的 Device Farm 项目的作业超时设置。默认情况下，Device Farm 项目的作业超时时间为 150 分钟，因此您的角色必须支持至少 150 分钟的会话持续时间。
+ **相同的账户要求**：IAM 角色必须与用于调用 Device Farm 的角色位于相同的 AWS 账户中。不支持跨账户角色假设。
+ **PassRole 权限**：必须通过允许对指定执行角色执行`iam:PassRole`操作的策略授权调用方传递 IAM 角色。

### 示例信任策略
<a name="trust-policy-example"></a>

 以下示例显示了允许 Device Farm 担任您的执行角色的信任策略。此信任策略应仅附加到您打算在 Device Farm 中使用的特定 IAM 角色，而不应附加到您账户中的其他角色：

**Example**  

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "devicefarm.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

### 权限策略示例
<a name="permissions-policy-example"></a>

 以下示例显示了一个权限策略，该策略授予对测试中使用的常见 AWS 服务的访问权限：

**Example**  

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-test-bucket",
        "arn:aws:s3:::my-test-bucket/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "appconfig:GetConfiguration",
        "appconfig:StartConfigurationSession"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:log-group:/devicefarm/test-*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "sqs:SendMessage",
        "sqs:GetQueueUrl"
      ],
      "Resource": "arn:aws:sqs:*:*:test-results-*"
    }
  ]
}
```

## 配置 IAM 执行角色
<a name="configuring-iam-execution-role"></a>

 您可以在项目级别或为单个测试运行指定 IAM 执行角色。在项目级别进行配置后，该项目中的所有运行都将继承执行角色。在运行时配置的执行角色将取代其父项目上配置的任何执行角色。

 有关配置执行角色的详细说明，请参阅：
+ [在 AWS Device Farm 中创建项目](how-to-create-project.md)-用于在项目级别配置执行角色
+ [在 Device Farm 中创建测试运行](how-to-create-test-run.md)-用于为单个运行配置执行角色

 您也可以使用 Device Farm API 配置执行角色。如需了解更多信息，请参阅 Dev [ice Farm API 参考](https://docs.aws.amazon.com/devicefarm/latest/APIReference/)。

## 最佳实践
<a name="iam-role-best-practices"></a>

 在为 Device Farm 测试配置 IAM 执行角色时，请遵循以下最佳实践：
+ **最低权限原则**：仅授予测试运行所需的最低权限。避免使用过于宽泛的权限，例如`*`操作或资源。
+ **使用特定资源的权限**：如果可能，请将权限限制为特定资源（例如特定的 S3 存储桶或 DynamoDB 表），而不是某一类型的所有资源。
+ **将测试资源和生产资源分开**：使用专用的测试资源和角色，以避免在测试期间意外影响生产系统。
+ **定期审查角色**：定期审查和更新您的执行角色，以确保他们仍然满足您的测试需求并遵循安全最佳实践。
+ **使用条件键**：考虑使用 IAM 条件键来进一步限制角色的使用时间和方式。

## 问题排查
<a name="troubleshooting-iam-roles"></a>

 如果您遇到与 IAM 执行角色有关的问题，请检查以下内容：
+ **信任关系**：验证角色的信任策略是否包含`devicefarm.amazonaws.com`为可信服务。
+ **权限**：检查该角色是否具有您的测试尝试访问的 AWS 服务的必要权限。
+ **测试日志**：查看测试执行日志，了解与 AWS API 调用或权限拒绝相关的特定错误消息。

# 自定义测试环境的环境变量
<a name="custom-test-environment-variables"></a>

 Device Farm 动态配置多个环境变量，以便在自定义测试环境运行中使用。

**Topics**
+ [自定义环境变量](#custom-test-environment-variables-custom)
+ [常用环境变量](#custom-test-environment-variables-common)
+ [Appium 测试的环境变量](#custom-test-environment-variables-appium)
+ [XCUITest 测试的环境变量](#custom-test-environment-variables-xcuitest)

## 自定义环境变量
<a name="custom-test-environment-variables-custom"></a>

 Device Farm 支持配置在测试主机上作为环境变量应用的键值对。这些变量可以在 Device Farm 项目上配置，也可以在运行创建过程中进行配置；运行时配置的任何变量都将取代其父项目上可能配置的任何变量。以下限制适用：
+ 旧版 iOS 测试主机不支持自定义环境变量。有关更多信息，请参阅 [旧版 iOS 测试主机](custom-test-environments-hosts-ios.md#legacy-ios-host)。
+ 以开头的`$DEVICEFARM_`变量名保留供内部服务使用。
+ 自定义环境变量不得用于在测试规范中配置测试主机计算选择。

## 常用环境变量
<a name="custom-test-environment-variables-common"></a>

 本节介绍了 Device Farm 中所有测试共有的环境变量。

** `$DEVICEFARM_DEVICE_NAME` **  
 运行测试的设备。它代表设备的唯一设备标识符 (UDID)。

** `$DEVICEFARM_DEVICE_UDID` **  
 设备的唯一标识符。

** `$DEVICEFARM_DEVICE_PLATFORM_NAME` **  
 设备的平台名称。要么是要`Android`么`iOS`。

** `$DEVICEFARM_DEVICE_OS_VERSION` **  
 设备的操作系统版本。

** `$DEVICEFARM_APP_PATH` **  
 *（移动应用程序测试）*   
 在其上执行测试的主机上移动应用程序的路径。此变量在 Web 测试期间不可用。

** `$DEVICEFARM_LOG_DIR` **  
 默认目录的路径，存储客户日志、工件和其他所需文件以供日后检索。使用[示例测试规范](custom-test-environment-test-spec.md#custom-test-environment-test-spec-example)，此目录中的文件存档在 ZIP 文件中，并在测试运行后作为构件提供。

** `$DEVICEFARM_SCREENSHOT_PATH` **  
 测试运行期间捕获的屏幕截图（如果有）的路径。

** `$DEVICEFARM_PROJECT_ARN` **  
 作业的上级项目的 ARN。

** `$DEVICEFARM_RUN_ARN` **  
 作业的父项运行的 ARN。

** `$DEVICEFARM_DEVICE_ARN` **  
 被测设备的 ARN。

** `$DEVICEFARM_TOTAL_JOBS` **  
 与其父 Device Farm 运行相关的任务总数。

** `$DEVICEFARM_JOB_NUMBER` **  
 这份工作的编号在里面`$DEVICEFARM_TOTAL_JOBS`。例如，一次运行可能包含 5 个作业，每个任务都有一个`$DEVICEFARM_JOB_NUMBER`从 0 到 4 的唯一任务。

** `$AWS_REGION` **  
 AWS 区域。该服务会将其设置为与被测设备所在的区域相匹配。如果需要，它可以被自定义环境变量覆盖。

** `$ANDROID_HOME` **  
 *（仅限 Android 设备）*   
 Android 软件开发工具包安装目录的路径。

## Appium 测试的环境变量
<a name="custom-test-environment-variables-appium"></a>

 本节介绍任何 Appium 测试在 Device Farm 的自定义测试环境中使用的环境变量。

** `$DEVICEFARM_CHROMEDRIVER_EXECUTABLE_DIR` **  
 *（仅限 Android 设备）*   
 包含在 Appium Web 和 ChromeDriver 混合测试中使用的必要可执行文件的目录的位置。

** `$DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH_V<N>` **  
 *（仅限 iOS）*   
 为在 Device Farm 上运行 WebDriverAgent 而构建的版本的派生数据路径。变量上的编号将对应于的主要版本。 WebDriverAgent举个例子，`DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH_V9`将指向 9.x WebDriverAgent 的 a 版本。有关更多信息，请参阅 [为 iOS 测试选择 WebDriverAgent 版本](test-types-appium.md#test-types-appium-select-wda)。  
 `$DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH_V<N>`环境变量仅存在于非旧版 iOS 主机上。有关更多信息，请参阅 [旧版 iOS 测试主机](custom-test-environments-hosts-ios.md#legacy-ios-host)。

** `$DEVICEFARM_WDA_DERIVED_DATA_PATH_V9` **  
 *（仅限 iOS，已弃用）*   
 为在 Device Farm 上运行 WebDriverAgent 而构建的版本的派生数据路径。有关替换命名方案，请参阅。`$DEVICEFARM_APPIUM_WDA_DERIVED_DATA_PATH_V<N>`

## XCUITest 测试的环境变量
<a name="custom-test-environment-variables-xcuitest"></a>

 本节介绍 XCUITest 测试在 Device Farm 的自定义测试环境中使用的环境变量。

** `$DEVICEFARM_XCUITESTRUN_FILE` **  
 Device Farm `.xctestun` 文件的路径。它是从您的应用程序和测试程序包生成的。

** `$DEVICEFARM_DERIVED_DATA_PATH` **  
Device Farm xcodebuild 输出的预期路径。

** `$DEVICEFARM_XCTEST_BUILD_DIRECTORY` **  
测试程序包文件的解压缩内容的路径。

# 执行自定义测试环境的最佳实践
<a name="custom-test-environments-best-practices"></a>

 以下主题涵盖了在 Device Farm 中使用自定义测试执行的推荐最佳实践。

**运行配置**
+  尽可能@@ **依靠 Device Farm 托管软件和 API 功能进行运行配置**，而不是通过测试规范文件中的 shell 命令应用类似的配置。这包括测试主机和设备的配置，因为这将在测试主机和设备之间更具可持续性和一致性。

   虽然 Device Farm 鼓励您根据需要自定义测试规范文件以运行测试，但随着时间的推移，随着更多自定义命令的添加，测试规范文件可能会变得难以维护。使用 Device Farm 托管软件（通过类似工具` devicefarm-cli`和中的默认可用工具`$PATH`），并使用托管功能（如[https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ScheduleRunConfiguration.html#devicefarm-Type-ScheduleRunConfiguration-deviceProxy](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ScheduleRunConfiguration.html#devicefarm-Type-ScheduleRunConfiguration-deviceProxy)请求参数），通过将维护责任转移给 Device Farm 本身来简化测试规范文件。

**测试规范和测试包代码**
+  **请勿在测试规范文件或测试包代码中使用绝对路径或依赖特定的次要版本**。Device Farm 会将例行更新应用于选定的测试主机及其随附的软件版本。使用特定或绝对路径（例如` /usr/local/bin/python`代替`python`）或要求特定的次要版本（例如Node.js`20.3.1`而不仅仅是` 20`）可能会导致您的测试无法找到所需的可执行文件/文件。

   作为自定义测试执行的一部分，Device Farm 会设置各种环境`$PATH`变量和变量，以确保测试在我们的动态环境中获得一致的体验。有关更多信息，请参阅 [自定义测试环境的环境变量](custom-test-environment-variables.md) 和 [自定义测试环境中支持的软件](custom-test-environments-hosts-software.md)。
+  **在测试运行期间，将生成或复制的文件保存在临时目录中。**今天，我们确保用户在测试执行期间可以访问临时目录 (`/tmp`)（除了托管目录，例如`$DEVICEFARM_LOG_DIR`）。用户有权访问的其他目录可能会随着时间的推移而发生变化，这取决于所使用的服务或操作系统的需要。
+  **将您的测试执行日志保存到`$DEVICEFARM_LOG_DIR`**。这是为您的执行提供的默认构件目录，用于向其中添加执行日志/工件。默认情况下，我们提供的每个[示例测试规范](custom-test-environment-test-spec.md#custom-test-environment-test-spec-example)都使用此目录存放工件。
+  在测试规范`test`阶段**，确保命令在失败时返回非零代码**。我们通过检查该`test`阶段调用的每个 shell 命令的非零退出代码来确定您的执行是否失败。您应确保您的逻辑或测试框架将为所有所需场景返回非零的退出代码，这可能需要额外的配置。

   例如，某些测试框架（例如 JUnit5）不认为零测试运行失败，这会导致即使未执行任何测试也能检测到您的测试已成功运行。以此 JUnit5 为例，您需要指定命令行选项，以确保此场景`--fail-if-no-tests`以非零的退出代码退出。
+  **查看软件与将用于测试运行的设备操作系统版本和测试主机版本的兼容性**。例如，测试软件框架（例如：Appium）中的某些功能可能无法在被测试设备的所有操作系统版本上按预期运行。

**安全性**
+  **避免在测试规范文件中存储或记录敏感变量（如 AWS 密钥）。**测试规范文件、测试规范生成的脚本和测试规范脚本的日志都作为可下载的工件在测试执行结束时提供。这可能会导致您账户中对您的测试运行具有读取权限的其他用户意外泄露机密。

# 将测试从标准测试环境迁移到自定义测试环境
<a name="custom-test-environment-migration"></a>

在 AWS Device Farm 中，您可以从标准测试执行模式切换到自定义执行模式。迁移主要涉及两种不同的执行模式：

1. **标准模式**：此测试执行模式主要用于为客户提供精细的报告和完全托管的环境。

1. **自定义模式**：此测试执行模式专为不同的用例而构建，这些用例需要更快的测试运行、提升和转换能力、并能实现与本地环境的平衡，以及实时视频流。

有关 Device Farm 中标准模式和自定义模式的更多信息，请参阅 [AWS Device Farm 中的测试环境](test-environments.md)和 [AWS Device Farm 中的自定义测试环境](custom-test-environments.md)。

## 迁移时的注意事项
<a name="considerations-when-migrating"></a>

本节列出了迁移到自定义模式时需要考虑的一些重要用例：

1. **速度**：在标准执行模式下，Device Farm 使用特定框架的打包说明解析您已打包并上传的测试的元数据。解析会检测软件包中的测试数量。之后，Device Farm 将分别运行每项测试，并分别显示每项测试的日志、视频和其他结果构件。但是，这会稳步增加总 end-to-end测试执行时间，因为服务端有测试和结果工件的预处理和后处理。

   相比之下，自定义执行模式不会解析您的测试包；这意味着无需对测试或结果构件进行预处理和最少的后期处理。这会使总 end-to-end执行时间接近您的本地设置。测试的执行格式与在本地计算机上运行时的格式相同。测试结果与您在本地获得的结果相同，可在任务执行结束时下载。

1. **自定义或灵活性**：标准执行模式解析您的测试包以检测测试数量，然后分别运行每个测试。请注意，不能保证测试会按照您指定的顺序运行。因此，需要特定执行顺序的测试可能无法按预期运行。此外，无法自定义主机环境或传递以某种方式运行测试所需的配置文件。

   相比之下，自定义模式允许您配置主机环境，包括安装其他软件、将筛选条件传递给测试、传递配置文件以及控制测试执行设置。它通过一个 yaml 文件（也称为 testspec 文件）来实现这一点，您可以通过向其中添加 shell 命令来修改该文件。此 yaml 文件被转换为在测试主机上执行的 shell 脚本。您可以保存多个 yaml 文件，并在安排运行时根据需要动态选择一个。

1. **直播视频和日志**：标准和自定义执行模式均可为您提供测试所需的视频和日志。但是，在标准模式下，只有在测试完成后才能获得测试的视频和预定义日志。

   相比之下，自定义模式为您提供测试视频和客户端日志的实时流。此外，您还可以在测试结束时下载视频和其他构件。

**提示**  
如果您的用例至少涉及上述因素之一，我们强烈建议您切换到自定义执行模式。

## 迁移步骤
<a name="migrating-to-custom"></a>

要从标准模式迁移到自定义模式，请执行以下操作：

1. 登录 AWS 管理控制台 并打开 Device Farm 控制台，网址为[https://console.aws.amazon.com/devicefarm/](https://console.aws.amazon.com/devicefarm/)。

1. 选择您的项目，然后启动新的自动化运行。

1. 上传您的应用程序（或选择 `web app`），选择您的测试框架类型，上传您的测试包，然后在“`Choose your execution environment`”参数下选择选项以`Run your test in a custom environment`。

1. 默认情况下，将显示 Device Farm 的示例测试规范文件以供您查看和编辑。此示例文件可用作在[自定义环境模式下](https://docs.aws.amazon.com/devicefarm/latest/developerguide/custom-test-environments.html)试用测试的起点。然后，在控制台确认测试运行正常后，您可以更改与 Device Farm 的任何 API、CLI 和管道集成，以便在安排测试运行时使用此测试规范文件作为参数。有关如何添加测试规范文件作为运行参数的信息，请参阅我们的《API 指南》中有关 `ScheduleRun` API 的 `testSpecArn` 参数部分。[https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ScheduleRun.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ScheduleRun.html)

## Appium 框架
<a name="custom-test-environment-migration-appium"></a>

在自定义测试环境中，Device Farm 不会在 Appium 框架测试中插入或覆盖任何 Appium 功能。您必须在测试规范 YAML 文件或测试代码中指定测试的 Appium 功能。

## Android Instrumentation
<a name="custom-test-environment-migration-instrumentation"></a>

您不需要执行任何更改，即可将 Android Instrumentation 测试迁移到自定义测试环境。

## iOS XCUITest
<a name="custom-test-environment-migration-xcuitest"></a>

您无需进行更改即可将 iOS XCUITest 测试移至自定义测试环境。

# 在 Device Farm 中扩展自定义测试环境
<a name="custom-test-environments-extending"></a>

AWS Device Farm 支持配置用于自动测试的自定义环境（自定义模式），这是针对所有 Device Farm 用户的推荐方法。Device Farm 自定义模式支持运行的不仅限于测试套件。在本节中，您将学习如何扩展测试套件和优化测试。

有关 Device Farm 中自定义测试环境的更多信息，请参阅 [AWS Device Farm 中的自定义测试环境](custom-test-environments.md)。

**Topics**
+ [在 Device Farm 中运行测试时设置设备 PIN](custom-test-environments-extending-set-pin.md)
+ [通过所需的功能加快 Device Farm 中基于 Appium 的测试](custom-test-environments-extending-speed.md)
+ [在 Device Farm 中运行测试 APIs 后使用 Webhook 和其他内容](custom-test-environments-extending-webhooks.md)
+ [在 Device Farm 中向测试程序包中添加额外文件](custom-test-environments-extending-files.md)

# 在 Device Farm 中运行测试时设置设备 PIN
<a name="custom-test-environments-extending-set-pin"></a>

 某些应用程序要求您在设备上设置 PIN。Device Farm 不支持在设备上原生设置 PIN。但是，这是可能的，但需要注意以下几点：
+ 设备必须运行 Android 8 或更高版本。
+ 测试完成后必须删除 PIN。

 要在测试中设置 PIN，请使用 `pre_test` 和 `post_test` 阶段来设置和删除 PIN，如下所示：

```
phases:
    pre_test:
      - # ... among your pre_test commands
      - DEVICE_PIN_CODE="1234"
      - adb shell locksettings set-pin "$DEVICE_PIN_CODE"
    post_test:
      - # ... Among your post_test commands
      - adb shell locksettings clear --old "$DEVICE_PIN_CODE"
```

 开始您的测试套件时，将设置 PIN 1234。退出测试套件后，PIN 将被删除。

**警告**  
如果您在测试完成后没有从设备上删除 PIN 码，则设备和您的账户将被隔离。

有关扩展测试套件和优化测试的更多方法，请参阅 [在 Device Farm 中扩展自定义测试环境](custom-test-environments-extending.md)。

# 通过所需的功能加快 Device Farm 中基于 Appium 的测试
<a name="custom-test-environments-extending-speed"></a>

使用 Appium 时，您可能会发现标准模式测试套件非常慢。这是因为 Device Farm 会应用默认设置，并且不会对您希望如何使用 Appium 环境做出任何假设。虽然这些默认值是围绕行业最佳实践建立的，但它们可能不适用于您的情况。要微调 Appium 服务器的参数，可以在测试规范中调整默认的 Appium 功能。例如，以下内容在 iOS 测试套件中将 `usePrebuildWDA` 功能设置为 `true`，以加快初始启动时间：

```
phases:
  pre_test:
    - # ... Start up Appium
    - >-
    appium --log-timestamp
    --default-capabilities "{\"usePrebuiltWDA\": true, \"derivedDataPath\":\"$DEVICEFARM_WDA_DERIVED_DATA_PATH\",
    \"deviceName\": \"$DEVICEFARM_DEVICE_NAME\", \"platformName\":\"$DEVICEFARM_DEVICE_PLATFORM_NAME\", \"app\":\"$DEVICEFARM_APP_PATH\",
    \"automationName\":\"XCUITest\", \"udid\":\"$DEVICEFARM_DEVICE_UDID_FOR_APPIUM\", \"platformVersion\":\"$DEVICEFARM_DEVICE_OS_VERSION\"}"
    >> $DEVICEFARM_LOG_DIR/appiumlog.txt 2>&1 &
```

Appium 功能必须是经过 shell 转义的、带引号的 JSON 结构。

以下 Appium 功能是性能改进的常见来源：

`noReset` 和 `fullReset`  
这两种功能是相互排斥的，它们描述了 Appium 在每个会话完成后的行为。当 `noReset` 设置为 `true` 时，Appium 服务器不会在 Appium 会话结束时从应用程序中删除数据，实际上不会进行任何清理。`fullReset` 会在会话关闭后从设备中卸载并清除所有应用程序数据。有关更多信息，请参阅 Appium 文档中的 [Reset Strategies](http://appium.io/docs/en/writing-running-appium/other/reset-strategies/)。

`ignoreUnimportantViews`（仅限 Android）  
指示 Appium 将 Android 界面层次结构仅压缩为测试的*相关*视图，从而加快某些元素的查找速度。但是，这可能会破坏一些 XPath基于测试套件，因为界面布局的层次结构已更改。

`skipUnlock`（仅限 Android）  
通知 Appium 当前没有设置 PIN 码，这样可以在屏幕关闭事件或其他锁定事件发生后加快测试速度。

`webDriverAgentUrl`（仅限 iOS）  
指示 Appium 假设一个基本的 iOS 依赖项 `webDriverAgent` 已经在运行，并且可以在指定 URL 上接受 HTTP 请求。如果 `webDriverAgent` 尚未启动并运行，Appium 在测试套件开始时可能需要一些时间才能启动 `webDriverAgent`。如果您自己启动 `webDriverAgent` 并在启动 Appium 时将 `webDriverAgentUrl` 设置为 `http://localhost:8100`，则可以更快地启动测试套件。请注意，切勿将此功能与 `useNewWDA` 功能一起使用。  
您可以使用以下代码通过设备本地端口 `8100` 上的测试规范文件启动 `webDriverAgent`，然后将其转发到测试主机的本地端口`8100`（这允许您将 `webDriverAgentUrl` 的值设置为 `http://localhost:8100`）。在定义了任何用于设置 Appium 和 `webDriverAgent` 环境变量的代码之后，应在安装阶段运行此代码：  

```
      # Start WebDriverAgent and iProxy
      - >-
        xcodebuild test-without-building -project /usr/local/avm/versions/$APPIUM_VERSION/node_modules/appium/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj
        -scheme WebDriverAgentRunner -derivedDataPath $DEVICEFARM_WDA_DERIVED_DATA_PATH
        -destination id=$DEVICEFARM_DEVICE_UDID_FOR_APPIUM IPHONEOS_DEPLOYMENT_TARGET=$DEVICEFARM_DEVICE_OS_VERSION
        GCC_TREAT_WARNINGS_AS_ERRORS=0 COMPILER_INDEX_STORE_ENABLE=NO >> $DEVICEFARM_LOG_DIR/webdriveragent_log.txt 2>&1 &
        
        iproxy 8100 8100 >> $DEVICEFARM_LOG_DIR/iproxy_log.txt 2>&1 &
```
然后，您可以将以下代码添加到测试规范文件中，以确保 `webDriverAgent` 成功启动。在确保 Appium 成功启动后，应在预测试阶段结束时运行此代码：  

```
      # Wait for WebDriverAgent to start
      - >-
        start_wda_timeout=0;
        while [ true ];
        do
          if [ $start_wda_timeout -gt 60 ];
          then
              echo "WebDriverAgent server never started in 60 seconds.";
              exit 1;
          fi;
          grep -i "ServerURLHere" $DEVICEFARM_LOG_DIR/webdriveragent_log.txt >> /dev/null 2>&1;
          if [ $? -eq 0 ];
          then
              echo "WebDriverAgent REST http interface listener started";
              break;
          else
              echo "Waiting for WebDriverAgent server to start. Sleeping for 1 seconds";
              sleep 1;
              start_wda_timeout=$((start_wda_timeout+1));
          fi;
        done;
```

有关 Appium 支持的功能的更多信息，请参阅 Appium 文档中的 [Appium Desired Capabilities](http://appium.io/docs/en/writing-running-appium/caps/)。

有关扩展测试套件和优化测试的更多方法，请参阅 [在 Device Farm 中扩展自定义测试环境](custom-test-environments-extending.md)。

# 在 Device Farm 中运行测试 APIs 后使用 Webhook 和其他内容
<a name="custom-test-environments-extending-webhooks"></a>

在每个测试套件使用 **curl** 完毕后，您可以让 Device Farm 调用 webhook。执行此操作的过程因目的地和格式而异。对于您的特定 webhook，请参阅该 webhook 的文档。以下示例会在每次测试套件完成时向 Slack webhook 发布一条消息：

```
phases:
  post_test:
    - curl -X POST -H 'Content-type: application/json' --data '{"text":"Tests on '$DEVICEFARM_DEVICE_NAME' have finished!"}' https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
```

有关将 webhook 与 Slack 结合使用的更多信息，请参阅 Slack API 参考中的 [Sending your first Slack message using Webhook](https://api.slack.com/tutorials/slack-apps-hello-world)。

有关扩展测试套件和优化测试的更多方法，请参阅 [在 Device Farm 中扩展自定义测试环境](custom-test-environments-extending.md)。

您不仅局限于使用 **curl** 来调用 webhook。测试包可以包含额外的脚本和工具，前提是它们与 Device Farm 执行环境兼容。例如，您的测试包可能包含向其他人发出请求的辅助脚本 APIs。确保将所有必需的软件包与测试套件的要求一起安装。要添加在测试套件完成后运行的脚本，请将该脚本包含在测试包中，并将以下内容添加到测试规范中：

```
phases:
  post_test:
    - python post_test.py
```

**注意**  
您有责任维护测试包中使用的任何 API 密钥或其他身份验证令牌。我们建议您将任何形式的安全凭证排除在源代码控制之外，使用权限尽可能少的证书，并尽可能使用可撤销的短期令牌。要验证安全要求，请参阅您 APIs 使用的第三方的文档。

如果您计划将 AWS 服务用作测试执行套件的一部分，则应使用在测试套件之外生成并包含在测试包中的 IAM 临时证书。这些证书应具有最少的授予权限和最短的生命周期。有关创建临时安全凭证的更多信息，请参阅《IAM 用户指南》**中的[使用临时安全凭证](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_credentials_temp_request.html)。

有关扩展测试套件和优化测试的更多方法，请参阅 [在 Device Farm 中扩展自定义测试环境](custom-test-environments-extending.md)。

# 在 Device Farm 中向测试程序包中添加额外文件
<a name="custom-test-environments-extending-files"></a>

您可能希望在测试中使用其他文件作为额外配置文件或其他测试数据。您可以在将这些额外文件上传到 AWS Device Farm之前将其添加到测试包中，然后通过自定义环境模式访问这些文件。从根本上讲，所有测试包上传格式（ZIP、IPA、APK、JAR 等）都是支持标准 ZIP 操作的包存档格式。

在将文件上传到测试存档之前，您可以使用以下命令将其添加到 AWS Device Farm 测试存档：

```
$ zip zip-with-dependencies.zip extra_file
```

要获取额外文件的目录，请执行以下操作：

```
$ zip -r zip-with-dependencies.zip extra_files/
```

除了 IPA 文件外，这些命令适用于所有测试包上传格式。对于 IPA 文件，尤其是与一起使用时 XCUITests，由于 iOS 测试包的 AWS Device Farm 重新设计方式，我们建议您将任何多余的文件放在略有不同的位置。构建 iOS 测试时，测试应用程序目录将位于另一个名为的目录中*Payload*。

例如，此类 iOS 测试目录可能是这样的：

```
$ tree
.
└── Payload
    └── ADFiOSReferenceAppUITests-Runner.app
        ├── ADFiOSReferenceAppUITests-Runner
        ├── Frameworks
        │   ├── XCTAutomationSupport.framework
        │   │   ├── Info.plist
        │   │   ├── XCTAutomationSupport
        │   │   ├── _CodeSignature
        │   │   │   └── CodeResources
        │   │   └── version.plist
        │   └── XCTest.framework
        │       ├── Info.plist
        │       ├── XCTest
        │       ├── _CodeSignature
        │       │   └── CodeResources
        │       ├── en.lproj
        │       │   └── InfoPlist.strings
        │       └── version.plist
        ├── Info.plist
        ├── PkgInfo
        ├── PlugIns
        │   ├── ADFiOSReferenceAppUITests.xctest
        │   │   ├── ADFiOSReferenceAppUITests
        │   │   ├── Info.plist
        │   │   └── _CodeSignature
        │   │       └── CodeResources
        │   └── ADFiOSReferenceAppUITests.xctest.dSYM
        │       └── Contents
        │           ├── Info.plist
        │           └── Resources
        │               └── DWARF
        │                   └── ADFiOSReferenceAppUITests
        ├── _CodeSignature
        │   └── CodeResources
        └── embedded.mobileprovision
```

对于这些 XCUITest 软件包，请将任何额外的文件添加到目录*.app*内结尾的*Payload*目录中。例如，以下命令显示如何向此测试包中添加文件：

```
$ mv extra_file Payload/*.app/
$ zip -r my_xcui_tests.ipa Payload/
```

将文件添加到测试包时，根据其上传格式， AWS Device Farm 中的交互行为可能会略有不同。如果上传文件使用 ZIP 文件扩展名，则 AWS Device Farm 将在测试之前自动解压缩上传文件，并将解压缩的文件留在环境变量所在的位置。*\$1DEVICEFARM\$1TEST\$1PACKAGE\$1PATH*（这意味着，如果您像第一个示例那样在档案的根目录中添加了一个名*extra\$1file*为的文件，则该文件将在测试*\$1DEVICEFARM\$1TEST\$1PACKAGE\$1PATH/extra\$1file*期间位于该文件所在的位置）。

举一个更实际的例子，如果你是 Appium Testng 用户，想要在测试中加入一个*testng.xml*文件，你可以使用以下命令将其包含在存档中：

```
$ zip zip-with-dependencies.zip testng.xml
```

然后，您可以在自定义环境模式下将测试命令更改为以下内容：

```
java -D appium.screenshots.dir=$DEVICEFARM_SCREENSHOT_PATH org.testng.TestNG -testjar *-tests.jar -d $DEVICEFARM_LOG_DIR/test-output $DEVICEFARM_TEST_PACKAGE_PATH/testng.xml
```

如果您的测试包上传扩展名不是 ZIP（例如 APK、IPA 或 JAR 文件），则可以在上找到上传的包文件本身*\$1DEVICEFARM\$1TEST\$1PACKAGE\$1PATH*。由于这些文件仍然是存档格式的文件，因此您可以解压缩文件，以便从中访问其他文件。例如，以下命令会将测试包的内容（用于 APK、IPA 或 JAR 文件）解压缩到该*/tmp*目录：

```
unzip $DEVICEFARM_TEST_PACKAGE_PATH -d /tmp
```

如果是 APK 或 JAR 文件，您会发现多余的文件已解压缩到该*/tmp*目录（例如）。*/tmp/extra\$1file*如前所述，对于 IPA 文件，多余文件将位于以结尾的文件夹内稍有不同的位置*.app*，也就是*Payload*目录内。例如，根据上面的 IPA 示例，可以在该位置找到该文件*/tmp/Payload/ADFiOSReferenceAppUITests-Runner.app/extra\$1file*（可引用为*/tmp/Payload/\$1.app/extra\$1file*）。

有关扩展测试套件和优化测试的更多方法，请参阅 [在 Device Farm 中扩展自定义测试环境](custom-test-environments-extending.md)。