Set是
Java集合类的重要组成部分,它用来存储不能重复的对象。枚举类型也要求其枚举元素各不相同。看起来枚举类型和集合是很相似的。然而枚举类型中的元素不能随意的增加、删除,作为集合而言,枚举类型非常不实用。EnumSet是专门为enum实现的集合类,本实例将演示其用法。
思路分析:可以通过为EnumSet指定类型,该类型即为在同一包中定义的枚举类。使用EnumSet类的add()方法添加元素,使用EnumSet类的remove()方法删除元素,使用EnumSet类的complementOf()方法获取对象的全部,使用EnumSet类的range()方法获取指定范围的元素。
代码如下:
Weeks.java: packagecn.edu.xidian.crytoll; publicenumWeeks{ MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURADAY,SUNDAY } EnumSetTest.java: packagecn.edu.xidian.crytoll; importstaticcn.edu.xidian.crytoll.Weeks.MONDAY; importstaticcn.edu.xidian.crytoll.Weeks.THURSDAY; importjava.util.EnumSet; publicclassEnumSetTest{ publicstaticvoidmain(String[]args){ EnumSetweek=EnumSet.noneOf(Weeks.class); week.add(MONDAY); System.out.println("EnumSet中的元素:"+week); week.remove(MONDAY); System.out.println("EnumSet中的元素:"+week); week.addAll(EnumSet.complementOf(week)); System.out.println("EnumSet中的元素:"+week); week.removeAll(EnumSet.range(MONDAY,THURSDAY)); System.out.println("EnumSet中的元素:"+week); } } |
个人理解,这两款软件从本质上说是issue tracking,而不是
项目管理。
先说些个人的想法
1)从现阶段情况看,都是够用的,毕竟本来就是小团队
2)从扩展而言,根据现在团队的实际情况(基本都是搞Java的),那么
JIRA当然有一定的优势了,比如自己写个插件啥的
3)从UI风格而言,稍偏向redmine
需求:
1)20人以下的团队
2)项目生态,相对较杂,不是专注1~2个产品的那种
3)将来希望将管理工具与代码结合起来(和版本管理一起结合或者其他模式都可以,希望能便捷的了解代码【尤其是变动】)
已经暴露的问题:
1)几乎没有这两款工具的使用经验,之前在某个项目的售后中小范围使用过redmine,今次而已
2)现阶段的代码管理是CC+SVN,准备逐步淘汰CC
3)有没有比较好的内外网解决方案?现在Maven的双网已经够折腾人了
redmine or JIRA?请各位说说自己的经验或者建议,谢谢!
毕竟一款工具的选用不是好或者不好的问题,而是适用与否的问题,只有来帮助了?
问题补充
---------------------------------------------------------
没用过 redmine ,我们用的是 jira ,
感觉用这类的东西,主要还是靠团队能按找规矩走,
新需求,改动,以及
测试的人员报出的 issue 能够写的明白,
开发中后期,可以按照一个依据来用,当然,有很多用文档描述不清,或不好表达的,还是需要面对面交流.
测试出bug,分配给项目经理,经理经过分析,再指派给某个人,或者直接回应.
插件之类的,感觉基本不会自己去写了,功能挺全的.
jira可以和svn过去关联,每次svn提交时,把 issue 的版本号写上, 在 jira 里就可以看见,对那个 issue 所提交的更改及 对于的 svn 版本.
我也不是很熟悉,但感觉还不错.
个人理解,这两款软件从本质上说是issue tracking,而不是
项目管理。
先说些个人的想法
1)从现阶段情况看,都是够用的,毕竟本来就是小团队
2)从扩展而言,根据现在团队的实际情况(基本都是搞Java的),那么
JIRA当然有一定的优势了,比如自己写个插件啥的
3)从UI风格而言,稍偏向redmine
需求:
1)20人以下的团队
2)项目生态,相对较杂,不是专注1~2个产品的那种
3)将来希望将管理工具与代码结合起来(和版本管理一起结合或者其他模式都可以,希望能便捷的了解代码【尤其是变动】)
已经暴露的问题:
1)几乎没有这两款工具的使用经验,之前在某个项目的售后中小范围使用过redmine,今次而已
2)现阶段的代码管理是CC+SVN,准备逐步淘汰CC
3)有没有比较好的内外网解决方案?现在Maven的双网已经够折腾人了
redmine or JIRA?请各位说说自己的经验或者建议,谢谢!
毕竟一款工具的选用不是好或者不好的问题,而是适用与否的问题,只有来帮助了?
问题补充
---------------------------------------------------------
没用过 redmine ,我们用的是 jira ,
感觉用这类的东西,主要还是靠团队能按找规矩走,
新需求,改动,以及
测试的人员报出的 issue 能够写的明白,
开发中后期,可以按照一个依据来用,当然,有很多用文档描述不清,或不好表达的,还是需要面对面交流.
测试出bug,分配给项目经理,经理经过分析,再指派给某个人,或者直接回应.
插件之类的,感觉基本不会自己去写了,功能挺全的.
jira可以和svn过去关联,每次svn提交时,把 issue 的版本号写上, 在 jira 里就可以看见,对那个 issue 所提交的更改及 对于的 svn 版本.
我也不是很熟悉,但感觉还不错.
关于精益的定义有许多,但其中最令我感到鼓舞的是精益企业研究所主席John Shooke在它的著作《管理精益》中所描述的一段话:精益通过提高员工的水平来保证产品开发。在这个定义的基础上,这篇论文接下来解释了精益是怎样提高人员的水平的:方法就是解决问题。这一定义揭示了以下管理实践的美妙之处:仔细设计你的
工作,让你能够清晰地看见所发生的问题(以及同时出现的
学习机会),并在问题出现后以科学的方式解决。
在与使用
敏捷方法进行
软件开发的团队共同工作时,我曾经有过一些误解:起初时,我混淆了
bug和问题的概念,并且确信敏捷过程就是精益,因为它能够使bug变得可见。在最后的几个月里,在我头脑中的概念开始渐渐清晰起来,回想起当初的情景,我开始相信,我所在的敏捷团队产生的bug,与精益系统产生的学习机会并不是一回事:后者表明在我的团队中确实存在着质量问题,而在其它许多团队身上我也看到了同样的问题。
写这篇
文章的目的,是为了描述我对bug与质量问题这一点上的思考方式是怎样逐渐变化的。这对于读者更好地理解造成bug产生的质量问题,并相应地提高绩效能够起到一些启示作用。并通过一些真实的故事描述来看清楚真正的问题所在。(先声明一点:我们并不假设所有的敏捷团队都对此问题抱有类似的误解)
什么是bug?
在软件工业中,一个bug可以代表任何形式的系统错误(NullPointerException、Http 404错误代码或是蓝屏……)、功能性错误(在我单击B的时候,系统本应执行Z,却最终执行了Y)、性能问题以及配置错误等等。
在精益的术语中,一个bug必须能够按照下一节提到的定义进行清晰的表达,才能说它是一个问题。请相信我,我所见过的(和自己产生的)bug中,95%以上都不像是某种问题。性能问题或许是个常见的例外情况,但有趣的是,它们都
而在精益团队中,一个bug并不代表一个问题,xXXX。我所见过的95%以上的bug表面上并不像真正的问题——性能问题或许是个常见的例外情况,但有趣的是,它们也是绩效的一部分,不是吗?
什么是问题?
让我们在这里做一个标准的定义吧。在《丰田模式:精益模式的实践》(Toyota Way Field book)这本书中,Jeffrey Liker定义了一个问题所需的四个方面的信息:
当前的实际绩效
预期的绩效(标准绩效或目标绩效)
以当前绩效和目标绩效之差所体现的问题严重程度
问题的范围和特点
正如Brenée Brown在TED所做的一次关于漏洞的演讲中所说的一样,如果你不能评估某个漏洞,那么它就不存在。从更实用的角度来说,如果你不能解释在绩效差距上的问题所在,那么很可能是由于你并没有花足够的时间去思考它。
在开始着手解决一个问题之前,重要的一点是要清晰地表达它,花一定时间去理解它(按照精益专家Michael Ballé的说法:要善待它),并且克制住直奔解决方案的冲动。我们都听说过爱因斯坦的名言:“如果我只有一小时的时间去解决一个问题,我会首先用55分钟去思考问题,最后用5分钟去思考解决方案。”没有人说这是件容易的事。
在软件开发敏捷团队的情境中,绩效指标或许是一张燃尽图(表示工作量与延迟)、bug数量、系统响应时间(质量)、客户对已提交的用户故事的评价(以总分10分来表示客户满意度),以及每个Sprint提交的用户故事(或用户故事总点数)数量(生产力)。
按照这些指标,可以有以下这些问题存在:
质量:这个页面的响应时间目标是在500ms以内,而在5000个并发用户的情况下,我们测量到的结果是1500ms。
质量:在Sprint结束时仍未解决的bug数量(2个,而不是0个)
工作量/延迟:我们预计这个用户故事需要3天时间完成,而实际上用了8天才完成
生产力:在Sprint结束时,整个团队共提交了5个完成的用户故事,而之前的计划是完成7个。
客户满意度:我们希望每个用户故事都能够得到8分以上(满分10分),而在上个Sprint结束后,有两个用户故事的客户满意度低于这个分数(6.5分和7分)。
怎样从bug中分析问题所在?
Bug的出现往往是系统中产生了更常见问题的一种症状,而对于精益团队来说,将这些症状与真正的问题相关联起来是至关重要的。可以这么说,正如米开朗基罗从大理石碎片中发现它的美丽,并最终打造成迷人的雕像一样,精益团队的任务(例如某些团队会将持续改进作为他们每日工作内容的一部分)就是发挥他们的洞察力,从大量的bug中发现问题,并将其抽取出来。实现这一点需要进行细致地分析,并将这些原始的问题转化为学习的机会。
我发现了一种着手进行这种分析的良好方式,就是将所有bug分门别类,并且理解每个bug类别的权重。大多数情况下,某个bug类别就体现了造成某个现有问题的原因,或者它本身就是一个问题。这种关联性可以帮助你以正确的顺序处理这些问题,并首先从对整个操作绩效影响最大的问题开始解决。如果你仍然不确定应该从何处着手,那么优先解决质量问题是比较保险的做法。
从图中可以猜测到还会有Redis 2.2.1 的
测试,相同的测试环境,1K的数据量,使用ServiceStack.Redis客户端进行如下测试:
1) Set操作
2) Get操作
3) Del操作
每一套测试分别使用三个配置进行测试:
1) 绿色线条的是开启Dump方式的持久化,5分钟持久化一次
2) 蓝色线条是开启AOF方式的持久化,每秒写入磁盘一次
3) 红色线条是关闭任何的持久化方式
对于每一个配置都使用相同的其他配置:
1) 开启VM 最大内存10GB(128字节一页)之后开始换出,VM空间160GB
2) 最大使用内存15GB,确保在Dump的时候有足够的剩余内存
3) 开启压缩,没有配置主从
现在来看一下测试结果:
从这个图中可以看出:
1) 对于没有持久化的方式,读写都在数据量达到800万的时候,性能下降几倍,此时正好是达到内存10G,Redis开始换出到磁盘的时候。并且从那以后再也没办法重新振作起来,性能比Mongodb还要差很多。
2) 对于AOF持久化的方式,总体性能并不会比不带持久化方式差太多,都是在到了千万数据量,内存占满之后读的性能只有几百。
3) 对于Dump持久化方式,读写性能波动都比较大,可能在那段时候正在Dump也有关系,并且在达到了1400万数据量之后,读写性能贴底了。在Dump的时候,不会进行换出,而且所有修改的数据还是创建的新页,内存占用比平时高不少,超过了15GB。而且Dump还会压缩,占用了大量的CPU。也就是说,在那个时候内存、磁盘和CPU的压力都接近极限,性能不差才怪。
总结一下:
1) Redis其实只适合作为缓存,而不是
数据库或是存储。它的持久化方式适用于救救急啥的,不太适合当作一个普通功能来用。对于这个版本的Redis,不建议使用任何的持久化方式。否则到时候可能会死的比较难看。说白了,期望Redis是memcached的升级版,带有各种数据结构,但是不要期望Redis来和Mongodb/Kt等来比。
2) 对于VM其实也是不建议开启,虽然开启VM可以让Redis保存比内存更多的数据,但是如果冷热数据不是很明显的话性能会非常差(我的测试都是随机查询Key,冷热不明显)。当然,对于冷热明显的情况下可以设置200% - 400%的内存作为VM空间,也不建议设置10倍的内存空间作为VM(像我的配置一样)。
3) ServiceStack.Redis客户端好像有几个
Bug,首先RedisTypedClient的Dispose居然没有实现,应该是要调用client.Dispose(),其次RedisNativeClient的Info属性不是每次都获取最新值的,第三PooledRedisClientManager的WritePoolIndex和ReadPoolIndex只看到加没看到减的地方,也不知道这是干啥的,其实每次都取第一个不是Active的Client就可以了,PooledRedisClientManager也没有把超时使用的Active的Client强制回收(避免使用的时候忘记Dispose占用过多的连接)。
从图中可以猜测到还会有Redis 2.2.1 的
测试,相同的测试环境,1K的数据量,使用ServiceStack.Redis客户端进行如下测试:
1) Set操作
2) Get操作
3) Del操作
每一套测试分别使用三个配置进行测试:
1) 绿色线条的是开启Dump方式的持久化,5分钟持久化一次
2) 蓝色线条是开启AOF方式的持久化,每秒写入磁盘一次
3) 红色线条是关闭任何的持久化方式
对于每一个配置都使用相同的其他配置:
1) 开启VM 最大内存10GB(128字节一页)之后开始换出,VM空间160GB
2) 最大使用内存15GB,确保在Dump的时候有足够的剩余内存
3) 开启压缩,没有配置主从
现在来看一下测试结果:
从这个图中可以看出:
1) 对于没有持久化的方式,读写都在数据量达到800万的时候,性能下降几倍,此时正好是达到内存10G,Redis开始换出到磁盘的时候。并且从那以后再也没办法重新振作起来,性能比Mongodb还要差很多。
2) 对于AOF持久化的方式,总体性能并不会比不带持久化方式差太多,都是在到了千万数据量,内存占满之后读的性能只有几百。
3) 对于Dump持久化方式,读写性能波动都比较大,可能在那段时候正在Dump也有关系,并且在达到了1400万数据量之后,读写性能贴底了。在Dump的时候,不会进行换出,而且所有修改的数据还是创建的新页,内存占用比平时高不少,超过了15GB。而且Dump还会压缩,占用了大量的CPU。也就是说,在那个时候内存、磁盘和CPU的压力都接近极限,性能不差才怪。
总结一下:
1) Redis其实只适合作为缓存,而不是
数据库或是存储。它的持久化方式适用于救救急啥的,不太适合当作一个普通功能来用。对于这个版本的Redis,不建议使用任何的持久化方式。否则到时候可能会死的比较难看。说白了,期望Redis是memcached的升级版,带有各种数据结构,但是不要期望Redis来和Mongodb/Kt等来比。
2) 对于VM其实也是不建议开启,虽然开启VM可以让Redis保存比内存更多的数据,但是如果冷热数据不是很明显的话性能会非常差(我的测试都是随机查询Key,冷热不明显)。当然,对于冷热明显的情况下可以设置200% - 400%的内存作为VM空间,也不建议设置10倍的内存空间作为VM(像我的配置一样)。
3) ServiceStack.Redis客户端好像有几个
Bug,首先RedisTypedClient的Dispose居然没有实现,应该是要调用client.Dispose(),其次RedisNativeClient的Info属性不是每次都获取最新值的,第三PooledRedisClientManager的WritePoolIndex和ReadPoolIndex只看到加没看到减的地方,也不知道这是干啥的,其实每次都取第一个不是Active的Client就可以了,PooledRedisClientManager也没有把超时使用的Active的Client强制回收(避免使用的时候忘记Dispose占用过多的连接)。
介绍
任何特定软件即将发布并投入生产期间,其性能一直备受关注。尽管一软件已被用户证明如预期的正常运作(通过功能测试后),故障仍可能会发生,尤其当它无法承担用户生成的大量loads, volumes, transactions等时。评估软件的质量和适用性时,很少认真考虑这种非功能需求。因此,谨慎和周密的策划分析和性能测试用例设计是防止软件性能故障的关键。有了正确的性能场景,就可以系统地进行测试执行和软件性能评估,从而可以对性能改进做出详细的分析和建议。
本文通过展示一个实际的案例研究(关于如何为一个基于云的系统规划和设计性能测试用例)解决了这个问题。性能测试结果对性能测试执行的分析,被证为测试用例设计的有效性的证据。
关于被测的基于云的系统的概述
开发被测系统的目的是:通过(最初是上网本上的)移动设备上的统一智能平台为大众提供各种在线服务。
该系统主要包括几个子系统:安装在上网本上的客户端系统,智能服务门户,位置感知服务,内容整合服务,以及承载所有在线服务系统的云或虚拟平台。
图1.被测系统的逻辑结构
客户端系统是使用Java语言开发,Java网络启动协议( JNLP )执行的。为了获取所需在线服务,客户端系统到智能服务门户网提出服务请求。存储所有服务的门户网还结合了内容整合服务和位置感知服务。所有这些使得合适的内容根据所请求的服务被推送到客户端系统的最终用户那儿。除此之外,门户网站还能够简介并结合适合服务的相关内容。另一方面,多个虚拟机上的云平台承载了所有子系统(智能服务门户网站,内容整合,以及位置感知),可以运行虚拟机实例并提供虚拟机负载的可扩展性。
该系统的逻辑结构如图1所示。从部署的角度去看,图2展示了整个系统的操作环境。
根据这两个图,很明显本系统的性能测试需要覆盖终端用户场景及服务器场景。
这是因为一个成功的服务器性能测试并不能保证在客户端运用该系统时,最终用户也会同样成功。
性能测试
这只是常用来衡量任何被测系统性能的一个概括。通常,我们设计并执行一次性能测试以弄清系统是如何响应特定load的,无论load有没有被定义为许多并发用户,volumes或 transactions。
如下表1描述了性能测试各个领域的重点。
表1.性能测试重点
上述重点保证了被测系统应对用户不断增长的loads时是可延展的,且一旦它被发布并投入生产就没有任何意想不到的问题,长远来看还有助于提高最终用户的满意度。这也将会使该系统比市场上的其它相似系统更具竞争优势。
设计性能测试用例
评估系统的测试用例的设计主要是受早前在规划和分析阶段设置的性能标准制约的。该系统需要足够快的响应速度,或者至少要达到规定的通过性能测试的最低性能标准。
图2.被测系统的物理架构
如果系统可以表现得超出这些标准,即比最低标准值更快,该系统则被认为具有更好的性能及未来可以应对更多用户的可扩展性。另一个重要方面是确保性能测试用例的目的是建立真实世界模拟测试。现实世界测试用例将大幅度提高测试结果的可靠性。确定要模拟的测试用例时的重点是“最常见使用场景”和“业务关键使用场景”。测试用例一度不得不预测最常见的场景,因为系统还未上市且唯一知道的信息是:要求的程度。一旦系统上市,例如β测试中,就应有足够的关于用户如何使用系统的信息。该系统在Apache Web服务器上,因此可以访问日志,上面提供所有游客到过系统的记录。日志可以用“流量分析器”跟踪一直以来的用户的模式和习惯。因此测试用例可用于反映真实世界场景。系统拥有者或利益相关者为使该系统通过性能测试而设置的标准规范是:系统需要在1到100个并发用户的负载下5秒内做出响应。
然而,该标准应当通过设计正确的、运行系统的、可能的场景而被进一步分解。最根本的是把性能测试一分为二:客户端性能和服务器端(云计算)性能。原因是,一个成功的测试服务器端并不等同于成功的客户端,反之亦然。
利益相关者都同意,要测试的用户数目为1 ,100,200 ,300,400 ,500,1000 , 1500和3000个并发(虚拟)用户。这些数字与下面表2中给出的各场景相关:
表2.性能测试场景和相关虚拟用户
设计性能测试用例时通常会被忽略的一方面是:将表2中的场景和一个网速测试或网络延迟连接以获得更逼真的测试用例,像对客户端系统所做的一样。这是为了模拟用户将如何体验不同互联网连接速度下系统的响应。选定的匹配性能测试的速度是标准LAN速度(这种情况下,1GbpsLAN速度),无线LAN速度,1 Mbps的有线宽带和0.44 Mbps的无线宽带。
对于云平台,只用局域网速度进行性能测试。因此,这一基于云的系统的用以执行性能测试的完整测试用例如表3所示:
表3.性能测试用例
案例研究 –把设计放入执行
一个开源性能测试工具被用来执行所有性能测试的云系统测试用例,因为相对于其他性能测试工具,它允许越来越多的user loads且没有虚拟用户许可证限制。
然而,手动执行被用于客户端系统,因为客户端系统只能在上网本上运行,所以手动测试更实用。
分布式性能测试方法被用于执行测试,以便工具可以有效地管理代理。
工具的环境设置如图3所示:
图3. 分布式性能测试执行的环境设置
性能测试结果分为两组:云平台的测试结果和客户端的测试结果。
表4详述了云平台的性能测试结果,而表5显示了客户端的性能测试结果。
此外,为了更好地理解,图4以图表形式展示了云性能结果。
表4.云平台性能的响应时间结果
图4.云平台性能测试结果
表5.客户端性能的响应时间结果
从给出的结果,可以进一步解释几个研究发现。
研究发现如下:
▪云平台或(客户端可从其获得在线服务的)服务器端系统能够在性能标准的5秒内响应1到100个虚拟用户而无任何中断。
▪虽然云平台仍然可以成功响应3000个虚拟用户,但响应时间延迟了,超出性能标准的5秒。
▪在客户端,最终用户可能会遇到:在通过客户端系统获取在线服务时,云平台的用户负载过大,响应时间延迟。
▪比起那些更慢的互联网获取,通过使用一个更快的互联网连接,最终用户可以更快地获取在线服务
结论
由于本文的重点是性能测试的测试用例设计,一个展示这些测试用例是如何被用于执行的案例研究为本文提供了论点。很显然,正确的规划对保证任何性能测试的成功都非常关键。性能测试不应该基于“想要时”或“要求时”。性能测试的测试场景和测试用例需尽可能早地被定义和设计,就和其他类型的测试一样,比如功能测试。这将决定能否顺利执行性能测试,其中包括:性能测试工具的选择,测试环境的设置,如何做出性能衡量和分析应该做的选择,性能结果不符合指定准则时扩大云平台的行动计划,以及执行测试的时间和资源。
这些到位了,任何经过了严格性能测试的系统,一旦置于生产环境中,都能够应付日益增长的负载量,并且对服务其用户更稳定,更反应灵敏。
Ant可以代替使用javac、
java和jar等命令来执行java操作,从而达到轻松的构建和部署Java工程的目的。下面来看几个知识点。
1.project元素
project元素是Ant构件文件的根元素,Ant构件文件至少应该包含一个project元素,否则会发生错误。在每个project元素下,可包含多个target元素。接下来向读者展示一下project元素的各属性。
1)name属性
用于指定project元素的名称。
2)default属性
用于指定project默认执行时所执行的target的名称。
3)basedir属性
用于指定基路径的位置。该属性没有指定时,使用Ant的构件文件的附目录作为基准目录。
2.target元素
它为Ant的基本执行单元,它可以包含一个或多个具体的任务。多个target可以存在相互依赖关系。它有如下属性:
1)name属性
指定target元素的名称,这个属性在一个project元素中是唯一的。我们可以通过指定target元素的名称来指定某个target。
2)depends属性
用于描述target之间的依赖关系,若与多个target存在依赖关系时,需要以“,”间隔。Ant会依照depends属性中target出现的顺序依次执行每个target。被依赖的target会先执行。
3)if属性
用于验证指定的属性是否存在,若不存在,所在target将不会被执行。
4)unless属性
该属性的功能与if属性的功能正好相反,它也用于验证指定的属性是否存在,若不存在,所在target将会被执行。
5)description属性
该属性是关于target功能的简短描述和说明。
3.property元素
该元素可看作参量或者参数的定义,project的属性可以通过property元素来设定,也可在Ant之外设定。若要在外部引入某文件,例如build.properties文件,可以通过如下内容将其引入:<property file=” build.properties”/>
property元素可用作task的属性值。在task中是通过将属性名放在“${”和“}”之间,并放在task属性值的位置来实现的。
Ant提供了一些内置的属性,它能得到的系统属性的列表与Java文档中System.getPropertis()方法得到的属性一致。
同时,Ant还提供了一些它自己的内置属性,如下:
basedir:project基目录的绝对路径,该属性在讲解project元素时有详细说明,不再赘述;
ant.file:buildfile的绝对路径,如上面的各例子中,ant.file的值为E:"build.xml;
ant.version:Ant的版本,在本文中,值为1.7.0;
ant.project.name:当前指定的project的名字,即前文说到的project的name属性的值;
ant.java.version:Ant检测到的JDK的版本,在上例运行结果中可看到为1.5。
下面来看具体的实例。
1.利用Ant的javac任务来编译java程序
其中build.xml文件的源码如下:
<?xml version="1.0"?> <project name="javacTest" default="compile" basedir="."> <target name="clean"> <delete dir="build"/> </target> <target name="compile" depends="clean"> <mkdir dir="build/classes"/> <javac srcdir="src" destdir="build/classes"/> </target> </project> |
运行该build.xml文件,结果如下:
Buildfile: Z:\vAccess_myeclipse\TestAnt\build.xml clean: compile: [mkdir] Created dir: Z:\vAccess_myeclipse\TestAnt\build\classes [javac] Z:\vAccess_myeclipse\TestAnt\build.xml:9: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds [javac] Compiling 1 source file to Z:\vAccess_myeclipse\TestAnt\build\classes BUILD SUCCESSFUL Total time: 2 seconds |
2.使用Ant的java任务运行Java程序
Ant中可以使用java任务实现运行Java程序的功能。下面在1的例子中进行如下的修改,修改后的build.xml文件的内容如下:
<?xml version="1.0"?> <project name="javaTest" default="run" basedir="."> <target name="clean"> <delete dir="build"/> </target> <target name="compile" depends="clean"> <mkdir dir="build/classes"/> <javac srcdir="src" destdir="build/classes"/> </target> <target name="run" depends="compile"> <java classname="com.ant.test01.Test01"> <classpath> <pathelement path="build/classes"/> </classpath> </java> </target> </project> |
可以看到在控制台的输出:
...
[java] Hello,Amigo
...
3. 使用Ant的war任务打包J2EE Web项目
配置文件源码如下:
<?xml version="1.0"?> <project name="antwebproject" default="war" basedir="."> <property name="classes" value="build/classes" /> <property name="build" value="build" /> <property name="lib" value="WebRoot/WEB-INF/lib" /> <!-- 删除build路径--> <target name="clean"> <delete dir="build" /> </target> <!-- 建立build/classes路径,并编译class文件到build/classes路径下--> <target name="compile" depends="clean"> <mkdir dir="${classes}" /> <javac srcdir="src" destdir="${classes}" /> </target> <!-- 打war包--> <target name="war" depends="compile"> <war destfile="${build}/TestAnt.war" webxml="WebRoot/WEB-INF/web.xml"> <!-- 拷贝WebRoot下除了WEB-INF和META-INF的两个文件夹--> <fileset dir="WebRoot" includes="**/*.jsp" /> <!-- 拷贝lib目录下的jar包--> <lib dir="${lib}" /> <!-- 拷贝build/classes下的class文件--> <classes dir="${classes}" /> </war> </target> </project> |
这个问题与语言无关,对于现代浏览器来说,使用 window.performance.timing这个对象就好了。
用execute_script方法(
java用executeScript)方法执行 window.performance.timing。
一般来说,下面的值都是可以拿到的
connectEnd 1351036536696 connectStart 1351036536696 domComplete 1351036538277 domContentLoadedEventEnd 1351036538146 domContentLoadedEventStart 1351036538119 domInteractive 1351036538042 domLoading 1351036537552 domainLookupEnd 1351036536694 domainLookupStart 1351036536694 fetchStart 1351036536696 loadEventEnd 1351036538295 loadEventStart 1351036538277 navigationStart 1351036536696 |
要拿请求发送时建立连接的时间,那么就用connectEnd-connectStart就可以了。
下图说明了具体的指标参数的意义。这里就不啰嗦了。
移动测试的挑战
在看移动测试的自动化工具前,你需要对与移动应用程序面临的挑战稍作了解。
设备
移动应用程序应该在你要求的设备上工作。
移动应用程序必须在每个设备上都正常工作。
移动设备必须为应用程序的运行时间进行测试。
移动设备处理能力不同,内存有限,还必须考虑通信协议。
应用
新的操作系统版本和功能意味着开发人员建立了必须被测试的新的,更复杂的程序。
多个构建常常时间很短,因此脚本执行往往不能完成。
网络
多种网络类型,必须进行测试,如GSM,CDMA,GPRS和Wi-Fi。
不同的连接速度(包括2G,3G和4G LTE)必须跨地点测试。
世界各地有超过400多的移动网络运营商,测试必须处理各种网络。
技术
必须考虑大量的测试用例。
必须处理手机特有的功能,包括触屏约定。
必须执行API级别的测试。
移动应用程序类型
当制定移动测试策略时,你必须清楚了解可能需要测试的应用程序。移动应用程序可分为本地应用程序(Native App), 网络应用程序(WebApp)和混合应用程序(Hybrid App)。
Native应用程序
Native App是专为移动操作系统所建,并直接安装到该设备上。
用户通常通过网上商店或市场(如App Store)获取这些应用程序。
Native App是用本地编程语言构建的。例如:iPhone或iPad apps是用ObjectiveC构建的,Android apps是用Java构建的。Native App速度快,提供更好的用户体验和界面,并且通常可以获取目标设备的所有功能。
Native Apps的功能包括:
存储。二进制“可执行映像”,被明确下载并存储到移动设备的文件系统中。安装过程可以由用户,或者在某些情况下,由企业的IT部门开启。
分布。获得Native Apps最常见的方法是去有相关特定设备的应用程序商店或市场(iTunes有iPhone或iPad的apps,安卓市场有Android Apps),或者通过企业分配机制获取。
操作。程序直接在操作系统中运行:
由主屏幕开启。
不需要另一个存储器应用程序来运行它。
明确利用操作系统APIs。
移动Web应用程序
移动Web应用程序是专门针对移动设备的网络驱动应用程序。
这些应用程序是通过移动设备的网页浏览器获取的(例如:iPhone上的Safari)。用户不需要在设备上直接下载和安装该应用程序。
| 利 | 弊 |
手机模拟器 | 费用: 手机模拟器是作为每个新的操作系统发布的软件开发工具包的一部分来免费提供的。
简单: 模拟器下载和安装简单,即刻使用。许多模拟器能够以简单和直接的方式来运行。
快速: 比起要连接到本地网络或云的真实设备,模拟器的等待时间更短。 | 硬件支持: 仿真模拟里,完全的硬件支持是无法测试的。
计算资源: 根据PC运行模拟器的处理能力和被用来测试的手机和智能机的类型,模拟器上的表现比起真实设备,可能是不切实际的好或坏。 网络互用性:使用模拟器不可能测试网络相关事件的影响 (如:来电,短信),不同的关于移动应用程序行为的网络技术(如: HSPDA, WCDMA, UMTS和LTE). 由于模拟器并没有连接到移动网络,它们不支持互操作性测试。 |
真实设备 | 可信赖的: 在真实设备上进行的测试给出的是最精确的结果。 网络的互操作性:真实设备测试是在真实的网络中进行的。用户体验:通过使用真实设备, 可以把特定设备的CPU,内存或屏幕大小等元素考虑在内,准确地看到用户体验。 | 物流和成本: 购买不同版本操作系统的不同设备是相当昂贵的,还要浪费不少精力来购买和管理这些设备。 |
表1:使用模拟器和真实设备的利弊
移动Web应用程序功能:
完全使用Web技术,如HTML(尤其是HTML5),CSS,Javascript代码写的。
该代码是由浏览器执行,而不是由操作系统。
用户可以通过多种方式启动应用程序:输入网址,单击超链接,扫描QR码,或者单击主屏幕上的快捷方式。
安装是非强制性的。
支持多种操作系统。
混合应用程序
类似本地应用,混合应用程序是使用传统的Web技术开发的。
Hybrid applications是在每台设备上的本地应用程序存储器中运行的,但却是集中部署和维护,是跨平台的性质的。通常情况下,他们是由云服务,所以地球上任何地方的终端用户体验是一致的,跨设备的。
使用模拟器和实际设备进行自动化测试
模拟器是用来复制一个移动设备的内部工作的。它是用于开发和测试移动应用程序的强大工具,被用于手动和自动化测试中。
当然,移动APP是用在真实设备,而不是模拟器上的,所以测试必须在实际设备上进行,以确保应用质量的最高水平。
然而,让你们组织里每个移动测试团队都拥有一个实际设备是很烧钱的,所以使用模拟器是一个可以控制成本的有效方法。
在制定移动测试策略时,你们组织应该谨慎拳皇使用模拟器或实际设备的利弊。
移动设备自动化测试工具分类
有三种类型的工具可以支持移动设备的自动化测试。
本地平台工具
本地平台工具通常是由移动平台供应商提供的软件开发工具包的一部分。这些框架通常与用户界面对象级别的应用程序进行交互。
这些工具允许更复杂的基于对象的交互,十分成熟,还支持本地UI对象,因为它们是平台供应商支持的。
因为这些是操作系统级别的应用程序对象,你可以通过用测试中的应用程序编译的小数据库(也被称为 “instrumentation”)洞察他们。
基于视觉的多平台工具
基于视觉的多平台工具最常用在移动设备自动化测试里。
这些工具通过可视化手段与设备交互,并可以识别文本或图像,使测试人员构建基于这些认识和内置的手势的自动脚本。
基于视觉的多平台工具的优点是它们支持多个平台,并且可跨多个设备执行测试。
视觉对象由OCR引擎(基本上都是将扫描的手写、机打图像,或印刷文本转换成机器编码的文本智能软件引擎)识别。
基于对象的多平台工具
基于对象的多平台工具可以在应用程序内通过识别,拦截,并发送信息到对象,直接用和传统的测试工具一样的方式来与应用程序UI对象进行交互。
这些工具的优势是,他们支持多种平台,并且可以跨平台上执行测试。
对象级整合也对应用程序变化更加宽容,从而降低与自动化测试相关的整体维护成本。
移动自动化测试的方法
在规划您的移动自动化工作时,别忘了以下的工具评估和选择,对象技术的方法:
工具评估和选择
执行工具的可行性,以检查是否该工具可以在各种移动技术和平台使用。
选择一个同时支持真机和模拟器或仿真器的工具。
识别多种设备和版本支持。
用实用性和可重复使用功能增加自动化测试工作的价值。
了解如果选择的工具需要你破解或获取设备的根。
确保该工具支持操作系统的新版本。
对象识别
基于图像的对象识别:把每个测试对象记录为图像,在GUI中匹配对象和可用运行时间图像。
光学字符识别对象的对象识别:使用光学字符识别(OCR)功能获取屏幕上的控件的文本。该功能使用了通过字符读取字符文本的专门算法。
真实对象或本地的对象标识:标识唯一对象的属性,如“ ID”,“名称”和“类” 。
基于DOM的识别:利用DOM属性来识别web应用程序对象。
特点 | 图像识别 | OCR对象 | 本地对象 | DOM对象 |
对象识别的复杂度 | 容易 | 容易 | 中等 | 中等 |
对象维护工作 | 高 | 高 | 容易 | 中等 |
跨设备支持 | 高 | 中等 | 容易 | 容易 |
执行中的识别速度 | 中等 | 中等 | 中等 | 高 |
结论
通过在移动应用程序测试中使用自动化测试,测试团队可以在保持质量和减少将产品推向市场时间的同时降低成本。
许多工具可用来支持移动设备自动化测试。选择正确的工具需要理解业务需求和移动测试独有的因素。
权衡手机模拟器和真实设备的优劣,企业的最佳移动测试解决方案往往不是只选择其中一个,而是选择结合这两者。