vstest 中作为环境变量的秘密

Ada*_*rek 3 vstest azure-devops

在我的测试中,我使用环境变量。由于安全原因,在 azure devops 管道中设置它时,我需要将其标记为秘密。是否可以在 vstest 任务中将其作为参数传递?

Mor*_*tan 6

显然缺乏足够的声誉来评论 @daniel-mann 的答案,我需要自己跟进答案。

关于运行设置文件的使用;

是的,我确信你可以这样做,但还有一种更简单的方法。在任务定义中,您可以选择覆盖测试运行参数。

对于非 YAML 管道,您可以在“覆盖测试运行参数”选项中执行此操作(工具提示显示“覆盖在运行设置文件的 TestRunParameters 部分或测试设置文件的属性部分中定义的参数。例如:-key1 value1 -key2 value2 . ”),这样就可以了:

-SomeSecret $(SomeSecret)
Run Code Online (Sandbox Code Playgroud)

对于 YAML 管道,您可以执行以下操作:

overrideTestrunParameters: '-SomeSecret $(SomeSecret)'
Run Code Online (Sandbox Code Playgroud)

好处是您想要覆盖的测试运行参数不需要存在于您的运行设置文件中。事实上,甚至根本不需要运行设置文件!

一般来说,这种方法的坏处是,您必须通过“ TestContext.Properties”集合(对于 NUnit)访问您的秘密,如果您想要一个对于本地开发同样有效的透明解决方案(使用“用户秘密”),这真的很糟糕。 ") 和 Azure 管道中。

另一个潜在的坏处是这些“覆盖”测试运行参数只是该测试运行的参数。如果您碰巧混合了 .NET Framework 和 .NET Core 测试,您可能希望在两个不同的测试运行中执行这些测试(为了使其能够正常工作...),然后您需要复制这些覆盖(假设需要一些相同的秘密)。

关于在管道中添加附加任务以设置适当的环境变量;

绝对地。使用“批处理脚本”任务非常适合于此,您只需将基于秘密的变量作为参数传递给脚本,然后在脚本文件中选取它们即可。

不过,为了使其按预期工作,您需要允许任务修改环境。

对于非 YAML 管道,这是通过勾选“修改环境”复选框来完成的。

对于 YAML 管道,您可以这样做:

- task: BatchScript@1
  displayName: 'Export key vault vars as env. vars (for tests)'
  inputs:
    filename: 'ExportKeyVaultEnvironmentVariables.cmd'
    arguments: '$(SomeSecret)'
    modifyEnvironment: true
Run Code Online (Sandbox Code Playgroud)

在“ExportKeyVaultEnvironmentVariables.cmd”脚本中,您只需执行以下操作:

set SomeSecret=%1
Run Code Online (Sandbox Code Playgroud)

注意:如果您的秘密偶然有一些有趣的字符,尤其是尾随“=”字符,您可能会遇到在脚本内收集参数时得到的不是您发送的内容。

您可以通过将参数括在双引号中来避免此问题,如下所示:

arguments: '"$(SomeSecret)"'
Run Code Online (Sandbox Code Playgroud)

然后使用“~”参数修饰符删除周围的引号来收集参数,如下所示:

set SomeSecret=%~1
Run Code Online (Sandbox Code Playgroud)

这种方法的一个很好的额外效果是,闪亮的新的成熟环境变量在管道的其余部分中持续存在。回顾一下我的“坏事”,即必须可能重复测试运行参数覆盖,这里不需要这样做。

关于OP提到的附加选项;

当然,在这种情况下,您不需要“批处理脚本”任务(需要调用脚本文件),而只需要“命令行”任务。

但是,请注意可能存在的问题!是的,如果您通过“”访问它,这将为您的测试代码创建一个环境变量以供选择Environment.GetEnvironmentVariable

就我而言,我正在构建一个“ IConfigurationRoot”实例,如下所示:

/// <summary>
/// Gets a configuration instance, based on user secrets (for local test execution) and environment variables (for Azure pipeline execution).
/// </summary>
/// <typeparam name="T">The type of the class that represents the "runtime" (and thus is able to get hold of any configuration).</typeparam>
/// <returns>An <see cref="IConfigurationRoot"/> instance.</returns>
public static IConfigurationRoot GetConfigurationRoot<T>()
    where T : class =>
    new ConfigurationBuilder()
        //// Note: The "AddUserSecrets" method requires the "Microsoft.Extensions.Configuration.UserSecrets" package
        .AddUserSecrets<T>()
        //// Note: The "AddEnvironmentVariables" method requires the "Microsoft.Extensions.Configuration.EnvironmentVariables" package
        .AddEnvironmentVariables()
        .Build();
Run Code Online (Sandbox Code Playgroud)

这是通过添加各种“配置提供程序”来实现的,最终允许您通过“配置提供程序”无缝地访问它们configuration["SomeSecret"]

不过,我发现,如果我没有严重错误的话,“SomeSecret”在添加的“”中仍然不可用EnvironmentVariablesConfigurationProvider,即使我可以使用上述方法直接完美地访问它。想想看(但我可能是错的......)。

可能的替代方法(但仅适用于 YAML 管道?);

似乎对于 YAML 管道,您可以为任务显式设置环境变量,如下所示:

- task: VSTest@2
  env:
    SomeSecret: $(SomeSecret)
[...]
Run Code Online (Sandbox Code Playgroud)

我自己没有测试过,但看到一位同事这样做(我自己,目前没有 YAML 管道)。至少这个变量可以用“ Environment.GetEnvironmentVariable”来获取,但我不知道是否可以通过“”实例来获取IConfigurationRoot

我还没有看到任何选项可以在非 YAML 管道中实现相同的目标。

但同样,这也可能遇到同样的“必须在多次测试运行中复制环境变量”的问题。

另请参阅我在Azure DevOps 人员中对我自己的问题的解决方案