如何对GUI进行单元测试?

时间:2008-10-18 19:16:03

标签: unit-testing code-coverage

我的代码中的计算经过了充分测试,但由于GUI代码太多,我的整体代码覆盖率低于我的预期。有关单元测试GUI代码的指南吗?它甚至有意义吗?

例如,我的应用中有图表。我无法弄清楚如何自动化测试图形。需要人眼AFAIK来检查图表是否正确。

(我正在使用Java Swing)

14 个答案:

答案 0 :(得分:65)

像MVP和MVC这样的设计通常会尝试从实际的GUI中抽象尽可能多的逻辑。一篇非常受欢迎的文章是Michael Feathers的"The Humble Dialog Box"。就个人而言,我尝试将逻辑移出用户界面时遇到了不同的经验 - 有时候它的效果非常好,而有时它却比它的价值更麻烦。但这有点超出了我的专业领域。

答案 1 :(得分:33)

当然,答案是使用MVC并尽可能多地移出GUI。

话虽这么说,很久以前我从一位同事那里听到,当SGI将OpenGL移植到新硬件时,他们进行了一系列单元测试,可以在屏幕上绘制一组灵长类动物,然后计算MD5的总和。帧缓冲区。然后可以将此值与已知良好的哈希值进行比较,以快速确定API是否按像素精确。

答案 2 :(得分:10)

您可以尝试UISpec4J是基于Swing的Java应用程序的开源功能和/或单元测试库......

答案 3 :(得分:6)

以下是一些提示:

尝试从GUI(拥有控制器和模型对象)中删除尽可能多的代码,这样您就可以在没有GUI的情况下测试它们。

对于图形,您应该测试您为生成图形的代码提供的值。

答案 4 :(得分:6)

您可以尝试使用CucumberSwinger以简单的英语为Swing GUI应用程序编写功能验收测试。 Swinger使用Netbeans的Jemmy库驱动应用程序。

Cucumber允许你编写这样的测试:

 Scenario: Dialog manipulation
    Given the frame "SwingSet" is visible
    When I click the menu "File/About"
    Then I should see the dialog "About Swing!"
    When I click the button "OK"
    Then I should not see the dialog "About Swing!"

请查看此Swinger video demo以查看其实际效果。

答案 5 :(得分:5)

Selenium RC,它将自动测试基于Web的UI。它将记录动作并重放它们。您仍然需要完成与UI的交互,因此这对覆盖率没有帮助,但它可以用于自动构建。

答案 6 :(得分:5)

测试是一种艺术形式。我同意逻辑应该尽可能地删除GUI。然后我们可以将重点放在那里。像其他测试一样,关于降低风险。你不总是需要测试所有东西,但很多时候最好的办法就是打破不同区域的不同测试。

另一个问题是你真正想要在UI层测试什么。 UI测试是最昂贵的测试,因为它通常需要更长的时间来创建,维护并且最脆弱。如果您在尝试绘制线之前测试逻辑以确定坐标是否正确,那么您具体测试的是什么?如果要测试带有红线的图形。你能给它一套预定的坐标并测试某些像素是红色还是不红色?正如上面提到的位图比较工作,Selenium但我主要关注的不是过度测试GUI,而是测试有助于创建UI的逻辑,然后关注UI的哪些部分中断或怀疑并集中一些测试那里。

答案 7 :(得分:3)

您可以使用JFCUnit来测试您的GUI,但图形可能更具挑战性。我有几次拍摄了GUI的快照,并自动将它与之前的版本进行了比较。虽然这不提供实际测试,但如果自动构建无法产生预期输出,它会提醒您。

答案 8 :(得分:3)

我从您的问题中收集到的是,您正在寻找一种自动测试GUI行为的方法,您提供的示例是测试曲线是否实际绘制正确。

单元测试框架提供了一种自动化测试的方法,但我认为您要做的测试类型是复杂的集成测试,可以验证多个类的正确行为,其中包括GUI工具包/库的类,你不应该测试。

您的选择非常依赖于您使用的平台/工具包/框架:例如,使用Qt作为其GUI框架的应用程序可以使用Squish自动化其测试。验证测试结果一次,随后自动执行的测试将结果与验证结果进行比较。

答案 9 :(得分:2)

适用于Swing&的

Window Licker Ajax的

答案 10 :(得分:0)

据我所知,这很复杂,而且真的取决于语言 - 许多语言都有自己的GUI测试方式,但是如果你真的需要测试GUI(而不是模型/ gui交互),那么你通常需要模拟实际用户点击按钮。例如,Eclipse中使用的SWT框架提供SWTBotJFCUnit已经被提及,Mozilla有自己的方式在XUL中模拟这个(并且从我在他们的博客上看到的,这些测试似乎很脆弱。)

有时您必须截取屏幕截图,并测试像素完美呈现(我相信Mozilla会这样做以检查正确呈现的页面) - 这需要更长的设置,但可能是您需要的图形。这样,当您更新代码并且测试中断时,如果失败是真实的,您必须手动检查图像,或者您改进了图形渲染代码以生成更漂亮的图形并需要更新屏幕截图。

答案 11 :(得分:0)

如果您使用的是Swing,FEST-Swing对于驱动GUI和测试断言非常有用。如果我点击按钮A,对话框B应显示“或”,如果我从下拉列表中选择选项2,则可以非常简单地测试“取消选择“

您提到的图表方案并不容易测试。只需创建和显示GUI组件(并且可能使用FEST驱动它们),就很容易获得GUI组件的代码覆盖率。然而,做出有意义的断言是困难的部分(没有有意义的断言的代码覆盖是一种自我欺骗的练习)。你如何测试图表是否被颠倒或过小?

我认为您必须接受GUI的某些方面无法通过自动化单元测试进行有效测试,并且您必须以其他方式测试它们。

答案 12 :(得分:0)

测试GUI库不是您的工作。因此,您可以逃避检查屏幕上实际绘制的内容并检查窗口小部件的属性的责任,而信任库,它们可以准确地代表绘制的内容。

答案 13 :(得分:0)

我的GUI测试方法正在不断发展,业界共识也在不断发展。但是我认为一些关键技术已经开始出现。

我会根据情况(例如,它是哪种GUI,需要多快构建,最终用户是谁等)使用一种或多种技术。

  1. 手动测试。处理代码时,您始终在运行GUI,并确保它与代码同步。您可以在工作时手动测试和重新测试工作的零件,从而在代码和正在运行的应用程序之间切换。每次完成一些重要的工作时,都会对应用程序的整个屏幕或整个区域进行整体测试,以确保没有任何退步。

  2. 单元测试。编写针对GUI行为的功能或较小单元的测试。例如,您的图形可能需要根据“基本”颜色计算出不同的颜色阴影。您可以将该计算结果提取到一个函数中,并为其编写单元测试。您可以在GUI中搜索这样的逻辑(尤其是可重用的逻辑),并将其提取到谨慎的功能中,从而可以更轻松地进行单元测试。甚至可以通过这种方式提取和测试复杂的行为-例如,可以将向导中的一系列步骤提取到函数中,而单元测试可以验证给定输入是否返回了正确的步骤。

  3. 组件资源管理器。。您将创建一个“资源管理器”屏幕,其唯一作用是展示构成GUI的每个可重用组件。该屏幕为您提供了一种快速简便的方法,可以直观地验证每个组件的外观和感觉。与手动浏览整个应用程序相比,组件浏览器效率更高,因为A)您只需要验证每个组件一次,B)您无需深入应用程序即可查看组件,只需查看和查看即可。立即验证。

  4. 自动化测试。您编写了一个与屏幕或组件交互,模拟鼠标单击,数据输入等的测试,断言在进行这些操作后应用程序可以正常运行。这可以用作额外的备份测试,以捕获其他测试可能遗漏的潜在错误。我倾向于为GUI中最容易出现故障和/或非常关键的部分保留自动化测试。我想尽早知道零件是否损坏的零件。其中可能包括高度复杂的交互式组件,容易受到破坏或损坏主屏幕。

  5. 差异/快照测试。您编写了一个仅将输出捕获为屏幕截图或HTML代码并将其与先前输出进行比较的测试。这样,每当输出更改时,您都会收到警报。如果GUI的视觉方面很复杂和/或可能会发生变化,则差异测试可能会很有用,在这种情况下,您需要快速直观的反馈,以了解给定更改对GUI整体的影响。

    < / li>

我不是费力地使用每种可能的测试,而是更喜欢根据自己正在从事的工作来选择测试技术。因此,在一种情况下,我将提取一个简单的函数并对其进行单元测试,但在另一种情况下,我将向组件资源管理器中添加一个组件,依此类推。

我还没有发现代码覆盖率是一个非常有用的指标,但是其他人可能已经发现了它的用途。

我认为第一个衡量标准是错误的数量和严重性。您的首要任务可能是拥有一个运行正常的应用程序。如果应用程序正常运行,则应该很少或没有错误。如果存在许多错误或严重错误,则大概是您没有测试或测试无效。

除了减少错误外,还有其他措施,例如性能,可用性,可访问性,可维护性,可扩展性等。这些措施会有所不同,具体取决于您所构建的应用程序类型,业务,最终用户等。

这一切都是基于我的个人经验和研究以及UI TestsHam Vocke上的出色写作。