将类放独立文件的PowerShell模块在GitHub Actions中Pester测试失败
我正在开发一个包含自定义类的PowerShell模块。当把类直接定义在psm1文件中时,所有测试都正常通过;但将类移到独立文件并通过using module .\PathTo\MyClass.ps1引入后,GitHub Actions中的Pester测试报错:Unable to find type [MyClass]。
本地新建PowerShell会话运行Invoke-Pester测试完全正常,仅在GitHub Actions环境下失败。本地环境为PowerShell v7.3.6、Pester v5.5.0,GitHub Actions使用PowerShell v7.2.13、Pester v5.5.0。
根据PowerShell官方文档,using module仅从根模块(即psm1文件本身)导入类,嵌套模块或点源脚本中的类导入行为不一致。我希望按规范将多个类分文件存放,寻求解决该问题的方案。
场景1:类直接定义在psm1中(全环境正常)
ModuleWithClassInPsm1.psm1
class MyClassInPsm1 { [string] $Name } function Get-MyClassInPsm1 { return [MyClassInPsm1]::new() } Export-ModuleMember -Function Get-MyClassInPsm1
ModuleWithClassInPsm1.Tests.ps1
using module .\ModuleWithClassInPsm1.psm1 Describe 'Module' { It 'Should return a new class instance without error' { $instance = Get-MyClassInPsm1 $instance | Should -Not -Be $null } }
场景2:类在独立文件中(GitHub Actions中失败)
Classes\MyClassInSeparateFile.ps1
class MyClassInSeparateFile { [string] $Name }
ModuleWithClassInSeparateFile.psm1
using module .\Classes\MyClassInSeparateFile.ps1 function Get-MyClassInSeparateFile { return [MyClassInSeparateFile]::new() } Export-ModuleMember -Function Get-MyClassInSeparateFile
ModuleWithClassInSeparateFile.Tests.ps1
using module .\ModuleWithClassInSeparateFile.psm1 Describe 'Module' { It 'Should return a new class instance without error' { $instance = Get-MyClassInSeparateFile $instance | Should -Not -Be $null } }
解决建议
方案1:用点源替代using module导入类文件
在psm1文件中通过点源方式引入类文件,确保类被加载到模块作用域内:
. .\Classes\MyClassInSeparateFile.ps1 function Get-MyClassInSeparateFile { return [MyClassInSeparateFile]::new() } Export-ModuleMember -Function Get-MyClassInSeparateFile
方案2:将类文件配置为嵌套模块
在模块的psd1配置文件中,通过NestedModules属性指定类文件路径,让PowerShell自动加载这些嵌套模块,保证类在模块初始化时被正确导入:
@{ RootModule = 'ModuleWithClassInSeparateFile.psm1' NestedModules = @('.\Classes\MyClassInSeparateFile.ps1') # 其他模块属性(如ModuleVersion、Author等) }
方案3:升级GitHub Actions中的PowerShell版本
测试失败可能与PowerShell 7.2.x的using module行为兼容性有关,将CI环境的PowerShell版本升级到与本地一致的7.3.x,可在GitHub Actions workflow中配置:
steps: - name: Setup PowerShell uses: actions/setup-powershell@v2 with: pwsh-version: '7.3.6'
方案4:测试脚本中额外引入类文件(临时 workaround)
如果上述方案暂无法实施,可在测试脚本中直接引入类文件,但会增加测试与类文件路径的耦合性:
using module .\ModuleWithClassInSeparateFile.psm1 using module .\Classes\MyClassInSeparateFile.ps1 Describe 'Module' { It 'Should return a new class instance without error' { $instance = Get-MyClassInSeparateFile $instance | Should -Not -Be $null } }
内容的提问来源于stack exchange,提问作者deadlydog

