我将Pester与Selenium WebDriver一起使用。 WebDriver初始化为&BeforeAll'阻止相应的'描述'阻止并将结果实例分配给$ driver变量。然后,在' Describe'和'它'块我调用驻留在PowerShell自动加载的外部PowerShell模块中的自定义函数。我希望这些函数可以访问在&BeforeAll'之前定义的$ driver变量。阻止,但它没有发生,我收到以下错误信息:
RuntimeException:您无法在空值表达式上调用方法。
以下是Search.Tests.ps1 Pester脚本的代码:
Describe "Search for something" -Tag something {
BeforeAll {
$driver = New-WebDriver
$driver.Navigate().GoToUrl('http://example.com')
}
AfterAll {
$driver.Close()
$driver.Dispose()
$driver.Quit()
}
Find-WebElement -Selector ('some_selector')
It "Something is found in search results" {
GetTextFrom-WebElement -Selector ('some_selector') | Should Be 'something'
}
}
Find-WebElement和GetTextFrom-WebElement是辅助函数,它们使用$ driver通过CSS获取元素并提取元素的内部文本。
我调查了这个问题并找到了解决方法,但我认为这不是一个优雅的方法。解决方法是在param块之后立即重新定义外部PowerShell模块中每个帮助器函数中的$ driver:
$driver = $PSCmdlet.GetVariableValue('driver')
这样功能可以看到$ driver,一切正常。
我的问题:是否可以执行某些操作,因此函数始终可以访问$ driver而无需在每个驱动程序中重新定义驱动程序?
答案 0 :(得分:2)
“我希望这些函数[在PowerShell模块中定义]可以访问'BeforeAll'块中定义的$ driver变量...”
他们没有,你可能不应该依赖这种行为,即使他们这样做了。
BeforeAll{}
,BeforeEach{}
,Context{}
和It{}
块中定义的变量 1}}文件由x.Tests.ps1
(reference)调用。如果恰好直接调用Invoke-Pester
文件(即通过在ISE中按 F5 ),则可以从被测模块访问x.Tests.ps1
中定义的变量。依靠这种行为可以排除测试大批量运行,因此应该避免。
似乎您的自定义模块期望BeforeAll{}
在模块外部的某处定义,并且可以从模块内部隐式访问。这提出了以下问题:自定义模块的作者在哪里定义$driver
?作为模块中的脚本变量?作为全球变量?这两个都是模块的相当笨拙的公共接口,因为很难控制$driver
的正确值是否确实可用于模块。如果模块确实依赖于此类行为,我建议更改自定义模块以明确接受您的$driver
对象
(或至少创建该对象所需的信息)。
如果您无法更改自定义模块,则可以将变量引用从$driver
更改为$driver
。你应该尽量避免这种情况,因为以这种方式使用全局变量可能会在某些时候导致任何各种问题。