qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

Java实现高效的枚举元素集合

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);
}
}

posted @ 2014-05-21 10:09 顺其自然EVO 阅读(191) | 评论 (0)编辑 收藏

项目管理软件选择:redmine or JIRA

个人理解,这两款软件从本质上说是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 版本.
  我也不是很熟悉,但感觉还不错.

posted @ 2014-05-21 10:08 顺其自然EVO 阅读(647) | 评论 (0)编辑 收藏

项目管理软件选择:redmine or JIRA

个人理解,这两款软件从本质上说是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 版本.
  我也不是很熟悉,但感觉还不错.

posted @ 2014-05-21 10:08 顺其自然EVO 阅读(538) | 评论 (0)编辑 收藏

如何从敏捷到精益地修复bug与解决问题

  关于精益的定义有许多,但其中最令我感到鼓舞的是精益企业研究所主席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类别就体现了造成某个现有问题的原因,或者它本身就是一个问题。这种关联性可以帮助你以正确的顺序处理这些问题,并首先从对整个操作绩效影响最大的问题开始解决。如果你仍然不确定应该从何处着手,那么优先解决质量问题是比较保险的做法。
 示例1:敏捷开发中的情景
  当时我在这个使用敏捷开发的团队中担任经理一职。和许多团队一样,我们团队也不是一个跨职能的团队(典型的Scrum-but),而是一个负责后台的团队。它在某个迭代内负责构建基础服务端软件,以便让应用团队在之后的迭代中使用这部分功能。
  我们按照Paretos原则(即80-20原则)对产生的bug进行了一些分析,并且找出了一个占总数约20%的bug类别:这些bug都是由应用团队所提出的,与我们团队所建立的后台软件所暴露的API对“隐式”这一概念的定义有关。当应用团队在使用我们提供的功能时,经常会发生遗漏了某些输入参数,或者是缺少了某些输出数据等问题……因此他们就会为我们创建一些bug,而我们的团队则会说:嘿!这个API已经隐式地表明了它不会返回这些数据。
  我们同时注意到了这些bug的持续时间,通常从创建直到关闭为止一共持续了大约4个星期。(在最好的情况下)在以一个月为周期的迭代的最后阶段会进行代码发布,客户端团队则可以在下一个迭代时使用这些代码。因此当客户端团队创建了bug,并指派给原来的开发者时,往往距离她开发那些代码时已经过去了两三个星期,开发者不得不再度拾起这段代码……
  为了处理这种情况,我们决定改变一下工作的方式,将相关人员组织在一起,而产生一个相关联、跨职能并且跨技能的团队。
  采用了新的方式之后,我们注意到这些“隐式API”相关的bug数量大幅下降了(约50%)。最令人欣慰的是,这种类型的bug的持续时间下降到了几个工作日以内。当然,这个数字有一定的水分,有些bug虽然被发现了,但是并没有记录下来,因为开发者们现在进行结对编程,于是许多bug直接在座位上就解决了。
  虽然成果是显著的,但我总感觉到还有些不适之处,却说不出究竟是哪里出了问题。之后不久我才发觉,从精益的角度来说,我们目前还有两个不足之处:
  首先,我们的系统中依然存在bug,因此我们不得不重复劳动,这使得整个开发系统出现了生产力的浪费。但是由于缺乏内建的质量标准,我们无法保证服务端开发者所开发的API不存在问题。此外,对于错误的处理也没有真正的标准,我们的解决手段就是:遇到问题就坐下来一起解决。
  尽管结果非常显著且令人振奋,但它与团队的每日绩效没并有什么直接的关联,团队也无法立即采取行动并在第二天直接看到结果。我们只是从宏观上在6个月结束后的发布中才能够看到这一效果:即在bug总数中与API相关的bug只占少数。因此我们看到:建立一个跨技能的团队确实能够在某种程度上改进质量,但我们还未能提供一种有效的方法,让我们能够每天监控它的情况,并采取相应的行动。
  示例2:精益开发中的情景
  时间转眼间过去了几年,我还是任职于同一家公司中,但目前的职位是项目主管及教练,负责一个大型的多团队、多种技术的敏捷项目的实施。某一个团队遇到了一个很有挑战的技术难题,他们要与某个大家都没有什么经验的技术进行整合。整个团队在过去的两个Sprint中没有交付任何用户故事,他们深陷于质量问题(例如bug)中难以自拨。当第二个Sprint结束后,依然没有任何完成的用户故事(比方说,按照我们对完成的定义来看,该用户故事在功能性需求上需要做到没有任何bug)可以交付。因此在回顾会议中,整个团队一致决定,将每周进行bug评审(在精益中称为红箱分析)。
  在第一次会议中,团队为所遇到的问题建立了一个Pareto模型。我们创建了一张表格,将bug类别放在一列里,bug的数量和bug ID则分别用余下的几列来表示。
  之后的目标是逐个排除每种bug类别背后的根本问题,首先从发生次数最频繁的开始。为了鼓励团队成员就这一话题展开交流,Scrum Master决定将这张Pareto表格贴在Scrum公告板与bug数量的旁边,并且每天对其进行更新。在每天早上的站立会议上,团队都会报告当前的bug情况,而新产生的bug都会按照其分类添加到该表格中。这种方式能够使团队更明显地意识到每日质量性能的变化情况,同时也是实现PDCA中的C——Check(检验)的一种良好方式。当问题被根除之后,这方面的bug应该至少在一周之内不复存在了。不过,某些时候还是会发生这些bug,而这也是需要学习的地方。
  举一个例子,该团队已经认识到了bug类别中有一种属于回归缺陷,即对软件的改动破坏了原本能够正常工作的特性。这种bug多数情况下发生在图形用户界面端,因为对这一部分进行自动化测试是非常困难的事。我们所找出的一个根本问题在于,初级程序员并不总是完全理解他们对代码的改动可能会造成的影响。对此问题的解决措施是在流程中加入一个新的步骤,在提交代码之前先让某个更资深的开发者进行代码复审。这一步骤大概只需要15分钟,但能够大幅降低回归缺陷出现的次数。此外还将对每次发布的bug数量进行每日评估(每天发布两次)。这种方式还能够提高初级开发者的技能水平。
  最终,所有的问题都得到了解决,结果是令人惊叹的:所有的问题都通过标准流程(在提交代码之前进行代码复审)得以一一根除。每日的bug数量直线下降,每个迭代周末能够提交的包括完整功能并且无bug的用户故事数量也在上升。3个月之后,该团队就从之前产生bug数量最多的困境中摇身一变,成为了整个项目中高质量、高效率团队的代名词。
  这种方式相比之前的方法显得更为精益。因为它对每日绩效(质量)和生产力(提交的用户故事数量)产生了直接的影响,并且为团队带来了新的操作标准。
  
图2:敏捷团队的性能指标示例
  将一个敏捷团队转变为学习团队
  经历过了以上两个示例之后,加上我从这次经历中所学到的经验,我将为你推荐一种将敏捷团队转变为精益和学习团队的路线图:
  对绩效进行评估,让它可为众人所见,并且每天都要对它展开讨论。
  我能够理解这一点对于某些非主流的敏捷教练来说是难以忍受的,但事实可能会令你感到沮丧:如果我们需要进行改进,那么首先要做的第一件事就是评估。此外,最重要的一点是,只有面对现实,才能进行深刻的学习。网络巨擎(谷歌、亚马逊、Twitter及Facebook)或者实践领导者(Etsy)都是这样做的:他们对每件事情都进行评估,如果他们仅仅关注于计算用户故事的点数,就不可能达到如今的绩效。在敏捷团队方面有个实际的例子可供参考:除了Sprint燃尽图之外,还要展示质量绩效(没有关闭的bug数量、每次发布的bug数量、每种类别的bug数量,等等)、客户满意度(例如对交付的用户故事按照总分10分进行评分),并且每一天都对燃尽图没有达到预期目标的原因进行分析。
  确保使用精益的方式表达问题
  对于某个问题的表达必须包含两个方面:所观察到的绩效和目标绩效。Pareto是一种将原始的bug进行分类处理的优秀工具,但还要专门进行分析,以理解每个类别是如何影响到绩效的。
  这种方式可以保证你已经清晰地为划分了问题的类型,并且从商业绩效的角度以正确的次序分别进行处理。
  当问题出现时逐一分析解决
  精益式解决问题方法的关键之一,就在于不要试图同时解决多个问题。你只需要专注于一个问题,理解它如何影响你的绩效指标,并确保你理解造成该问题的原因所在。
  进行校验
  很遗憾,根据我的经验来看,我们通常会倾向于忽略这一步骤。如果你的预估与现实不符、你的软件不能正常工作,那很好!你是否可以从中学到些什么?如果你所想象中会发生的事与实际发生的事产生了偏差,那这一段偏差就是可以从中进行学习的地方。这正是在第二个示例中的团队所做的事。正如Stephen J. Spear在他的著作《Chasing the Rabbit》中所写的一样,这是你的组织中的系统在向你发出的一种声音:“在我身上还有一些你所不了解的东西,但如果你愿意倾听,我就会告诉你。”团队正是这样才能够从工作与流程中快速地培养自己的专业技能,并真正地成为一支梦想中的团队。
  从敏捷到精益
  我从2004年开始成为一名敏捷实践者,而在过去的几年中,我的思维方式渐渐转为精益。正是它帮助我跨越了一些单纯依靠敏捷无法跨过的障碍。
  按我的经验来看,精益已经被证明是一种有效的手段,它能够帮助你超越敏捷,建立起一种持续改进的实践,并为团队带来直接的绩效提高和激励作用。而明确地区分bug与问题这一方式已经被证实是对持续改进的一大助力。
  如果你也开始了这一相同的过程,你是否能指出bug与问题之间有哪些关键的区别因素吗?

posted @ 2014-05-21 10:06 顺其自然EVO 阅读(198) | 评论 (0)编辑 收藏

Redis千万级的数据量的性能测试

从图中可以猜测到还会有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占用过多的连接)。

posted @ 2014-05-21 10:05 顺其自然EVO 阅读(251) | 评论 (0)编辑 收藏

Redis千万级的数据量的性能测试

从图中可以猜测到还会有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占用过多的连接)。

posted @ 2014-05-21 10:05 顺其自然EVO 阅读(186) | 评论 (0)编辑 收藏

基于云的测试系统经历

介绍
  任何特定软件即将发布并投入生产期间,其性能一直备受关注。尽管一软件已被用户证明如预期的正常运作(通过功能测试后),故障仍可能会发生,尤其当它无法承担用户生成的大量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秒。
  ▪在客户端,最终用户可能会遇到:在通过客户端系统获取在线服务时,云平台的用户负载过大,响应时间延迟。
  ▪比起那些更慢的互联网获取,通过使用一个更快的互联网连接,最终用户可以更快地获取在线服务

  结论
  由于本文的重点是性能测试的测试用例设计,一个展示这些测试用例是如何被用于执行的案例研究为本文提供了论点。很显然,正确的规划对保证任何性能测试的成功都非常关键。性能测试不应该基于“想要时”或“要求时”。性能测试的测试场景和测试用例需尽可能早地被定义和设计,就和其他类型的测试一样,比如功能测试。这将决定能否顺利执行性能测试,其中包括:性能测试工具的选择,测试环境的设置,如何做出性能衡量和分析应该做的选择,性能结果不符合指定准则时扩大云平台的行动计划,以及执行测试的时间和资源
  这些到位了,任何经过了严格性能测试的系统,一旦置于生产环境中,都能够应付日益增长的负载量,并且对服务其用户更稳定,更反应灵敏。

posted @ 2014-05-21 10:04 顺其自然EVO 阅读(191) | 评论 (0)编辑 收藏

Ant构建Java项目之第1篇

  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>

posted @ 2014-05-20 10:24 顺其自然EVO 阅读(168) | 评论 (0)编辑 收藏

Selenium webdriver如何拿到页面的加载时间

 这个问题与语言无关,对于现代浏览器来说,使用 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就可以了。
  下图说明了具体的指标参数的意义。这里就不啰嗦了。

posted @ 2014-05-20 10:23 顺其自然EVO 阅读(1041) | 评论 (1)编辑 收藏

使用模拟器和实际设备进行自动化测试

  移动测试的挑战


  在看移动测试的自动化工具前,你需要对与移动应用程序面临的挑战稍作了解。

  设备

  移动应用程序应该在你要求的设备上工作。

  移动应用程序必须在每个设备上都正常工作。

  移动设备必须为应用程序的运行时间进行测试。

  移动设备处理能力不同,内存有限,还必须考虑通信协议。

  应用

  新的操作系统版本和功能意味着开发人员建立了必须被测试的新的,更复杂的程序。

  多个构建常常时间很短,因此脚本执行往往不能完成。

  网络

  多种网络类型,必须进行测试,如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对象

对象识别的复杂度

容易

容易

中等

中等

对象维护工作



容易

中等

跨设备支持


中等

容易

容易

执行中的识别速度

中等

中等

中等


  结论
  通过在移动应用程序测试中使用自动化测试,测试团队可以在保持质量和减少将产品推向市场时间的同时降低成本。
  许多工具可用来支持移动设备自动化测试。选择正确的工具需要理解业务需求和移动测试独有的因素。
  权衡手机模拟器和真实设备的优劣,企业的最佳移动测试解决方案往往不是只选择其中一个,而是选择结合这两者。

posted @ 2014-05-20 10:22 顺其自然EVO 阅读(605) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 109 110 111 112 113 114 115 116 117 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜