首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RubberDuck能否测试程序是否结束?

RubberDuck能否测试程序是否结束?
EN

Stack Overflow用户
提问于 2018-12-25 22:55:29
回答 1查看 164关注 0票数 4

我正在用RubberDuck开发测试,并希望测试程序中的MsgBox输出。问题是,程序在输出MsgBox之后就结束了--实际上有一个"End“语句。

当运行RubberDuck测试并使用Fakes.MsgBox.Returns时,有一个非决定性的黄色结果,即消息“运行测试时意外的COM异常”

我试着在测试的末尾放置一个"Assert.Fail“;但是,程序的结尾似乎会抛出一些东西。

RubberDuck中的测试是否有可能检测程序是否结束?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-26 00:04:46

tldr;否

Rubber鸭单元测试是在VBA运行时的上下文中执行的,也就是说,VBA单元测试代码是从主机应用程序内部运行的。通过API将测试结果报告给Rubber鸭子。如果您查看插入测试模块时生成的VBA代码,它将给出测试运行方式的基本概念。例如,我们的集成测试套件中的这个单元测试:

代码语言:javascript
复制
'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

分解:

这将创建一个托管类,用于“侦听”正在测试的代码中的断言,并评估通过或失败测试的条件。

代码语言:javascript
复制
Private Assert As New Rubberduck.AssertClass     

FakesProvider是一个实用程序对象,用于将VB运行时中的钩子设置为“忽略”或“欺骗”VB运行时内部对InputBox函数的调用。

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

代码语言:javascript
复制
    With Fakes.InputBox

返回和ReturnsWhen调用使用VBA对象将假调用的测试设置与InputBox通信。在本例中,它将InputBox对象配置为返回调用1的vbNullString,在传递调用2的"Second"Prompt参数时返回“用户条目2”。

代码语言:javascript
复制
        .Returns vbNullString, 1
        .ReturnsWhen "Prompt", "Second", "User entry 2", 2

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

代码语言:javascript
复制
        Assert.IsTrue userInput = vbNullString

就你的问题而言,这意味着什么:

注意,在上面的代码执行方式的细分中,所有内容都是在VBA环境中执行的。Rubber鸭为VBA提供了一个“窗口”,通过AssertClass对象报告结果,并通过FakesProvider对象提供钩子服务(对于“简单”的一些值)。VBA“拥有”这两个对象--它们只是通过Rubber鸭的COM提供者提供的。

当您在VBA中使用End语句时,它强制终止在这一点上的执行。Rubber鸭COM对象不再由客户端主动引用(您的测试过程),并且它没有定义是否会减少COM对象上的引用计数。就像拔掉墙上的插头一样。Rubber鸭在这一点上唯一能确定的是COM客户端已经断开连接。在您的例子中,它表现为一个在Rubber鸭子中捕获的COM异常。由于Rubber鸭无法知道它所提供的对象为什么失去了通信,所以它将测试结果报告为“不确定”--它没有完成测试。

尽管如此,解决方案是重构代码以避免使用End。永远不会。引用上面链接的文档End..。

立即终止执行。它本身从来不需要,但可以放置在一个过程中的任何地方,以结束代码执行、关闭使用Open语句打开的文件和清除变量。

这一点远远不够优雅,而且如果您有对其他COM对象(除了Rubber鸭子)的引用,就无法保证它们将可靠地终止。

完全公开后,我为Rubber鸭子项目贡献了部分代码,并编写了上述代码。如果您想更好地了解单元测试功能(并且可以读取c#),COM提供者可以在此链接上找到的实现。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53926116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档