首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >测试MS Access应用程序的最佳方式?

测试MS Access应用程序的最佳方式?
EN

Stack Overflow用户
提问于 2008-09-06 11:58:30
回答 12查看 19.7K关注 0票数 45

由于代码、表单和数据都在同一个数据库中,我想知道为Microsoft Access应用程序(比如Access 2007)设计一套测试的最佳实践是什么。

测试窗体的主要问题之一是,只有少数控件具有hwnd句柄,而其他控件只有一个拥有焦点的控件,这使得自动化非常不透明,因为您无法获得窗体上可操作的控件列表。

有什么经验可以分享吗?

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2015-02-05 22:50:44

1.编写可测试代码

首先,停止在表单的代码中编写业务逻辑。那不是适合它的地方。它不能在那里进行适当的测试。事实上,你根本不应该测试你的表单本身。它应该是一个非常愚蠢的简单视图,它响应用户交互,然后将响应这些操作的责任委托给另一个类,即可测试的。

你怎么做到的?熟悉Model-View-Controller pattern是一个很好的开始。

它不能在VBA中完美地完成,因为我们要么得到事件,要么得到接口,而不是两者都得到,但你可以非常接近。考虑这个简单的表单,它有一个文本框和一个按钮。

在窗体后面的代码中,我们将TextBox的值包装在一个公共属性中,并重新引发我们感兴趣的任何事件。

代码语言:javascript
复制
Public Event OnSayHello()
Public Event AfterTextUpdate()

Public Property Let Text(value As String)
    Me.TextBox1.value = value
End Property

Public Property Get Text() As String
    Text = Me.TextBox1.value
End Property

Private Sub SayHello_Click()
    RaiseEvent OnSayHello
End Sub

Private Sub TextBox1_AfterUpdate()
    RaiseEvent AfterTextUpdate
End Sub

现在我们需要一个模型来工作。在这里,我创建了一个名为MyModel的新类模块。这是我们将要测试的代码。请注意,它自然与我们的视图具有相似的结构。

代码语言:javascript
复制
Private mText As String
Public Property Let Text(value As String)
    mText = value
End Property

Public Property Get Text() As String
    Text = mText
End Property

Public Function Reversed() As String
    Dim result As String
    Dim length As Long

    length = Len(mText)

    Dim i As Long
    For i = 0 To length - 1
        result = result + Mid(mText, (length - i), 1)
    Next i

    Reversed = result
End Function

Public Sub SayHello()
    MsgBox Reversed()
End Sub

最后,我们的控制器将它们连接在一起。控制器侦听表单事件,传达对模型的更改,并触发模型的例程。

代码语言:javascript
复制
Private WithEvents view As Form_Form1
Private model As MyModel

Public Sub Run()
    Set model = New MyModel
    Set view = New Form_Form1
    view.Visible = True
End Sub

Private Sub view_AfterTextUpdate()
    model.Text = view.Text
End Sub

Private Sub view_OnSayHello()
    model.SayHello
    view.Text = model.Reversed()
End Sub

现在,这段代码可以从任何其他模块运行。出于本例的目的,我使用了一个标准模块。我强烈建议您使用我提供的代码自己构建它,看看它是如何工作的。

代码语言:javascript
复制
Private controller As FormController

Public Sub Run()
    Set controller = New FormController
    controller.Run
End Sub

所以,这很棒,而且都是,但是这和测试有什么关系呢?!朋友,它有来做测试。我们所做的就是让我们的代码可测试。在我提供的示例中,根本没有理由尝试测试GUI。我们唯一真正需要测试的就是model。这就是所有真正的逻辑所在。

因此,进入第二步。

2.选择单元测试框架

这里没有太多的选择。大多数框架都需要安装COM插件、大量模板、奇怪的语法、编写测试作为注释等等。这就是我参与building one myself的原因,所以我的这部分回答并不公正,但我会尝试对可用的内容给出一个公平的总结。

  1. AccUnit

代码语言:javascript
复制
- Works only in Access.
- Requires you to write tests as a strange hybrid of comments and code. (no intellisense for the comment part.
- There _**is**_ a graphical interface to help you write those strange looking tests though.
- The project has not seen any updates since 2013.

  1. VB Lite Unit我不能说我个人用过它。它是存在的,但自从2005.
  2. xlUnit xlUnit不是很糟糕以来就没有看到更新,但它也不是很好。它很笨拙,而且有很多样板代码。它是最好的,但它在Access中不起作用。
  3. 构建您自己的框架

我已经been there and done that了。它可能比大多数人想要的要多,但是在Native VBA code.

免责声明:我是联合开发者之一。

我有偏见,但到目前为止,这是我最喜欢的。

代码语言:javascript
复制
- Little to no boiler plate code.
- Intellisense is available.
- The project is active.
- More documentation than most of these projects.
- It works in most of the major office applications, not just Access.
- It is, unfortunately, a COM Add-In, so it has to be installed onto your machine.

3.开始编写测试

因此,回到第1节的代码。我们真正需要测试的唯一代码是MyModel.Reversed()函数。那么,让我们来看看这个测试是什么样子的。(给出的示例使用Rubberduck,但这是一个简单的测试,可以转换为您选择的框架。)

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

'@TestMethod
Public Sub ReversedReversesCorrectly()

Arrange:
    Dim model As New MyModel
    Const original As String = "Hello"
    Const expected As String = "olleH"
    Dim actual As String

    model.Text = original

Act:
    actual = model.Reversed

Assert:
    Assert.AreEqual expected, actual

End Sub

编写良好测试的指导原则

  1. 一次只测试一件事。只有在系统中引入错误或者要求changed.
  2. Don't包含外部依赖项(如数据库和文件系统)时,
  3. 好的测试才会失败。这些外部依赖项可能会因为您无法控制的原因而导致测试失败。其次,它们会减慢您的测试速度。如果测试很慢,就不会运行它们。
  4. 使用描述测试内容的测试名称。不要担心它会变得很长。最重要的是它是descriptive.

我知道这个答案有点长,而且有点晚,但希望它能帮助一些人开始为他们的VBA代码编写单元测试。

票数 24
EN

Stack Overflow用户

发布于 2008-09-16 09:07:31

我很欣赏诺克斯和大卫的回答。我的答案介于他们的答案之间:让不需要调试的表单成为

我认为窗体应该完全按照它们原来的样子来使用,这意味着图形界面,这意味着它们不需要调试!然后,调试作业仅限于您的VBA模块和对象,处理起来容易得多。

当然,向窗体和/或控件添加VBA代码是一种自然的趋势,特别是当Access为您提供了这些伟大的“更新后”和“更改时”事件时,但我强烈建议您不要使用将任何窗体或控件特定的代码放入窗体的模块中。这使得进一步的维护和升级成本非常高,您的代码将在VBA模块和窗体/控件模块之间拆分。

这并不意味着您不能再使用此AfterUpdate事件!只需在事件中放入标准代码,如下所示:

代码语言:javascript
复制
Private Sub myControl_AfterUpdate()  
    CTLAfterUpdate myControl
    On Error Resume Next
    Eval ("CTLAfterUpdate_MyForm()")
    On Error GoTo 0  
End sub

其中:

  • CTLAfterUpdate是每次更新控件时运行的标准过程form
  • CTLAfterUpdateMyForm是每次在MyForm

上更新控件时运行的特定过程

然后我有2个模块。第一个是

  • utilityFormEvents

我将在何处安装CTLAfterUpdate generic event

第二个是

  • MyAppFormEvents

包含MyApp应用程序的所有特定形式的特定代码,并包括CTLAfterUpdateMyForm过程。当然,如果没有要运行的特定代码,CTLAfterUpdateMyForm可能就不存在。这就是为什么我们将"On error“改为"resume next”...

选择这样的通用解决方案意义重大。这意味着你正在达到一个高水平的代码规范化(意味着代码的无痛苦维护)。当您说您没有任何特定于表单的代码时,这也意味着表单模块是完全标准化的,它们的生产可以是automated:只需说明您希望在表单/控件级别管理哪些事件,并定义您的通用/特定过程术语。

写你的自动化代码,一劳永逸。

它需要几天的工作,但它给出了令人兴奋的结果。我在过去的两年里一直在使用这个解决方案,它显然是正确的:我的表单是完全自动从头开始创建的,有一个"Forms Table",链接到一个"Controls Table“。

然后,我可以将时间花在表单的具体过程上。

代码规范化,即使使用MS Access,也是一个漫长的过程。但是这样的痛苦是值得的!

票数 17
EN

Stack Overflow用户

发布于 2008-09-16 16:45:37

Access being a COM application的另一个优点是您可以创建一个.NET application to run and test an Access application via Automation。这样做的好处是,您可以使用更强大的测试框架(如NUnit )来编写针对访问应用程序的自动化断言测试。

因此,如果你精通C#或VB.NET,再加上NUnit之类的东西,那么你就可以更容易地为你的访问应用程序创建更大的测试覆盖率。

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

https://stackoverflow.com/questions/47400

复制
相关文章

相似问题

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