繁体   English   中英

单元测试 MFC UI 应用程序?

[英]Unit testing MFC UI applications?

如何对大型 MFC UI 应用程序进行单元测试?

我们有一些已经开发多年的大型 MFC 应用程序,我们使用一些标准的自动化 QA 工具来运行基本脚本来检查基本原理、文件打开等。这些由 QA 小组在每日构建后运行。

但是我们想介绍一些程序,以便个别开发人员可以在将代码提交到日常构建之前针对应用程序的对话框、菜单和其他可视元素构建和运行测试。

我听说过诸如对话框上的隐藏测试按钮之类的技术,这些技术仅出现在调试版本中,是否有任何标准工具包可用于此目的。

环境为 C++/C/FORTRAN、MSVC 2005、Intel FORTRAN 9.1、Windows XP/Vista x86 & x64。

这取决于应用程序的结构。 如果逻辑和 GUI 代码是分开的 (MVC),那么测试逻辑就很容易了。 看看 Michael Feathers 的“谦虚对话框” (PDF)。

编辑:如果您考虑一下:如果应用程序的结构不是这样,您应该非常仔细地重构。 没有其他技术可以测试逻辑。 模拟点击的脚本只是触及表面。

其实很简单:

假设当用户单击按钮时,您的控件/窗口/任何更改列表框的内容,并且您希望确保单击后列表框包含正确的内容。

  1. 重构以便有一个单独的列表,其中包含要显示列表框的项目。 这些项目存储在列表中,不会从您的数据来源处提取。 使列表框列表事物的代码只知道新列表。
  2. 然后创建一个包含逻辑代码的新控制器对象。 处理按钮点击的方法只调用 mycontroller->ButtonWasClicked()。 它不知道列表框或其他任何东西。
  3. MyController::ButtonWasClicked() 为预期的逻辑做需要做的事情,准备项目列表并告诉控件更新。 为此,您需要通过为控件创建接口(纯虚拟类)来解耦控制器和控件。 控制器只知道该类型的对象,而不知道控件。

而已。 控制器包含逻辑代码并且仅通过接口知道控制。 现在您可以通过模拟控件为 MyController::ButtonWasClicked() 编写常规单元测试。 如果您不知道我在说什么,请阅读 Michaels 的文章。 两次。 在那之后又一次。
(自我注意:必须学会不要那么多废话)

既然你提到了 MFC,我就假设你有一个应用程序,很难在自动化测试工具下使用。 当您在编写代码时构建测试时,您将观察到单元测试框架的最大好处.. 但是尝试以测试驱动的方式将新功能添加到并非设计为可测试的应用程序中.. 可能是一项艰巨的工作并且令人沮丧。

现在我要建议的绝对是艰苦的工作……但是只要有纪律和毅力,你很快就会看到好处。

  • 首先,您需要一些管理支持,新修复需要更长的时间。 确保每个人都明白为什么。
  • 接下来买一本WELC 书 如果您有时间,或者如果您的压力很大,请从头到尾阅读它,扫描索引以查找您的应用程序表现出的症状。 这本书包含许多很好的建议,正是您尝试使现有代码可测试时所需要的。 替代文字
  • 然后对于每个新的修复/更改,花一些时间并了解您将要处理的领域。 使用您选择的 xUnit 变体(免费提供)编写一些测试以测试当前行为。
  • 确保所有测试都通过。 编写一个新的测试来练习所需的行为或错误。
  • 编写代码使最后一个测试通过。
  • 在测试区域内无情地重构以改进设计。
  • 从这里开始,对您必须对系统进行的每项新更改都重复一遍。 这条规则没有例外。
  • 现在的乐土:很快,不断增长的经过良好测试的代码孤岛将开始浮出水面。 越来越多的代码将属于自动化测试套件,并且更改将变得越来越容易。 那是因为缓慢而确定地底层设计变得更加可测试。

最简单的方法是我之前的回答。 这是艰难但正确的出路。

我意识到这是一个过时的问题,但对于我们这些仍在使用 MFC 的人来说,VS2012 中的 Microsoft C++ 单元测试框架运行良好。

一般程序:

  1. 将 MFC 项目编译为静态库
  2. 将新的本机单元测试项目添加到您的解决方案中。
  3. 在测试项目中,添加您的 MFC 项目作为参考。
  4. 在测试项目的配置属性中,为您的头文件添加包含目录。
  5. 在链接器中,输入选项添加您的 MFC.lib;nafxcwd.lib;libcmtd.lib;
  6. 在“忽略特定默认库”下添加 nafxcwd.lib;libcmtd.lib;
  7. 在 General 下添加 MFC 导出的 lib 文件的位置。

https://stackoverflow.com/questions/1146338/error-lnk2005-new-and-delete-already-defined-in-libcmtd-libnew-obj很好地描述了为什么需要nafxcwd.lib 和libcmtd.lib .

在遗留项目中检查的另一件重要事情。 在常规配置属性中,确保两个项目都使用相同的“字符集”。 如果您的 MFC 使用多字节字符集,您也需要 MS 测试来这样做。

虽然不完美,但我找到的最好的是 AutoIt http://www.autoitscript.com/autoit3

“AutoIt v3 是一种类似 BASIC 的免费软件脚本语言,设计用于自动执行 Windows GUI 和通用脚本。它结合使用模拟击键、鼠标移动和窗口/控件操作,以便以其他方式不可能或可靠的方式自动执行任务。语言(例如 VBScript 和 SendKeys)。AutoIt 也非常小,自包含,可以在所有版本的 Windows 上开箱即用,不需要烦人的“运行时”!

当您可以访问被驱动的应用程序的源代码时,这很有效,因为您可以使用要驱动的控件的资源 ID 号。 通过这种方式,您不必担心特定像素上的模拟鼠标点击。 不幸的是,在遗留应用程序中,您很可能会发现资源 ID 不是唯一的,这可能会导致问题。 然而。 将 ID 更改为唯一并重建非常简单。

另一个问题是您会遇到计时问题。 对于这些,我没有经过验证的真正解决方案。 反复试验是我使用过的,但这显然是不可扩展的。 问题是 AutoIT 脚本必须等待测试应用程序响应命令,然后脚本才会发出下一个命令或检查正确的响应。 有时要找到一个方便的事件来等待和观看并不容易。

我的感觉是,在开发新应用程序时,我会坚持以一致的方式来表示“就绪”。 这对人类用户和测试脚本都有帮助! 这对于遗留应用程序来说可能是一个挑战,但也许您可以在有问题的地方引入它,并随着维护的继续将其慢慢扩展到整个应用程序。

虽然它无法处理 UI 端,但我使用 Boost Test 库对 MFC 代码进行了单元测试。 有一篇关于入门的代码项目文章:

使用 Boost 设计健壮的对象

好吧,我们在工作场所拥有这些庞大的 MFC 应用程序之一。 维持或延长它是一个巨大的痛苦......它现在是一个巨大的泥球,但它在moolah中耙动。无论如何

  • 我们使用Rational Robot进行冒烟测试等。
  • 另一种取得一些成功的方法是创建一个小型的特定于产品的语言和脚本测试,这些测试使用 VBScript 和一些 Control 处理间谍魔法。 将常见操作转换为命令。例如,OpenDatabase 将是一个命令,它将注入所需的脚本块以单击主菜单 > 文件 >“打开...”。 然后,您创建 Excel 表格,这些表格是一系列此类命令。 这些命令也可以带参数。 有点像 FIT 测试......但更多的工作。 一旦您确定了大多数常用命令并准备好了脚本。 它是挑选和组装脚本(由 CommandID 标记)来编写新测试。 测试运行程序解析这些 Excel 表格,将所有小脚本块组合成一个测试脚本并运行它。

    1. OpenDatabase "C:\\tests\\MyDB"
    2. OpenDialog“添加模型”
    3. AddModel "M0001", "MyModel", 2.5, 100
    4. 按确定
    5. 保存数据库

HTH

实际上,我们一直在使用 Rational Team Test,然后是 Robot,但是在最近与 Rational 的讨论中,我们发现他们没有计划支持更多关注 .NET 的 Native x64 应用程序,因此我们决定切换自动化 QA 工具。 这很好,但许可成本不允许我们为所有开发人员启用它。

我们所有的应用程序都支持用于脚本编写的 COM API,我们通过 VB 对其进行回归测试,但这不是测试应用程序本身的 API。

理想情况下,我会对人们如何在开发人员级别将 cppunit 和类似的单元测试框架集成到应用程序中感兴趣。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM