You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pester数据驱动测试如何在-ForEach中使用BeforeAll定义的变量

Pester测试中BeforeAll变量无法传入It块-ForEach参数的解决方案

问题原因

Pester 5+的执行分为两个阶段:

  1. 发现阶段:遍历测试文件解析所有测试块参数,包括It的-ForEach测试用例集,此时BeforeAll/BeforeEach等执行阶段的块还未运行,内部定义的变量尚未初始化,因此直接在-ForEach中引用会返回$null。
  2. 执行阶段:按顺序执行BeforeAll、测试用例、AfterAll等逻辑,此时BeforeAll定义的变量才会生效。

解决方案1:使用BeforeDiscovery块(最推荐)

BeforeDiscovery是Pester专门为测试数据预定义设计的块,会在发现阶段执行,内部定义的变量既可以被-ForEach正常读取,也可以在后续执行阶段的块中访问,完全符合Pester编码规范。
示例代码如下:

BeforeDiscovery {
    # 所有需要在-ForEach中使用的测试数据统一放在这里定义
    $PORead = @{
        Name = "Paul"
        Permission ="Read"
        Inheritance = "ThisFolderSubfoldersAndFiles"
    }
    $PODelete = @{
        Name = "Paul"
        Permission ="Delete"
        Inheritance = "ThisFolderOnly"
    }
    $POReadExp = "add parameters"
    $PODeleteExp = "delete parameters"

    # 也可以直接预生成测试用例集
    $testCases = @(
        @{FunctionParam=$PORead;Expected=$POReadExp}
        @{FunctionParam=$PORead,$PORead;Expected=$POReadExp,$POReadExp}
        @{FunctionParam=$PORead,$PODelete,$PORead,$PORead;Expected=$POReadExp,$POReadExp,$POReadExp,$PODeleteExp}
    )
}

BeforeAll {
    # 此处放测试执行前的初始化逻辑,比如导入模块、初始化环境等
    # BeforeDiscovery中定义的变量在这里也可以正常访问
}

It "Test if all combinations works" -ForEach $testCases {
    $result = Function-Call -Param $FunctionParam
    $wanted = $Expected -join(" ")
    $result | Should -Be $wanted
}

解决方案2:标识映射方案(适合测试数据需要动态生成的场景)

如果你的测试数据依赖BeforeAll中的动态初始化结果(比如需要调用模块接口返回值作为测试参数),可以在-ForEach中仅传静态字符串标识,在It块执行时再从BeforeAll定义的索引表中读取实际值:

BeforeAll {
    # 把所有测试参数和预期值统一存入索引哈希表
    $testDataIndex = @{
        PORead = @{
            Param = @{
                Name = "Paul"
                Permission ="Read"
                Inheritance = "ThisFolderSubfoldersAndFiles"
            }
            Expected = "add parameters"
        }
        PODelete = @{
            Param = @{
                Name = "Paul"
                Permission ="Delete"
                Inheritance = "ThisFolderOnly"
            }
            Expected = "delete parameters"
        }
    }
}

# -ForEach中仅传入可静态解析的字符串标识
It "Test if all combinations works" -ForEach(
    @{ParamIds = @("PORead"); ExpectedIds = @("PORead")}
    @{ParamIds = @("PORead","PORead"); ExpectedIds = @("PORead","PORead")}
    @{ParamIds = @("PORead","PODelete","PORead","PORead"); ExpectedIds = @("PORead","PORead","PORead","PODelete")}
) {
    # 执行阶段再从索引表中取出实际的参数和预期值
    $FunctionParam = $ParamIds | ForEach-Object { $testDataIndex[$_].Param }
    $Expected = $ExpectedIds | ForEach-Object { $testDataIndex[$_].Expected }
    
    $result = Function-Call -Param $FunctionParam
    $wanted = $Expected -join(" ")
    $result | Should -Be $wanted
}

内容的提问来源于stack exchange,提问作者Usul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 17:15:07