FlexMonkey为Flex用户界面开发人员带来了单元测试

在过去的十年中,维护自动化的单元测试套件的做法已被广泛接受,以至于当今大多数开发人员要么从事一定数量的测试编写,要么至少因不这样做而感到难过。 自动化单元测试的兴起导致对于谁应该测试什么感到有些困惑。 开发人员应该在单元测试中争取100%的代码覆盖率吗?如果是,这是否意味着我们不再需要专门的QA测试人员? 许多开发团队在用户界面上划清界限,理由是由于用户界面几乎不需要编程即可执行,因此可以由专用测试人员以手动或专用测试工具对它们进行更经济的测试。 这种分工使许多人将测试领域划分为“单元测试”和“功能测试”,开发人员提供前者,而QA测试人员则提供后者。 在本文中,我们将探讨Gorilla Logic的新型开源Flex用户界面自动化测试工具FlexMonkey如何提高开发人员和QA测试人员的工作效率。 FlexMonkey允许开发人员将用户界面测试合并到单元测试套件和持续集成环境中,并允许QA测试人员扩展这些单元测试以创建和维护全面的质量测试。

虽然由开发人员和QA测试人员进行的测试最终都旨在确保应用程序按预期运行,但开发测试的总体目标与QA的目标有所不同。 开发人员测试的目标是确保新编写或修改的代码按预期工作,并且不会引起“回归”(即,先前工作代码的无意破坏)。 自动化的回归测试是敏捷开发的关键部分,因为只有疯狂的开发人员才能对工作代码进行最琐碎的重构,而没有足够的自动化测试来确保重构后的代码仍然有效。

期望开发人员对每个新编写的代码进行测试是合理的,但不必使每个此类测试都自动化。 手动测试对于测试新功能或修改的功能可以完全有效,但是手动测试作为防止回归的手段几乎总是不切实际的。 为了防止回归,开发人员必须提供一组测试,以对应用程序进行自上而下和端到端(前端到后端)的测试,但轶事证据表明,即使是自动化测试,其覆盖率也仅为50%的代码可以有效地防止许多应用程序中的回归。

QA测试要比开发人员测试更为详尽,因为QA测试旨在确保代码在所有可能的使用场景下都能正常运行。 换句话说,质量检查测试人员的任务是通过对应用程序执行可怕的操作来破坏该应用程序。 开发人员当然很熟悉许多可怕的事情,并且可以自己提供这样的测试,但这实际上只剩下很少的时间来编写代码。

胜任的开发人员要么遵循测试优先原则,即在甚至没有实现API本身之前就构建了小型测试工具来行使API,要么采用一种“一点点测试就一点代码(CALTAL)”的方法,所开发的每个代码单元在编译后都将立即进行测试。 CALTAL方法在用户界面(UI)开发人员中尤为普遍,因为与可以在实现之前定义为逻辑接口的API不同,没有真正的方法可以表达用户界面以进行测试,而无需实际执行一些操作视图和控制器代码。

传统上,程序员主要依靠xUnit系列测试框架来组织和执行单元测试。 xUnit框架(例如JUnitFlexUnit )使开发人员可以管理大型的自动化测试套件。 使用这些框架,各个测试套件可以单独运行或组合运行,以便为系统一个方面开发的套件可以独立运行,也可以作为测试整个子系统或整个应用程序并合并其的较大套件的一部分而包含。报告,以便开发人员和管理人员可以轻松地查看摘要和详细的测试结果。 xUnit测试本身就是小程序,它们行使应用程序代码并验证实际结果是否与预期结果相符。 xUnit测试套件提供了一种防止回归的简单但有效的方法。 大多数构建系统(例如ant)在应用程序构建过程中为运行xUnit测试套件提供直接支持,而持续集成系统(例如Cruise ControlHudson)则在每次将代码提交到团队的版本时自动启动此类构建控制系统,并有帮助地确定任何因提交未通过测试套件的代码而应被团队嘲笑的人。 (这种嘲笑对于提高开发团队的整体效率至关重要。)

另一方面,QA测试人员主要依靠可视化工具来记录与应用程序的交互,例如鼠标单击和键盘输入,然后可以在验证结果时回放这些交互。 从历史上看,此类工具不太适合开发人员使用,因为生成的录制脚本通常非常脆弱,以至于视图布局的细微变化(例如重新排列输入字段或引入与特定脚本无关的其他用户界面元素)即使使用情况在逻辑上仍与更新的视图兼容,也会导致播放失败。 结果,在UI测试自动化时,UI开发人员往往会通过编写直接调用控制器代码或通过生成“合成” UI事件来编写以编程方式行使控制器代码的测试,来“剥离”用户界面本身。 尽管这种方法并非没有优点,但可能难以准确地再现用户界面代码的异步处理。 结果,开发此类测试可能会很费力,并且由于用户界面本身并未直接由测试执行,因此此类测试通常无法验证对键盘和鼠标输入的正确处理或正确的显示数据的。 因此,开发人员对用户界面的所有测试通常都是手动过程。 虽然这种方法肯定允许UI开发人员参与CALTAL流程,但它导致用户界面完全被自动化回归和连续集成测试所忽略。

FlexMonkey的设计完全是为了提供强大的记录和回放功能,类似于HP的QuickTest Professional等商业工具,但这样做的方式可以满足开发人员和QA测试人员的需求。 FlexMonkey提供了用户交互方案的交互式记录和回放,但还可以将测试另存为可立即运行的FlexUnit测试套件。 生成的包含这些测试的ActionScript是可读且可编辑的,甚至可以从头开始进行编码,而不是通过记录进行编码。

交互式创建测试

FlexMonkey本身是Adobe AIR应用程序,但是可以测试AIR和Flex应用程序,包括使用远程服务(例如BlazeDS)的基于服务器的Flex SWF。 FlexMonkey可以记录和回放应用程序的交互,而无需链接任何特殊的测试库,并且可以在独立运行或在浏览器中运行时对应用程序进行测试。

要创建测试套件,可以使用FlexMonkey启动器来运行应用程序,方法是通过文件选择对话框导航到SWF文件,或者通过指定URL来加载驻留在服务器上的SWF。 FlexMonkey将启动SWF并将其显示在其自己的窗口或浏览器页面中,并将打开一个单独的窗口,其中包含FlexMonkey控制台 ,该控制台管理用户界面测试的记录和编辑。 要记录测试,只需单击“记录”按钮,然后与您的应用程序进行交互。 当您单击组件并在应用程序窗口中键入字段时,每个动作都会被记录并显示在FlexMonkey控制台中。 下面的屏幕快照显示了一个简短记录会话的结果,其中我们使用一个简单的联系人管理器应用程序(“猴子联系人管理器”)输入姓名(“弗雷德”)和电话号码(“ 555 555 1212”),以及单击添加按钮以在应用程序的联系人列表中创建新行。 FlexMonkey可以忠实地记录任何UI事件,包括更多的“奇异”事件,例如,选择嵌入在DataGrid中的ComboBox中的值。

在上面的屏幕截图中,我们看到FlexMonkey控制台包含在手动测试Monkey Contact Manager应用程序时记录的事件。

FlexMonkey使用熟悉的xUnit测试层次结构,该层次结构将测试组织到测试用例和套件中。 在此示例中,我们创建了一个名为MonkeyContactsSuite的套件, 其中包含一个名为MonkeyContactsCase的测试用例 。 反过来,该测试用例包含一个名为TestAddNewContact的测试,该测试由我们刚完成记录的各种用户操作组成。 对于每个用户操作,FlexMonkey都会捕获UI Event ,标识事件目标的属性和值对以及事件特定的参数。 通过单击第一个Input操作,我们可以看到其详细信息显示在FlexMonkey Console的右侧,并且我们可以编辑各种参数。 例如,我们可以在播放期间将脚本更改为输入“ Ethel”而不是“ Fred”。

对于此操作,将带有参数“ Ethel”的Input UI Event发送到具有AutomationName属性(其值为inName)的组件 。 换句话说,此操作将指示FlexMonkey在播放期间在联系人管理器的“ 名称”字段中输入“ Ethel”。 容器值容器属性字段可用于通过指定标识父容器的属性/值对来进一步限定哪个组件是事件的目标。 通过目标以及容器属性来标识UI组件的能力使得可以轻松明确地引用任何UI组件,即使没有为其指定AutomationName属性的组件也是如此。 例如,我们可以创建一个操作,在带有id =“ editPanel”的组件内单击带有label =“ Go”的组件。

我们可以通过单击FlexMonkey Console上的Verify按钮(绿色复选标记)来交互式创建一个断言,以验证一组属性值,这将打开FlexMonkey Spy Window 。 使用间谍窗口,我们可以选择要验证其期望值的UI组件的任何属性集。 下面的屏幕快照显示了在执行一组操作之后,如何使用间谍窗口指定“ 名称”字段的text属性的值应为“ Fred”。

除了验证属性值外,FlexMonkey还可以在记录过程中捕获应用程序窗口的选定区域的位图图像,并在回放过程中将窗口的相同区域与该位图进行比较,从而提供了一种自动“选择”部分的“眼球”方法。应用程序的实际屏幕显示。

现在,我们可以单击“ 播放”按钮来运行测试。 FlexMonkey会针对联系人管理器应用程序重放每个记录的操作,并且该应用程序的响应完全就像是使用鼠标和键盘手动输入的那些操作一样。 我们的简单测试结果如下所示。

通过这种方式使用FlexMonkey,我们可以交互地创建和维护各种复杂的测试套件,其中包括任意数量的测试用例和测试。

在ActionScript中生成测试

除了以交互方式创建和运行测试之外,我们还可以使用FlexMonkey API以编程方式指定可以与xUnit框架 (包括Fluinthttp://fluint.googlecode.com )和FlexUnit 4http://opensource.adobe) .com / wiki / display / flexunit / FlexUnit)。

尽管通过针对FlexMonkey API进行编码完全从头开始创建测试是相当合理的,但是我们可以使用FlexMonkey Console代替直接从记录的测试场景中创建基于ActionScript的测试。 选择“生成AS3”菜单选项将为每个套件和测试用例创建ActionScript类。 每个单独的测试在其对应的测试用例类中作为方法输出。 这是为我们的简单示例生成的测试用例类。

package testSuites.MonkeyContactsSuite.tests {
    import com.gorillalogic.flexmonkey.events.MonkeyCommandRunnerEvent;
    import com.gorillalogic.flexmonkey.core.MonkeyTest;
    import com.gorillalogic.flexmonkey.monkeyCommands.*;
    import com.gorillalogic.flexmonkey.application.VOs.AttributeVO;
    import com.gorillalogic.flexmonkey.flexunit.tests.MonkeyFlexUnitTestCase;

    import mx.collections.ArrayCollection;

    import flash.events.IEventDispatcher;

    public class MonkeyContactsCase extends MonkeyFlexUnitTestCase{
	public function MonkeyContactsCase(){
	    super();
	}

	private var mtTestAddNewContact:MonkeyTest = new MonkeyTest(null,
'TestAddNewContact', null, 500,
	    new ArrayCollection([
		new UIEventMonkeyCommand('Input', 'inName', 'automationName', ['Fred']),
		new UIEventMonkeyCommand('Input', 'inPhone', 'automationName', ['555 555 1212']),
		new UIEventMonkeyCommand('Click', 'Add', 'automationName', ['0'])
		]));

	private var mtTestAddNewContactTimeout:int = 8500;

	[Test]
	public function TestAddNewContact():void{
	    // startTest(<MonkeyTest>, <Complete method>, <Async timeout value>,
<Timeout method>)
	     startTest(mtTestAddNewContact, TestAddNewContactComplete,
mtTestIA1TimeoutTime, defaultTimeoutHandler);
	}

	public function TestAddNewContactComplete(event:MonkeyCommandRunnerEvent, passThroughData:Object):void{
	     checkCommandResults(mtTestAddNewContact);
	}
    }
}

已为我们测试中的每个操作生成了一个UIEventMonkeyCommand。 这些命令中的每个命令都指定一个动作,标识该动作目标组件的属性/值对以及一系列特定于动作的参数。 (所有可用操作均在http://code.google.com/p/flexmonkey/wiki/FlexMonkeyCommands上进行了记录。)在示例中,每个UIComponent均已被标识为automationName属性,但如上所述,我们可以改用任何属性/值对。

我们可以轻松修改脚本而无需重新录制。 例如,通过在数组中插入以下命令,我们可以从联系人管理器的组合框中选择“移动”电话类型:

new UIEventMonkeyCommand('Select', 'inType', 'id', ['Mobile'])

我们可以通过编程生成命令来测试向我们的经理添加1000个联系人。 例如,下面的代码行反复输入一个唯一的联系人姓名,然后单击添加按钮:

for (var i:int=0; i<1000; i++)
    { mtTestAddNewContact.addItem(new UIEventMonkeyCommand('Input', 'inName', 'automationName', ['Contact' + i]));
    mtTestAddNewContact.addItem(new UIEventMonkeyCommand('Click', 'Add', 'automationName', ['0']));
}

对于每个生成的测试方法,也会生成一个相应的Complete方法。 完成测试方法后,将调用Complete方法。 我们可以向此方法添加其他断言,以测试其他属性。 例如,我们可以检查脚本完成后,列表中第一个联系人的姓名是“ Fred”。

public function TestAddNewContactComplete(event:MonkeyCommandRunnerEvent, passThroughData:Object):void{
    var grid:DataGrid = MonkeyUtils.findComponentWith("grid", "id"); // Find the component with id="grid"

    var actual:String = grid.dataProvider[0]["name"] assertEquals("First contact was not Fred", "Fred", actual);
}

我们也可以通过这种方式测试非可视应用程序类的值。

我们可以使用FlexMonkey的GUI TestRunner运行测试,该GUI加载要测试的SWF以及包含测试本身的SWF,然后运行测试。

尽管我们在这里研究的示例非常简单,但应该清楚的是,FlexMonkey通过代码生成和自定义的强大功能和灵活性,为用户界面场景记录提供了便利和效率。

持续集成进行UI测试

FlexMonkey提供了可以从ant任务中调用的测试运行程序,并输出可以与其他FlexUnit测试以及Java的JUnit测试汇总的结果。 使用JUnit的junitreport ant任务,可以使用下面显示的熟悉的JUnit报告格式呈现FlexMonkey测试输出。

FlexMonkey ant任务启动FlexMonkey启动程序,该启动程序将加载要测试的SWF,并包含测试本身的SWF。 输出通过套接字发送回FlexMonkey ant任务,该任务将其写入磁盘,以便可以将它们与其他Fluint / FlexUnit或JUnit测试输出合并,以提供包含套件的所有Flex和Java测试的合并报告。

由于FlexMonkey可以从ant运行,因此可以使用Cruise ControlHudson之类的框架轻松地将其集成到连续的集成构建中。

猴子自上而下的测试

通过结合记录器,代码生成器和易于使用的API,FlexMonkey允许开发人员创建量身定制的,复杂的,自动化的用户界面测试,以行使应用程序功能,而不会因整个开发过程中用户界面的不断发展而脆弱生命周期。 在Flex应用程序中,对于大多数操作而言,用户界面是堆栈的顶部,而FlexMonkey允许自上而下的测试方法,为低级应用程序类的单元测试提供了有力的补充。 通过创建可行使用户界面本身的测试,开发人员可以使用最少的测试数量来测试最大数量的代码。 实际上,通过对与远程后端进行通信的应用程序运行FlexMonkey测试,FlexMonkey可以从用户界面一直将端到端测试驱动回数据库或外部系统。 在持续集成环境中包含这样的测试可以为整个团队提供最大的保证,即每次代码更改都不会无意间破坏了应用程序系统中某些遥远但相互依存的部分。

开发人员测试与质量检查测试

尽管开发人员当然可以使用FlexMonkey创建可提供完整代码覆盖范围的测试,并完全消除了对QA测试的需求,但让开发人员自动执行代表性的应用程序功能仍然是更好的分工和技能专长,但仍由QA负责。提供确保完整代码覆盖范围所需的大量测试,以及更一般地对应用程序执行可怕的操作以查看其性能。 FlexMonkey满足了开发人员和质量检查测试人员的需求,并且通过提供一个通用的测试平台,使开发人员最初创建的测试可以为质量检查人员创建的更广泛的测试提供基础。

尽管QA测试的笼统性质有时会使它们过于脆弱以致不能包含在连续集成套件中,但也可以将QA测试集成到连续集成环境中。 无论如何,可以选择将选定的质量检查测试添加到集成套件中,这将使开发人员更容易建立全面的测试基础。

入门

您可以在http://flexmonkey.gorillalogic.com上找到FlexMonkey源代码,二进制文件和完整文档的链接。 Gorilla Logic还提供培训和咨询服务,可以快速启动用户界面测试自动化,并帮助快速建立全面的持续集成环境。 您也可以关注项目博客: http : //flexmonkey.org

翻译自: https://www.infoq.com/articles/flexmonkey-ui-unit-testing/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值