1

我将 Pester 与 Selenium WebDriver 一起使用。WebDriver 在相应的“Describe”块内的“BeforeAll”块中初始化,并将生成的实例分配给 $driver 变量。然后,在“描述”和“它”块中,我调用驻留在外部 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 获取元素并提取元素的内部文本。

我调查了这个问题并找到了解决方法,但我认为这不是一个优雅的方法。解决方法是在外部 PowerShell 模块中的每个辅助函数中重新定义 $driver,就在 param 块之后,如下所示:

$driver = $PSCmdlet.GetVariableValue('driver')

这样,函数可以看到 $driver 并且一切正常。

我的问题:是否有可能做某事,所以函数总是可以访问 $driver 而无需在每个函数中重新定义驱动程序?

4

1 回答 1

2

“我希望这些函数 [在 PowerShell 模块中定义] 可以访问在 'BeforeAll' 块中定义的 $driver 变量......”

他们没有,即使他们这样做了,您也可能不应该依赖这种行为。

无法从模块访问 Pester 脚本块中定义的变量

当文件被( referenceBeforeAll{} ) 调用时,在、BeforeEach{}Context{}It{}块中定义的变量不能从被测模块访问。如果文件恰好被直接调用(即通过按下ISE),则可以从被测模块访问定义的变量。依赖这种行为会阻止测试以更大的批次运行,因此应该避免。x.Tests.ps1Invoke-Pesterx.Tests.ps1F5BeforeAll{}

应避免依赖外部变量的隐式可访问性

似乎您的自定义模块期望$driver在模块外部的某个地方定义,并且可以从模块内部隐式访问。这就提出了以下问题:自定义模块的作者打算在哪里$driver定义?作为模块中的脚本变量?作为全局变量?对于模块来说,这两个都是非常尴尬的公共接口,因为很难控制正确的值$driver是否确实可用于模块。如果模块确实依赖于这种行为,我建议更改自定义模块以明确接受您的$driver对象(或至少创建该对象所需的信息)。

如果您无法更改自定义模块,则可以通过将变量引用从更改$driver$global:driver. 不过,您确实应该尽量避免这种情况,因为以这种方式使用全局变量可能会在某些时候导致各种问题。

于 2016-09-05T17:31:01.660 回答