Sencha应用程序的UI测试

原文:http://www.sencha.com/blog/ui-testing-a-sencha-app/


几个月前,笔者写了一篇题为《自动化单元测试》的文章,内容涉及开发人员如何为业务逻辑编写单元测试和验证Javascript语法。在创建一个企业应用程序的时候必需了解这些概念:在更新要推送到产品之前必须捕获错误,或可能带来的灾难性后果。


在那篇文章没有涉及的一个领域就是“UI测试(也称为集成测试,Integration Testing)”的观念。阅读了许多关于那篇文章的评论和听到社区反馈后,我决定发表一篇在ExtJS应用程序中添加UI测试和讨论企业应用程序测试策略的文章。


      UI 测试:概述

正如前文提到的,UI测试与单元测试的不是同一样东西,这个两个概念经常造成困惑。


UI测试要做的是从主观上验证屏幕上的元素行为(包括外观)是否如预期的那样,这包括静态(平面渲染)和动态(用户操作给予的行为)两个方面。单元测试则是针对小块代码并客观验证应用逻辑。


它们主要的不同点就在于测试性质的主观性和客观性上。


这观念进一步来说,就是可以把UI测试划分为两个组成部分:QA测试组件测试

  • QA测试模拟的是在用户使用应用程序时,现实世界与应用程序的交互。
  • 组件测试就是将应用程序划分成不同的块(可重用)来验证他们的显示和行为。


在本文,将看到这两种类型的UI测试。


使用UI测试的常见问题

选择正确的工具

测试应用程序的外观和复杂的交互是一项艰巨的任务,因而,许多Web开发人员抵制(通常是放弃)通过UI测试来充分解决QA问题也就毫不奇怪了。


其实,开发人员需要解决的最大障碍是为这个工作选择最好的工具。一些工具依赖于Xpath或CSS选择器来浏览应用程序,另外,还需要复杂的服务器配置来实现自动化测试。归根结底,选择富有弹性的工具非常重要,QA测试会因业务需求改变或应用程序修改而频繁重写,因而,测试易于创建和维护相当重要。


以笔者的经验来说,有三种工具适合编写Sencha应用程序的QA测试:

  • Selenium
  • CasperJS(需要运行在PhantomJS平台)
  • Siesta

这些工具每一个都有突出的优点和缺点,不过,笔者个人觉得Siesta更易于配置,而且它的API可以无缝的与Sencha框架一起工作。


免责声明:其他UI测试工具,我不主张去使用他们,我也不主张Siesta就一定是目前最“好的”工具。我只是根据我自己的经验提供意见。


模拟数据


使用UI测试的另一个重要(经常被忽视)的问题是,测试往往不是针对在线API编写的。不管什么原因,API本身就不可靠:服务器宕机、网络出现延迟以及发生例外错误等等。


UI测试的目的是验证显示和行为,而不是存在于任何给定时间的特定数据。如果可能,UI测试应该模拟API数据,但这不是一个易于解决的问题。一些实现使用的是Ajax请求的静态数据,而另一些则需要重定向网络调用来模拟API。


不单是Javascript模拟库存在难以控制的问题,不过我不打算在本文深入探讨这个问题。我只是想让大家对该问题提供认识,因为它是常常会让人感到沮丧。在示例应用程序中,使用了Sinon.js作为API调用的存根。


说了这么多,可能会让你会觉得应该使用在线API,不过,我通常只建议在验证发布版本的时候才使用在线的API。


示例应用程序

示例Ext JS应用程序,可以在ui-tests文件夹找到使用Siesta编写的QA测试(/app/)和组件测试(/ux/)。



QA测试

在/app/文件夹下,可以在浏览器中打开index.html文件来查看QA测试的Siesta接口。在这里的目标是运行实际的应用程序并测试用户所期望的现实世界的交互。尽管示例应用程序是比较简单的示例,但两个QA测试还是演示了测试应用程序全部行为的不同方式。


第一个测试,名为“Testtabs for data in grids”(/app/tests/01_tabs.js),只是简单的加载应用程序并检查是否能确保所请求的视图的显示是正确。虽然这个特殊示例还比较原始,但在应用程序基于用户角色、喜好或其它一些逻辑动态创建它的接口时,测试结果可能会非常有用。


第二个测试,名为“Testdouble-click functionality”(/app/test/02_RsvpWindow.js),会重新加载整个应用程序。这一次,要模拟的是Grid和标签的交互以确保所需行为按预期执行。


必须注意的是,这里使用了Sinon.js文件作为Store的JsonP请求的存根。这样做就无须假定在线API能访问并能正常工作,就可测试到应用程序的功能。有许多方法可以做到这一点,在这里选择了重写Ext.data.JsonP.request()的行为来自动返回模拟数据(请看/ui-tests/app/api_stub.js)。


组件测试

在/ux/文件夹下,可以在浏览器打开index.html文件来查看组件测试的Siesta接口。与QA测试不同,这里的目标是分离各个组件并测试他们的行为。通过测试大型应用程序以外的组件,就可隔离已知错误,并保证未来的兼容性。


示例应用程序(/apuxp/tests/01_RsvpWindow.js)的唯一测试是检查RsvpWindow视图的显示和行为。默认情况下,视图(扩展自Window类)将以300×300的尺寸、带标题作为模态窗口弹出。使用Siesta,将创建一个独立的视图实例并验证这些默认配置属性。

   var defaultWin = Ext.create('ChicagoMeetup.view.RsvpWindow', {
       //default configs
   });
 
   t.is(defaultWin.modal, true, 'RsvpWindow should be modal.');
   t.is(defaultWin.title, 'RSVPs for the selected Meetup', 'RsvpWindow should have a title of "RSVPs for the selected Meetup".');
   t.is(defaultWin.getHeight(), 300, 'RsvpWindow should be 300px tall.');
   t.is(defaultWin.getWidth(), 300, 'RsvpWindow should be 300px wide.');
   t.is(defaultWin.getLayout().type, 'fit', 'RsvpWindow should have "fit" layout.');

这非常有用,也是一个好注意,可以为了可重用性确保RsvpWindow能被自定义。在Siesta测试,还可创建另一个RsvpWindow实例,不过,这次将重写默认值以确保初始化过程成功。

   var customWin = Ext.create('ChicagoMeetup.view.RsvpWindow', {
       modal  : false,
       title  : 'Foobar Window',
       height : 400,
       width  : 200,
       layout : 'card'
   });
 
   t.is(customWin.modal, false, 'RsvpWindow should be modal.');
   t.is(customWin.title, 'Foobar Window', 'RsvpWindow should have a title of "Foobar Window".');
   t.is(customWin.getHeight(), 400, 'RsvpWindow should be 300px tall.');
   t.is(customWin.getWidth(), 200, 'RsvpWindow should be 300px wide.');
   t.is(customWin.getLayout().type, 'card', 'RsvpWindow should have "card" layout.');

使用Siesta强大的测试API,可以模拟组件的各种交互方式(click、drag等等)。虽然RsvpWindow组件还不足以令人兴奋,但可以想象一下那些自定义的UX类的可能性。


结论

创建一个Web樱花程序的单元测试可能是一个艰巨的任务,但当做得争取时,努力的回报是无价的。最后,笔者想重申以下这些要点:

  • 单元测试和UI测试并不同。两者对保持稳定代码都很有价值,不过他们是用来解决不同问题的。
  • 注意语法。仅仅因为代码可以在一个浏览器中运行正确并不意味着它可以在每一个浏览器都能正确运行。
  • 测试自定义组件。框架如预期那样正常运行了,不过,不要以为UX就写对了。
  • 不要瞄准100%的代码覆盖率。可能会有测试整个应用程序的想法,但要考虑维护一个复杂的测试套件的成本。

这系列关于单元测试的文章是基于笔者个人经验来协助解决Sencha的用户解决常见问题的。在网络研讨会会学到更多。笔者会主持1月31日的Mats Bryntse来给开发人员介绍切合实际的测试Ext JS和Touch应用程序的方法。注册地址在这里。另外,还邀请你来分享自己的想法和经验,希望大家可以互相帮助,使Web应用程序测试更易于实现目标。


作者:Arthur Kay
Arthur Kay has been working with the Web since the late 1990s, when GeoCities and scrolling marquees were all the rage. Since those early days, Arthur graduated from Loyola University Chicago (where he studied Music and Computer Science) and has worked in a variety of professional roles throughout the Internet industry. Arthur currently lives in the Chicago suburbs and works as a Solutions Engineer for Sencha, Inc.


深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值