你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

适用于 Java 的 Azure Core 测试共享库 - 版本 1.22.0

此库包含用于测试 Azure SDK 客户端库的核心类。

较新的 SDK 测试利用 Azure SDK 工具测试代理 来记录和播放 HTTP 交互。 若要从现有 TestBase 迁移以使用测试代理,或了解有关使用测试代理的详细信息,请参阅 测试代理迁移指南

目录

入门

若要使用此包,请将以下内容添加到 pom.xml


<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-core-test</artifactId>
  <version>1.22.0</version>
</dependency>

关键概念

  • Record 模式下运行测试:若要记录任何 HTTP 请求,请将其存储在文件中,然后存储从最初面向的实时资源收到的响应。
  • Playback 模式下运行测试:播放意味着截获任何 HTTP 请求,并使用之前记录的匹配请求的存储响应对其进行响应。
  • Live 模式下运行测试:实时运行意味着不截获任何 HTTP 请求,直接将其发送到 Azure 服务。
  • 清理敏感信息:敏感信息意味着应从录制内容中清除密码、唯一标识符或个人信息等内容。
  • TestProxyTestBase:基本测试类,用于创建 InterceptorManager 并使测试可用于 test-proxy 运行测试。 它播放测试会话数据或记录测试会话。
  • InterceptorManager:一个类,它通过从现有测试会话记录读取数据或在内存中记录网络调用来跟踪网络调用。 从“.assets/{library-level}/src/test/resources/session-records/TestFileName.testName}.json”保存或读取测试会话记录。
  • TestProxyRecordPolicy:使用 记录网络调用的 test-proxy管道策略。
  • TestProxyPlaybackClient:使用测试代理播放来自会话记录的记录数据的响应的 HTTP 客户端。

编写或运行测试

设置测试资源

若要运行实时测试和生成录制内容,需要实时 Azure 资源。

如果尚未为测试资源部署设置 test-resources.json 文件,并且/或想要使用自己的测试资源,只需将凭据配置为面向这些资源。

若要创建 test-resources.json 文件,请执行以下操作:

  1. 为特定服务和所需的配置创建 Azure 资源管理模板。 这可以通过在 门户中 创建资源来完成,并在最后一步 (查看 + 创建) ,单击“下载用于自动化的模板”。
  2. 将此模板保存到 test-resources.json 包含包 () sdk/<my-service>/test-resources.json 文件的目录下的文件。 可以参考 表的 作为示例。
  3. 示例) (分组"resources"部分test-resources.json添加任何其他资源的模板。
  4. 向 添加一个 "outputs" 部分 test-resources.json ,描述访问这些资源所需的任何环境变量 (示例) 。

配置凭据

Java SDK 测试使用 EnvironmentVariables 来存储测试凭据。

New-TestResources如果使用 /eng/common/TestResources 中的脚本,则脚本应输出为服务运行实时测试所需的任何环境变量。 将这些变量存储在具有适当格式的本地环境变量中后,运行测试时,将在环境中设置凭据和测试配置变量。

如果服务没有 test-resources.json 用于测试部署的文件,则至少需要为 AZURE_SUBSCRIPTION_IDAZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET 设置环境变量。

  1. AZURE_SUBSCRIPTION_ID 变量设置为组织的订阅 ID。 可以在 Azure 门户中“订阅”边栏选项卡的“概述”部分找到它。
  2. AZURE_TENANT_ID定义测试服务主体的 、 AZURE_CLIENT_IDAZURE_CLIENT_SECRET 。 如果没有服务主体,请使用 Azure CLI 的 az ad sp create-for-rbac 命令 ( 理想情况下,使用别名作为服务主体的名称前缀) :
az login
az ad sp create-for-rbac --name "{your alias}-tests" --role Contributor

该命令将输出一组凭据。 在环境变量中设置 AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET 的值。

启动测试代理服务器

测试代理必须可用,才能使测试正常工作;当测试从 TestProxyTestBase扩展时,会自动完成此操作。 方法 com.azure.core.test.TestProxyTestBase#setupTestProxy() 负责启动测试代理。

public class MyTest extends TestProxyTestBase {
    // method in TestProxyTestBase 
    @BeforeAll
    public static void setupTestProxy(TestInfo testInfo) {
        // Start the test proxy server
        testProxyManager.startProxy();
    }
}

有关如何启动测试代理或测试代理本身的详细信息,请参阅 测试代理迁移指南

编写测试

每个 SDK 都应在其 tests 目录中包括客户端同步和异步测试, (sdk/{service}/{package}/tests) 命名模式 {ServiceName}ClientTest.java{ServiceName}AsyncClientTest.java。 将 {ServiceName}ClientTest 负责测试同步客户端,而 {ServiceName}AsyncClientTest 将负责测试异步客户端。 {ServiceName}ClientTest和 两者{ServiceName}AsyncClientTest都会扩展 ,{ServiceName}ClientTestBase然后扩展 TestProxyTestBase 类。 将 {ServiceName}ClientTestBase 负责初始化客户端、准备测试数据、注册消毒器/匹配器等 (在此示例中,我们使用 Tables SDK 进行演示) :


/**
 * Set the AZURE_TEST_MODE environment variable to either PLAYBACK or RECORD to determine if tests are playback or
 * record. By default, tests are run in playback mode.
 */
public static class ClientTests extends TestProxyTestBase {

    /**
     * Use JUnit annotation here for your testcase
     */
    public void testMethodName() {
        HttpPipelineBuilder pipelineBuilder = new HttpPipelineBuilder();
        if (interceptorManager.isRecordMode()) {
            // Add a policy to record network calls.
            pipelineBuilder.policies(interceptorManager.getRecordPolicy());
        }
        if (interceptorManager.isPlaybackMode()) {
            // Use a playback client when running in playback mode
            pipelineBuilder.httpClient(interceptorManager.getPlaybackClient());
        }

        Mono<HttpResponse> response =
            pipelineBuilder.build().send(new HttpRequest(HttpMethod.GET, "http://bing.com"));

        // Validate test results.
        assertEquals(200, response.block().getStatusCode());
    }

配置实时或播放测试模式

“实时”测试是指对实际 Azure 资源发出请求的测试。 “播放”测试需要记录每个测试;测试代理会将每次测试期间发出的请求/响应与记录中的请求/响应进行比较。

若要运行实时测试,请将环境变量 AZURE_TEST_MODE 设置为 LIVE。 若要在播放中运行测试,请将 PLAYBACK 设置为 AZURE_TEST_MODE 或使其保持未设置状态。

运行和记录测试

将环境变量 AZURE_TEST_MODE 设置为 以 RECORD 在记录模式下运行测试 () 。

测试完成运行后,包目录中应有一个名为 src/test/resources/session-records 的文件夹。 此文件夹中的每个录制都将是一个 .json 文件,用于捕获在运行与文件名匹配的测试时生成的 HTTP 流量。 如果将环境变量设置为 AZURE_TEST_MODE “PLAYBACK”并重新运行测试,则它们应再次通过 -- 这次,在播放模式下 (即不使用实际 HTTP 请求,使用 json 记录文件中) 记录的数据。

使用存储库外录制运行测试

如果正在测试的包将其录制内容存储在存储库外部azure-sdk-for-java(即已遵循录制迁移指南,并且包包含文件assets.json)则目录中不会有文件夹src/test/resources/session-recordstests。 相反,包的文件 assets.json 将指向存储库中 azure-sdk-assets 包含录制内容的标记。 这是首选的录制配置。

在此配置中,运行实时或播放测试与上一部分相同。 唯一的更改是更新录制的过程。

更新测试记录

先决条件

  • 目标库已迁移为使用测试代理。
  • Git 版本 > 2.30.0 在计算机上和路径中为 。 Git 由脚本和测试代理使用。
  • user.nameuser.email配置了全局 git 配置设置
    • 这些设置还分别使用环境变量 GIT_COMMIT_OWNERGIT_COMMIT_EMAIL设置, (环境或本地 .env 文件) 。
  • GitHub 组中的成员 azure-sdk-write 身份。

如果运行测试并将环境变量 AZURE_TEST_MODE 设置为 RECORD,则会更新测试记录。 但是,由于录制内容本身不再位于存储库中 azure-sdk-for-java ,因此这些更新将反映在存储库根目录的 git 排除 .assets 文件夹中。

.assets 文件夹包含一个或多个具有随机名称的目录,每个目录都是包含录制内容的 git 目录。 如果 cd 进入包含包录制内容的文件夹,则可以使用 git status 查看所做的录制更新。 还可以使用其他 git 命令;例如, git diff {file name} 查看特定文件更改,或 git restore {file name} 撤消不想保留的更改。

若要查找包含包录制内容的目录,请在 .breadcrumb 文件夹中打开 文件 .assets 。 此文件在每行中列出一个包名称,后跟记录目录名称;例如:

sdk/{service}/{package}/assets.json;2Wm2Z87545;java/{service}/{package}_<10-character-commit-SHA>

在本例中,录制目录是 2Wm2Z8745,两个分号之间的字符串。

验证录制更新看起来正确后,可以使用 test-proxy push -a assets.json 命令将这些录制内容推送到 azure-sdk-assets 存储库。 应为此命令提供包assets.json文件的相对路径。 例如,从存储库的根目录 azure-sdk-for-java

test-proxy push -a sdk/{service}/{package}/assets.json

可提供给此脚本的谓词为“push”、“restore”和“reset”:

  • push:将记录更新推送到新的资产存储库标记,并更新 中的 assets.json标记指针。
  • 还原:根据 中的标记指针从资产存储库提取 assets.json录制内容。
  • reset:根据 中的 assets.json标记指针放弃对录制的任何挂起更改。

推送录制内容后, assets.json 包的文件将更新为指向包含更新的新 Tag 文件。 将此更新assets.json包含在任何拉取请求中,以更新上游存储库中的录制指针。

清理机密

.json 记录模式下运行测试创建的文件可以包括授权详细信息、帐户名称、共享访问签名和其他机密。 录制内容包含在公共 GitHub 存储库中,因此,在将这些记录提交到存储库之前,从这些录制内容中删除任何机密非常重要。

可通过两种主要方法防止机密写入录制内容:

  1. 默认清理器(类似于使用 RecordingRedactor)已在 TestProxyUtils 中注册,用于默认修订。
  2. 可以使用 test_proxy_sanitizer&interceptorManager.addSanitizers() 方法添加[TestProxySanitizer]自定义清理器,以满足特定的服务清理需求。 例如,注册自定义清理器以从响应正文中修订 json key modelId 的值如下所示:
    
    List<TestProxySanitizer> customSanitizer = new ArrayList<>();
    // sanitize value for key: "modelId" in response json body
    customSanitizer.add(
        new TestProxySanitizer("$..modelId", "REPLACEMENT_TEXT", TestProxySanitizerType.BODY_KEY));
    
    if (interceptorManager.isRecordMode()) {
        // Add a policy to record network calls.
        pipelineBuilder.policies(interceptorManager.getRecordPolicy());
    }
    if (interceptorManager.isPlaybackMode()) {
        // Use a playback client when running in playback mode
        pipelineBuilder.httpClient(interceptorManager.getPlaybackClient());
        // Add matchers only in playback mode
        interceptorManager.addMatchers(Arrays.asList(new CustomMatcher()
            .setHeadersKeyOnlyMatch(Arrays.asList("x-ms-client-request-id"))));
    }
    if (!interceptorManager.isLiveMode()) {
        // Add sanitizers when running in playback or record mode
        interceptorManager.addSanitizers(customSanitizer);
    }
    

注意:只有在注册播放客户端或记录策略后,才能添加清理器。 例如,请查看 TableClientTestBase 类。

有关测试代理支持的清理器的详细信息,可 在此处找到。

自定义记录的内容

某些测试发送的大型请求正文没有意义,不应存储在会话记录中。 若要禁用存储特定请求的请求正文,请将 RecordWithoutRequestBody 批注添加到测试方法。

示例

故障排除

如果这些 SDK 遇到任何 bug,请通过 “问题” 提交问题,或查看 适用于 Azure Java SDK 的 StackOverflow

后续步骤

其他有用的包包括:

  • azure-core:包含所有客户端库使用的核心类和功能。

贡献

有关参与此存储库的详细信息,请参阅 [参与指南][cg]。

本项目欢迎贡献和建议。 大多数贡献要求你同意贡献者许可协议 (CLA),并声明你有权(并且确实有权)授予我们使用你的贡献的权利。 有关详细信息,请访问 https://cla.microsoft.com

提交拉取请求时,CLA 机器人将自动确定你是否需要提供 CLA,并相应地修饰 PR(例如标签、注释)。 直接按机器人提供的说明操作。 只需使用 CLA 在所有存储库中执行此操作一次。

此项目已采用 [Microsoft 开源行为准则][coc]。 有关详细信息,请参阅 [行为准则常见问题解答][coc_faq] 或联系 opencode@microsoft.com 任何其他问题或意见。

曝光数