gpt4 book ai didi

vba - 如果程序结束,RubberDuck 可以测试吗?

转载 作者:行者123 更新时间:2023-12-03 03:52:39 29 4
gpt4 key购买 nike

我正在使用 RubberDuck 开发测试,并想测试程序的 MsgBox 输出。问题是程序在输出 MsgBox 后立即结束——字面上有一个“结束”语句。

运行 RubberDuck 测试并使用 Fakes.MsgBox.Returns 时,会出现不确定的黄色结果,并显示消息“运行测试时出现意外的 COM 异常”

我尝试在测试结束时放置“Assert.Fail”;然而,节目的结尾似乎把事情搞砸了。

是否可以在 RubberDuck 中进行测试以检测程序是否结束?

最佳答案

tldr;不

Rubberduck 单元测试在 VBA 运行时的上下文中执行——也就是说,VBA 单元测试代码是从宿主应用程序内部运行的。测试结果通过其 API 报告回 Rubberduck。如果您查看插入测试模块时生成的 VBA 代码,它会基本了解测试运行的体系结构。以我们的集成测试套件中的这个单元测试为例:

'HERE BE DRAGONS.  Save your work in ALL open windows.
'@TestModule
'@Folder("Tests")

Private Assert As New Rubberduck.AssertClass
Private Fakes As New Rubberduck.FakesProvider

'@TestMethod
Public Sub InputBoxFakeWorks()
On Error GoTo TestFail

Dim userInput As String
With Fakes.InputBox
.Returns vbNullString, 1
.ReturnsWhen "Prompt", "Second", "User entry 2", 2
userInput = InputBox("First")
Assert.IsTrue userInput = vbNullString
userInput = InputBox("Second")
Assert.IsTrue userInput = "User entry 2"
End With

TestExit:
Exit Sub
TestFail:
Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
End Sub

分解:

这将创建一个托管类,该类“监听”正在测试的代码中的断言,并评估通过或失败测试的条件。
Private Assert As New Rubberduck.AssertClass     
FakesProvider是一个实用对象,用于将 VB 运行时中的 Hook 设置为“忽略”或“欺骗”来自 VB 运行时内部的调用,例如 InputBox。功能。

由于 Fakes对象被声明 As New , With block 实例化一个 FakesProvider为测试。 InputBox Fakes的方法这在 rtcInputBox 上设置了一个钩子(Hook)。 vbe7.dll 中的函数,它将所有流量从 VBA 重定向到该函数到 Rubberduck 实现。这现在正在计算调用、跟踪传递的参数、提供返回值等。
    With Fakes.InputBox

Returns 和 ReturnsWhen 调用使用 VBA 保存的 COM 对象将伪造调用的测试设置传达给 InputBox。 .在本例中,它配置了 InputBox返回 vbNullString 的对象用于调用一,当传递 Prompt 时为“用户条目 2” "Second"的参数电话号码二。
        .Returns vbNullString, 1
.ReturnsWhen "Prompt", "Second", "User entry 2", 2

这就是 AssertClass 的用武之地。当您从 Rubberduck UI 运行单元测试时,它会确定用户代码的 COM 接口(interface)。然后,它通过该接口(interface)调用调用测试方法。然后 Rubberduck 使用 AssertClass测试运行时条件。 IsTrue方法采用 Boolean作为参数(带有可选的输出消息)。因此,在下面的代码行中,VB 计算表达式 userInput = vbNullString并将结果作为参数传递给 IsTrue .橡皮鸭 IsTrue然后实现根据从 VBA 传递的参数是否满足 AssertClass 的条件来设置单元测试的状态。方法调用。
        Assert.IsTrue userInput = vbNullString

这对您的问题意味着什么:

请注意,在上述代码如何执行的分割中, 一切都在 VBA 环境中执行 . Rubberduck 正在为 VBA 提供一个“窗口”,通过 AssertClass 报告结果。对象,并且简单地(对于“简单”的某些值)通过 FakesProvider 提供 Hook 服务目的。 VBA“拥有”这两个对象——它们只是通过 Rubberduck 的 COM 提供程序提供的。

当您使用 End VBA 中的语句,它会在该点强制终止执行。 Rubberduck COM 对象不再被客户端(您的测试过程)主动引用,并且不确定是否会减少 COM 对象上的引用计数。这就像从墙上拔出插头一样。 Rubberduck 在这一点上唯一可以确定的是 COM 客户端已断开连接。在您的情况下,这表现为在 Rubberduck 中捕获的 COM 异常。由于 Rubberduck 无法知道它提供的对象为何失去通信,因此它将测试结果报告为“不确定”——它没有运行完成。

也就是说,解决方案是重构您的代码以不使用 End .曾经。引用上面链接的文档 End ...

Terminates execution immediately. Never required by itself but may be placed anywhere in a procedure to end code execution, close files opened with the Open statement, and to clear variables.



这远非优雅,如果您引用了其他 COM 对象(除了 Rubberduck),则无法保证它们会可靠地终止。

全面披露,我为 Rubberduck 项目做出了贡献,并编写了一些上述代码。如果您想更好地了解单元测试的功能(并且可以阅读 c#),COM 提供程序的实现 can be found at this link .

关于vba - 如果程序结束,RubberDuck 可以测试吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53926116/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com