Pester数据驱动测试如何在-ForEach中使用BeforeAll定义的变量
Pester测试中BeforeAll变量无法传入It块-ForEach参数的解决方案
问题原因
Pester 5+的执行分为两个阶段:
- 发现阶段:遍历测试文件解析所有测试块参数,包括
It的-ForEach测试用例集,此时BeforeAll/BeforeEach等执行阶段的块还未运行,内部定义的变量尚未初始化,因此直接在-ForEach中引用会返回$null。 - 执行阶段:按顺序执行
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
相关产品推荐
相关产品推荐

