此外,通过引入定时任务,也可以有效地利用Web服务器的空闲时间来处理后台任务。例如,通过Spring Batch Job来执行每日、每周或者每月的定时任务。如果需要多台机器去执行这些定时任务,可以引入Spring提供的Puppet来管理这些服务器。Puppet提供了可读性强的声明性语言来完成对机器的配置。
Map-Reduce
对于大数据的处理,自然可以引入Map-Reduce。为整个系统专门引入一个Map-Reduce层来处理数据是有必要的。相对于使用SQL数据库作为数据中心的方式,Map-Reduce对可伸缩性的支持更好。Map-Reduce可以与任务的定时机制结合起来。如下图所示:
平台层
Larson认为,大多数系统都是Web应用直接与数据库通信,但如果能加入一个平台层(Platform Layer),或许会更好。
首先,将平台与Web应用分离,使得它们可以独立地进行伸缩。例如需要添加一个新的API,就可以添加新的平台服务器,而无需增加Web服务器。要知道,在这样一个独立的物理分层架构中,不同层次对服务器的要求是不一样的。例如,对于数据库服务器而言,由于需要频繁地对磁盘进行I/O操作,因此应保证数据库服务器的IO性能,如尽量使用固态硬盘。而对于Web服务器而言,则对CPU的要求比较高,尽可能采用多核CPU。
其次,增加一个额外的平台层,可以有效地提高系统的可重用性。例如我们可以将一些与系统共有特性以及横切关注点的内容(如对缓存的支持,对数据库的访问等功能)抽取到平台层中,作为整个系统的基础设施(Infrastructure)。尤其对于产品线系统而言,这种架构可以更好地为多产品提供服务。
最后,这种架构也可能对跨团队开发带来好处。平台可以抽离出一些与产品无关的接口,从而隐藏其具体实现的细节。如果划分合理,并能设计出相对稳定的接口,就可以使得各个团队可以并行开发。例如可以专门成立平台团队,致力于对平台的实现以及优化。 最近,阅读了Will Larson的文章,感觉很有价值。作者分享了他在Yahoo!与Digg收获的设计可伸缩系统的架构经验。在我过往的架构经验中,由于主要参与开发企业软件系统,这种面向企业内部的软件系统通常不会有太大的负载量,太多的并发量,因而对于系统的可伸缩性考虑较少。大体而言,只要在系统部署上考虑集群以及负载均衡即可。本文给了我很多启发,现把本文的主要内容摘译出来,并结合自己对此的理解。
Larson首先认为,一个理想的系统,对于容量(Capacity)的增长应该与添加的硬件数是线性的关系。换言之,如果系统只有一台服务器,在增加了另一台同样的机器后,容量应该翻倍。以此类推。这种线性的容量伸缩方式,通常被称之为水平伸缩“Horizontal Scalability”。
在设计一个健壮的系统时,自然必须首要考虑失败的情况。Larson认为,一个理想的系统是当失去其中一台服务器的时候,系统不会崩溃。当然,对应而言,失去一台服务器也会导致容量的响应线性减少。这种情况通常被称为冗余“Redundancy”。
负载均衡
无论是水平伸缩还是冗余,都可以通过负载均衡来实现。负载均衡就好似一个协调请求的调停者,它会根据集群中机器的当前负载,合理的分配发往Web服务器的请求,以达到有效利用集群中各台机器资源的目的。显然,这种均衡器应该介于客户端与Web服务器之间,如下图所示:
本文提到了实现负载均衡的几种方法。其一是Smart Client,即将负载均衡的功能添加到数据库(以及缓存或服务)的客户端中。这是一种通过软件来实现负载均衡的方式,它的缺点是方案会比较复杂,不够健壮,也很难被重用(因为协调请求的逻辑会混杂在业务系统中)。对此,Larson在文章以排比的方式连续提出问题,以强化自己对此方案的不认可态度:
Is it attractive because it is the simplest solution? Usually, no. Is it seductive because it is the most robust? Sadly, no. Is it alluring because it’ll be easy to reuse? Tragically, no.
第二种方式是采用硬件负载均衡器,例如Citrix NetScaler。不过,购买硬件的费用不菲,通常是一些大型公司才会考虑此方案。
如果既不愿意承受Smart Client的痛苦,又不希望花费太多费用去购买硬件,那就可以采用一种混合(Hybird)的方式,称之为软件负载均衡器(Software Load Balancer)。Larson提到了HAProxy。它会运行在本地,需要负载均衡的服务都会在本地中得到均衡和协调。
缓存
为了减轻服务器的负载,还需要引入缓存。文章给出了常见的对缓存的分类,分别包括:预先计算结果(precalculating result,例如针对相关逻辑的前一天的访问量)、预先生成昂贵的索引(pre-generating expensive indexes,例如用户点击历史的推荐)以及在更快的后端存储频繁访问的数据的副本(例如Memcached)。
应用缓存
提供缓存的方式可以分为应用缓存和数据库缓存。此二者各擅胜场。应用缓存通常需要将处理缓存的代码显式地集成到应用代码中。这就有点像使用代理模式来为真实对象提供缓存。首先检查缓存中是否有需要的数据,如果有,就从缓存直接返回,否则再查询数据库。至于哪些值需要放到缓存中呢?有诸多算法,例如根据最近访问的,或者根据访问频率。使用Memcached的代码如下所示:
- key = "user.%s" % user_id
- user_blob = memcache.get(key)
- if user_blob is None:
- user = mysql.query("SELECT * FROM users WHERE user_id=\"%s\"", user_id)
- if user:
- memcache.set(key, json.dumps(user))
- return user
- else:
- return json.loads(user_blob)
|
数据库缓存
数据库缓存对于应用代码没有污染,一些天才的DBA甚至可以在不修改任何代码的情况下,通过数据库调优来改进系统性能。例如通过配置Cassandra行缓存。
内存缓存
为了提高性能,缓存通常是存储在内存中。常见的内存缓存包括Memcached和Redis。不过采用这种方式仍然需要合理的权衡。我们不可能一股脑儿的将所有数据都存放在内存中,虽然这会极大地改善性能,但比较起磁盘存储而言,RAM的代价更昂贵,同时还会影响系统的健壮性,因为内存中的数据没有持久化,容易丢失。正如之前提到的,我们应该将需要的数据放入缓存,通常的算法是least recently used,即LRU。
CDN
提高性能,降低Web服务器负载的另一种常见做法是将静态媒体放入CDN(Content Distribution Network)中。如下图所示:
CDN可以有效地分担Web服务器的压力,使得应用服务器可以专心致志地处理动态页面;同时,CDN还可以通过地理分布来提高响应请求的性能。在设置了CDN后,当系统接收到请求时,首先会询问CDN以获得请求中需要的静态媒体(通常会通过HTTP Header来配置CDN能够缓存的内容)。如果请求的内容不可用,CDN会查询服务器以获得该文件,并在CDN本地进行缓存,最后再提供给请求者。如果当前网站并不大,引入CDN的效果不明显时,可以考虑暂不使用CDN,在将来可以通过使用一些轻量级的HTTP服务器如Nginx,为静态媒体分出专门的子域名如static.domain.com来提供服务。
缓存失效
引入缓存所带来的问题是如何保证真实数据与缓存数据之间的一致性。这一问题通常被称之为缓存失效(Cache Invalidation)。从高屋建瓴的角度来讲,解决这一问题的办法无非即使更新缓存中的数据。一种做法是直接将新值写入缓存中(通常被称为write-through cache);另一种做法是简单地删除缓存中的值,在等到下一次读缓存值的时候再生成。
整体而言,要避免缓存实效,可以依赖于数据库缓存,或者为缓存数据添加有效期,又或者在实现应用程序逻辑时,尽量考虑避免此问题。例如不直接使用DELETE FROM a WHERE…来删除数据,而是先查询符合条件的数据,再使得缓存中对应的数据失效,继而根据其主键显式地删除这些行。
Off-Line处理
这篇文章还提到了Off-Line的处理方式,即通过引入消息队列的方式来处理请求。事实上,在大多数企业软件系统中,这种方式也是较为常见的做法。在我撰写的文章《案例分析:基于消息的分布式架构》中,较为详细地介绍了这种架构。在引入消息队列后,Web服务器会充当消息的发布者,而在消息队列的另一端可以根据需要提供消费者Consumer。如下图所示。对于Off-Line的任务是否执行完毕,通常可以通过轮询或回调的方式来获知。
为了更好地提高代码可读性,可以在公开的接口定义中明确地标示该任务是On-Line还是Off-Line。
引入Message Queue,可以极大地缓解Web服务器的压力,因为它可以将耗时较长的任务转到专门的机器上去执行。
经过自己总结和项目经理们探讨,认为项目或部门团队建设可分为三个等级:
一、乌合之众,强权政治(新手)
很多新手都会经历这样的过程,新组建的团队冲突不断,大家对当各种制度措施,报以反感。为保证执行力和项目成功,项目经理会选择强权压制,尤其是技术比较好的项目经理。大抵的逻辑是“我是老大并且我资深,要听我的”。最终的结果是大家对项目目标已经完全不感兴趣,一些冲突升级到个人情感冲突,项目经理左右突击,上蹿下跳,甚是辛苦,忙碌,确得不到大家的认可。
此时的项目经理至少需要做到两点,才有可能进入下个阶段,用杰克韦尔奇的两句话概况:
1、“在你成为领导以前,成功只同自己的成长有关。当你成为领导以后,成功都同别人的成长有关。”
2、“世界上的每一个人都想得到发言权和尊严,而且也应当得到”
所谓“发言权”,是指人们希望有机会说出他们的思想,拥有自己的观点、看法、获得被倾听的感受,无论他们的国籍、性别、年龄或者文化背景如何。
所谓“尊严”,是指人们本能地和自发地希望由于自己的工作、努力和个性而得到尊重。
这个阶段之所以命名为乌合之众,是因为大家对团队根本没有归属感,甚至厌弃团队,期望团队得到解散,或者团队目标达成时,并没有取得成就的感觉,而是有终于熬过来的感触。
二、尊重,民主社会 (老手)
在经历过挫折或是老前辈们的谆谆教导后,新手往往都能进入这个阶段。当然有些厉害的人有时也会自己跳到这个阶段。但是这个阶段里的人,也有高下之分。在这个阶段的人,往往可以带团队时,往往可以做到:
1、尊重,言路开明
不把人当做机器。制定计划,措施时,都可以征求的大家意见,当然计划定下来后,执行时是不能含糊的。
2、善用人才,培养人才
团队里有人才时,会使用授权等方式调用这些人的积极性,而不是幼稚的打压,并且在团队里没有人才时,能够积极选拔备选人员,并给予锻炼机会
3、分享荣誉
这个阶段的项目经理,在交流中,会摈弃掉“我怎么样,怎么样”,多使用“我们,我们团队怎么样”,尤其是在面对表扬和荣誉时。在项目组内也想方设法树立榜样,并且非常愿意这些人被自己的上级所获知,愿意为这些人谋个好前程。
4、坦诚
坦诚是相处的长远之计,而忽悠,画大饼这些手段只能短期效应,并在长期上让自己的人格受损。关于这点项目经理大多做得程度不一,有时说出一些不开心的事,是需要勇气的,例如在绩效沟通时。但是这个阶段的项目经理都了解它重要性。
5、团队信息透明
只有信息足够透明,大家才能够为项目出谋划策,才能有坦诚沟通的基础,大家才能对项目归属。“垄断信息,以显示自己领导的地位”是愚蠢的人才会干的事情
这个阶段之所以命名为民主社会,这个阶段的价值观是:民主计划,严格执行,有付出有回报,集体荣誉。第一个阶段到第二个阶段可能需要时间的积累,而第二个阶段到第三个阶段,有时却可望而不可达。
三、激情,燃烧军团 (高手)
激情团队的充分必要前提是,团队负责人是非常有激情的。这点很关键,一个打工者心态,没有把工作当成自己事业经营的人是不会带出有长久激情的团队。检视的原理:“看一下大家是不是为了同一个梦想而走到一起的”
要达成团队激情,至少具备以下几点:
1、老板风格,老板要有分享成功的决心,例如:股票,期权激励
2、企业文化,企业要有文化宣扬集体奋斗的精神,企业的使命价值观能够深入人心,得到强烈响应,此时企业的创新精神,将是从内而外的,从下而上的,大家集体思考,集体进步,集体创新。
3、有激情的中层,公司中层是企业的中流砥柱,如果每个中层是有激情的,扩散开来的影响力是很大的,反之,则激情容易变成口号。
这里典型的案例是sony的没落,从井深大的激情军团的消失,井深大倡导”工作保证本身就是一种强有力的激励“,把这种理念能够深植公司是多么可怕,激情可以创造出很多奇迹。
约翰·科特说过“如果你想建造一艘船,首先要做的不是去采集木材、加工木板和分派工作,而应该去唤起人们对广阔无垠大海的向往。“ 管理者的本质是获得追随的人,一个企业,一个团队如果能够拥有一批愿意追随公司成长的人,所产生的正向能量是无比巨大的。
这种境界的达到需要多方因素的促合,颇似于武侠里的天人合一,激情团队的管理将十分简单,保护这种激情,员工会很自主的进行自我管理。
当然实际工作中,以上每个阶段不孤立存在,可能会存在一些阶段的中间体。
相关链接:
项目实战笔记之一:高效会议的组织方法
项目实战笔记之二:风险管理
项目实战笔记之三:时间估算的三步曲
项目实战笔记之四:团队建设(尊重)
项目实战笔记之五:里程碑管理
【背景介绍】
NB公司的面试流程步骤多,严谨,正常情况下一个顺利的面试流程需经5个面试官的考核,真所谓过五关斩六将,能闯到最后一关者,绝非易事。----某公司的过来人如是说。
求职者:王小姐,毕业后一直从事软件测试,工作4年。
面试官:共5位,其中前3位为技术面,后2位为综合素质面。
【故事内容:面试回顾】
话说王小姐的面试还是比较顺利,用的是周六的时间,不用请假。虽早上7点多就开始准备,直到下午4点才面试完,但能在国内知名的NB公司面试,并闯入最后环节,当王小姐走出NB公司的大门,还是自我欣慰了一番,并自信的笑了笑。心想:NB公司的面试官确实个个都有不同的一面,问的问题有些还比较尖锐。说实在的,测试技术也就是那些,面试官非要纠缠一些细节。我只好……,这个策略也叫“兵来将挡,水来土掩”吧。
也就在王小姐离开公司的一会儿,按惯例,HR组织几个面试官碰在一起交流下彼此对王小姐的评价。
面试官1评价:沟通能力不错,整个过程没有不顺畅的地方。技术上没有发现明显的优势与劣势,但总觉得她的话不太符合逻辑。
下面是面试官1的经典回顾。
面试官1问:“工作过程中,是否曾主动总结过什么东西与他人分享?”
王小姐说:“有的。”
面试官1问:“是否有什么案例具体说说。”
王小姐说:“我安装配置过给公司内部使用的XX软件,由于配置复杂,当时写了一份总结,并上传到网上我的博客空间了。”
面试官1问:“是什么网站。”
王小姐说:“不记得了。”
面试官1心想,上传了博文,有不知道是什么网站的吗?一般情况下建立博客空间是要注册的。不太靠谱吧。
下面是面试官2对王小姐的面试评价:
1、工作主动,有一定的过程总结能力。例如:她从自带的旅行包里取出一份测试报告展示给我看,报告内容详细、清晰,并提出某某图表是她主动做的。
2、有点过于自信,或自我认识不足。问及做了几年测试后,有没有遇到什么技术上的困难,或哪些方面觉得还有待于提高,回答各方面都做得很好,没有遇到什么困难。我表示怀疑。
下面是面试官2的经典回顾。
面试官2问:“你认为做好软件测试工作,哪个环节的工作做好最重要?”
王小姐回答说:“每一个都很重要,每一个环节我都做过,包括测试计划,测试方案、用例设计,测试总结与报告等。”
面试官2心想,既然都做得好,于是继续问:“在多年的测试过程中是否有遇到偶发的Bug,是如何回归偶发Bug的”。
王小姐说:“可能运气好,真没遇到,发现的问题无偶发的并且开发都解决了。”
面试官2心想,这位王小姐,是神马,还是浮云,这显然不符合正常情况的软件研发过程逻辑。
轮到面试官3发表意见了,他略有所思,回忆了当时的面试场景。下面是他的经典回顾。
面试官3问道:“从事测试4年多来,是否有感到自己哪些方面比较欠缺的。”
王小姐说:“暂无感到有什么不足或缺点,工作上都挺顺利的。”
面试官3心想这个王小姐,心有顾虑,不太诚恳。于是现场出一个题目来考考她,拿出一张白纸,并在纸上画出一个日常常用到的软件界面,在明确需求的基础上,要她讲述测试的分析思路。
王小姐看了几眼,基本没作思考,便随口说了几个她所认为的测试思路。
面试官3心想,都是表面的几个测试点。从这点上来看,觉得她很一般,没有突出的特点。
面试官3继续问:“听你说,在公司各项工作开展都挺顺利的,也觉得自己没什么欠缺的,为什么还离职呢。”
王小姐回答说:“公司业绩不好,没有奖金发,一年了也未加过薪,这是重点。其次是看不到什么发展空间。”
对于王小姐回答的第1点,面试官3觉得可以理解,对于第2点有点好奇,于是追问道:“是什么原因使你认为看不到发展空间呢?”
王小姐回答说:“我的老板,即我的上司,是在公司工作了7-8年的老员工,在业务与技术上,自己明显是比不上的,他们老员工也比较稳,一般情况不会离职。而公司目前的发展未有其他管理岗位可提供。公司的测试部门还有另一个平台组,主要负责公共模块的测试,测试工具的开发,偏向测试开发,而自己这方面的技术水平又达不到。”
面试官3听了后,恍然大悟。
心里评价道:“工作不踏实,自命清高。回答问题不诚恳,自作聪明。”
【思路点拔】
三国时期的历史典故,杨修的鸡肋事件,本无其事,最后引火烧身,与本处的“聪明反被聪明误”案例,似有相似之处。抑或是杨修之死,还是本处的案例,告诉我们:
1、诚实。面试过程,是相互建立信任的过程,不少面试者为了掩盖自己的不足,往往会说一些谎言。当然作某些善意的谎言,只要不影响本质,面试官也不是不能接受的。
2、逻辑清晰。说话表达注意逻辑,问A问题,不能答B内容。软件测试是技术性工作,思路清晰,有逻辑的封闭性,这是基本的素质。例如本案例中提到的求职者主动上传了博文,却不知道博文位于何网站。
本故事面试场景中的一些地方,可能你也似曾相识,觉得那些地方求职者或面试官可以做得更好呢。
版权声明:本文出自 aux0 的51Testing软件测试博客:http://www.51testing.com/?26026
原创作品,转载时请务必以超链接形式标明本文原始出处、作者信息和本声明,否则将追究法律责任。
● 目的:保证需求质量
● 手段:针对需求开展测试设计
● 测试设计面临的挑战:
1、测试准则不确定(测试是比较预期结果与实际结果的过程,预期结果最了解的人群是开发、需求人员还是客户?答案未知,但是如果需求的质量更高些的话,会更利于更准确的知道预期结果)
2、测试无穷尽:要用少的用例覆盖尽可能多的需求,如何挑选合适的用例显得尤其重要
3、用例执行pass是否真正代表对应场景或功能就pass =>缺陷隐藏效应证明不一定,那么在挑选用例时如何做到,RBT会有所考虑
RBT是如何实现上面所提挑战的?
● 为什么要基于需求来开展测试?
1、导致软件失败的原因如下:
a)需求不完整
b)需求多变
c)需求缺少来自用户的实际输入
从而导致仅有60%~70%的需求交付量,且此其中50%左右的需求未被使用过,而开发团队针对这些未使用过的需求,投入了大量精力,存在一定程度的浪费。
2、BUG分析缺陷来自哪个阶段?=>60%来源于需求阶段(怎么有效区分BUG是哪个阶段?)
● RBT解决的是偏重型的测试问题(考虑项目的可适用性),是针对每条需求进行分析设计
● RBT倡导的思维是先测试,再构建
● RBT过程两大步:需求模糊度分析、因果图方法进行测试设计
1、需求模糊度分析
实际是分析需求是可测试的、可观察可触发的、结果是确定的(结果是确定的指:给定输入后,能准确得出其唯一的结果,对于输入A,结果为C,再次输入A,结果为B的情况则是不符合“结果是确定的”原则。当出现这种情况,则需求是肯定有问题的)
2、因果图方法进行测试设计,以下是几类设计方法的对比分析
a)根据用户实际使用场景、环境参数来设计用例的情况:30%左右的覆盖不乐观,且异常考虑不充分,依赖时间的场景无法覆盖
b)依据直觉进行设计的情况:依赖测试者经验,覆盖不确定,只能代表执行过的是OK,不能证明其完整覆盖度
c)组合测试设计的情况:所有场景组合全部覆盖,量太大
d)因果图方法设计的情况:借鉴了硬件领域的一些工程算法,覆盖率高
● RBT方法选择用例的标准:
1、体现变量间的各种逻辑关系
2、体现每个变量各种状态间的约束
3、考虑各节点的可观察性,如下面的例子
例子:
A、B、D、E全为T,C、F、G均为True,假定当A恒为False的缺陷存在时,直接通过对G的观察是无法发现此缺陷的,因为C、F是不可观察的
4、需测试哪些功能块
● RBT过程12步骤(12步记录不全)
1、分析为什么要做这个需求?(如同敏捷测试中要求一样,即:需求来自于哪里?用户是什么样的群体?基于什么原因提出这样的需求?要解决什么样的问题?有无其它可替代方案来解决?是否一定要做这样的需求?
2、用场景分析方法来分析需求的应用情况
3、进行模糊度分析,即:识别不清晰、不完整、疑惑点的地方(此点更期望是不了解需求的人来做,而非专家)
4、领域专家进行更深层次的审视
5、针对需求建模,理出所有业务逻辑,采用因果图方法
6、用工具检查逻辑不一致问题,可能是需求本身的问题,也可能是建模的问题
7、工具自动生成用例(此处的用例可以理解为是测试验证点,而非具体的测试数据)
8、确认生成的用例是否正确(此处有一个个人问题:既然自动生成的用例已经是很精简了,再进行评审怎么保证评审出的问题是否需要补充到用例的?=>答案:评审的目的一是确认是否正确理解了规则与需求,二是通过评审问题反向识别出需求遗漏的场景(如果可能,要求客户对需求进行review是最合适的)
9、设计编码阶段,用生成的用例进行验证
● RBT工具用途(记录了一些,不全)
1、自动生成测试用例
2、自动生成两张表单:因与果清单、规则VS用例覆盖率的对照表(“X”表示多个用例覆盖此规则,“#”表示1个用例覆盖此规则)
3、生成测试统计数据
4、自动反向生成较规范的需求文档,适用场景:a、review需求时发现的问题确认后,不会更新需求,通过自动生成更新得到全集;b、敏捷项目中适用,项目结束后形成需求与用例的匹配
5、生成用例过程中自动进行功能逻辑一致性校验,并给出提示,如同开发程序编译时的错误提示
6、维护过程会考虑对原有用例的最大程度复用
7、告诉你可优先执行哪些用例
8、支持快速设计(推荐在配置测试中使用,如移动领域测试环境支持验证,可生成基础用例)
9、可定义节点间的状态、约束,以便生成的用例是可执行或真实的组合,对于不可执行的用例前面会有“I”标识,点击后会显示原因
在没有使用版本控制的开发团体中,我所熟悉的一种常用开发方式是:多个开发人员共同负责一个软件的开发,每个人在各自的机器上有整个软件的拷贝,并对之实施编码,分别完成各自任务之后,再通过文本比对工具将各自机器上的不同版本的软件整合到一台机器上。
本文就这样的开发方式,提出在软件开发中出现的几个和版本控制密切相关的典型问题(但未必全面),同样也是需要通过版本控制来解决的问题,它们来源于实际开发过程中的切身体会,并经过总结和整理。
1、软件代码的一致性
软件的开发、维护和升级,往往是多个人共同协作的过程。不同人对同一个软件的不同部分同时做着修改,这种行为有时会出现彼此交叉的情况。由于同一软件在各自开发人员的机器上都有拷贝,软件的全部代码都暴露在每个开发人员面前,原则上他有权限可以不加限制地更改软件的任何部分。而当他们修改的内容属于公共部分,或者需要被其他人员所负责的部分调用时(软件各模块间的彼此依赖关系决定了这种情况是经常发生的),这种修改就属于交叉情况。此时,就有可能出现代码的不一致现象。比如:修改者在改动了某个公共函数的同时也修改了其调用接口,若其他人员没有得知此事,而在各自机器上仍调用原来版本的函数,则当整合时,就会出现错误。另一种更为严重的情况是,修改者决定废弃原有函数而另外编写一个新的函数,但他并未删除原有函数,这种情况即使最后的整合也可能不会被察觉,如果将这种一致性错误的纠正延迟到测试阶段,则会增加调试的难度,从而降低开发效率。为了始终保证代码的一致性,一种解决办法是,要求修改者每次修改后都通过某种方式告知同组其他人员,或者随时对软件做整合。但是这样,一方面会增加开发人员的负担,另一方面也降低了软件的开发效率。
2、软件内容的冗余问题
软件在各自开发人员的机器上都有拷贝,并且同一个开发人员在不同时期也会在本机保留当时的软件版本,也就是说,一台机器上还可能不止一个版本。这类似于一种信息的冗余。对于不同版本而言,其差别有时可能并不很大,如果说不必要的占用存储空间是一个次要问题的话,那么另一个问题可能更重要。随着时间的推移,开发人员可能对自己机器上的不同版本间具体差异的了解变得模糊不情,甚至忘记了当时为什么区分这些版本的原因,这会给整合带来麻烦。而且,如果需要同时维护多个版本,则对某个版本的改动可能需要反映到其余版本的对应处,很难保证这一过程不会出差错。还有一点,作为开发人员,有时即使知道自己机器上软件的某个版本可能不会再使用了,他也不会去删除(生怕万一需要从那里获取点什么),但是通常也不会再去维护或查看它,因此久而久之,这种“僵死之物”会在多台机器上“蔓延”。
3、软件过程的“事务性”
对于软件的某个版本,如果开发人员想要为其增添新的功能,或改善原有功能,而又担心会搅乱原来运行良好的软件。一种常用的办法,就是保留现有版本,另复制一个新的拷贝,并在新的副本上进行修改。这类似于一种事务处理,当将一系列操作做为一个事务时,如果中间某个操作出现偏差,则希望恢复到执行事务之前的状况。而当完成修改之后,开发人员该如何处理这两个副本呢?是在新的副本上继续新的开发,将之作为最新版本;还是将新的改动加入原有版本,删除新的副本。无论怎样,都可能会出现如下情况:如果软件运行正常,则出现2中提到的冗余情况;当删除修改前的版本后,又发现改动中有问题,但已无法恢复了;改动无误,将改动加入原有版本时,可能出现人为错误,导致软件运行出错;即使没有人为错误,这种做法也会给开发人员增加额外负担,一定程度的降低开发效率。重复上述过程则会出现多个类似的副本,此时,如何对待这些不同版本,将是开发人员需要面对的问题。而如果调试的过程中,发现确实有必要恢复到上一个版本,甚至上上个版本……,此时就不得不保留所有版本了。
4、软件开发的“并发性”
由于是多人共同开发一个软件,期间出现多人修改软件的同一部分,尤其是同时修改,有时是不可避免的。对于前者,具有良好编程习惯的人员的一种通常做法是,对他人的源程序进行修改时添加必要的注释,写明修改人,修改原因,修改日期等。但实际情况是,当修改内容很零散或修改过程很复杂时,注释很难写,或者代码被注释分割得支离破碎影响正常阅读,或者注释无法详细说明实际情况。而且,这种做法也增加了开发人员的负担:他需要在考虑代码逻辑的同时,兼顾如何写注释;而对于注释和代码的一致性也是他需要随时留意的问题,不能疏忽。因此,我认为这种措施在实际开发中,并未取得实质效果,是不必要的,事实上代码本身(而非注释)是最能说明问题的,而修改的记录应该置于代码之外的某处。而且,不论是否是同时修改,都需要考虑1所提到的一致性问题,需要及时进行人工的差异比较和整合以便形成一个统一的新版本。
5、软件代码的安全性
由于代码完全暴露于所有开发人员面前,任何人都可以增、删、改之。除了会造成1所提到的不一致问题外,从安全的角度来看,也是存在隐患的,这一点对于一个自主产权的长期开发的产品而言更是如此。即使是一般的项目开发,不同的人员其分工不同,允许别人可以不加限制地任意修改自己负责模块的代码(相当于所有人员都具有管理员身份),总是容易产生问题。对于共有模块更是如此,所有人都可以修改,一旦修改,则波及全体。
6、软件的整合
在软件的整合过程中,一般比较可靠的做法是使用文本比对工具辅助完成的。这种措施,有以下缺点:
● 可靠性,整合中的人为错误会影响软件的可靠性,有时这种错误很难察觉,可能编译没有问题,而在测试时却发现了问题。这种潜在的错误发现的时间越晚就越难以纠正。
● 效率,对于纯手工的整合即使熟练操作的人也是需要时间来完成的,而有些整合只是将两段代码拼接在一起,这一过程完全可以借助于某些自动机制。这可以大大节省时间,使开发人员可以专注于后续的开发任务。
目前,国内的很多公司,包括一些知名大公司,可能都还没有这个职位,但应会有这样一个角色的存在,比如这个角色落在测试经理或是测试主管的肩上。笔者不敢 称自己是一个专业的测试架构师,只是有一天发现业界有这个职位时,并对着职位描述的定义,发现自己很幸运地在不知不觉中做了一些这方面的事情。
对于架构,更具体一些指架构模式,如第6章介绍的关于测试对象分析的三层架构模式。一边是深不可测、充满挑战的技术与艺术的高度体现,一边是“又恐琼楼玉宇,高处不胜寒”的担忧。高深的东西如何平民化,即那些高调的架构,能不能具体应用到工程实践中,很好地达到预期,而不是成为束之高阁、脱离实际的一堆废话或模型。这里站在项目测试的实用角度,总 结工作中的经验与教训,提出架构设计的操作模型,如图4-9所示。从图中我们可以看到一个完整的测试架构设计过程包括以下几个阶段。
1、业务测试框架设计:它包括业务测试技术与流程管理两个部分,基本框架的设计离不开业务需求与公司流程体系。其表现形式可以是一种测试方法、一块代码程序、一系列的流程规范等。
2、提取测试需求:广义上理解,包括与测试工作相关的业务及非业务需求,只有有了需求(工作中出现的问题也可认为是一种需改进的需求),才可进一步完善框架。
3、决策/部署测试策略:为测试需求服务的一系列解决方案。
4、开发测试套件:具体解决测试需求的措施集,如测试用例集、脚本程序、测试工具等。
图4-9 测试架构设计过程示意图
这4个阶段,它们之间是相互作用,相互影响的。细心的读者也许已注意到,位于图中内侧的“提取测试需求”,它与测试框架的设计并不是一种直接关系,没错,它们之间的关系要通过后续的工作体现在框架中。可以理解为一个新的测试项目开始了,以新的测试需求为起点,通过部署测试策略,开发新特性的测试套件,来完善测试框架。如此往复,依托一个个测试项目,不断改进、壮大测试框架。以使后续的项目测试能重用测试框架的内容或方法,并使整个测试过程始终在有序可控的状态下进行,最终能以高质量且减少项目的整体测试时间来完成测试工作,这也是架构设计的最主要目的。
对这4个阶段,可以理解为它是一个系统级的最顶层划分,对于每一个阶段,它又可划分为不同的节点。其包含的意思及操作的方法,将在接下来的章节中进行详细讲述。
一个好的架构,只有在应用中收到实际的效果后,方显它的价值,比如节省了多少测试时间或提高了测试的全面性等。
主动向他人提需求,是一种架构能力的体现,从而影响开发、需求,甚至其他用户、市场部门为测试部门服务。测试架构设计,需重视过程,它是个不断发展的过程。架构必须由经验丰富的设计人员设计,很大程度上依赖于过去项目的成功与失败的经验。但是正因世界上万事万物都在不停地发展变化着,软件开发的方法、模式、具体项目的要求也不同。随着过程中遇到问题的不同,需要做出快速响应,并进行合适的调整,从而提高架构的应用性,丰富它的内涵。提升它应用的高度与广度,为它画上更大的外延,这也是符合事物的发展规律的。
14.2 性能测试结果分析方法
在14.1节中我们学习了对于性能测试数据有效性的判断,并且利用统计学知识与以往经验从中可以得到性能概况。另外,还可以根据几条经验规则对怀疑数据进行剔除。在本节中将讲解如何对现有有效的数据进行分析,并据此得到性能好与坏的结论,为编写性能测试报告做准备。
对性能测试结果进行分析需要依次进行以下几个步骤:
(1)判断影响性能的因素。
(2)运用隔离、对比等方法进行趋势判断。
(3)记录各个结果,发现规律。
14.2.1 判断影响性能的因素
判断影响Web应用性能的因素其实一般发生在性能测试的设计阶段,但列在这里也是适当的,因为:
在实际工作中,设计阶段可能对于影响因素考虑不足,导致有些因素没有考虑到。这种情况会令测试结果不完全,要增加测试的运行。
设计阶段也可能出现考虑影响因素过多的情况,这需要在测试数据中进行判断,从而将无关的因素去除。该情况下那些多余的测试结果并非没有益处,因为正是它们,使得性能测试工程师得以发现了无关因素。
在Web应用领域,影响性能的因素有用户数量、服务器性能(请见前面章节有关性能计数器的部分)、网络带宽、客户端软件配置等多种。由于这些因素是综合起作用的,它们对Web应用的影响可以组合出很多种情况,其中部分如表14-6所示。
表14-6 影响性能各因素的部分组合
情况编号 | 用户数量 | 服务器性能 | 网络带宽 | 客户端软件配置 |
1 | 变化 | 不变 | 不变 | 不变 |
2 | 变化 | 不变 | 变化 | 变化 |
3 | 变化 | 不变 | 不变 | 变化 |
可以知道,这样的组合还有很多种,如果都针对它们进行测试,在大多数情况下(时间、人力、软件发布要求等要求比较严格紧迫)是不可能完成的任务。因此,有必要使用隔离的方法进行精简。
不过,值得一提的是,对性能做出正确判断需要足够多的测试数据。
14.2.2 隔离与对比
隔离、对比是常见的生成、分析数据的方法。通俗地讲,隔离就是指固定其他的影响因素,只变化剩余那个影响因素的方法。对于表14-6的情况来说,我们只需要测试4种情况就可以了,即:
用户数量变化,其他因素不变的情况。
服务器性能变化,其他因素不变的情况。
网络带宽变化,其他因素不变的情况。
客户端软件配置变化,其他因素不变的情况。
这样一来,问题得到了简化,同时,各因素的影响规律也能够被发现。
并列是分析数据的方法,特别适用于将数据生成为图表的情况下。它可以分为纵向比较与横向比较。
【纵向比较】
所谓纵向比较就是在同一个影响因素数值变化、其他因素固定的情况下,将多次测试结果并列在一张图表当中进行分析,从而发现该因素对性能的影响规律。比如针对表14-6中的数据,可以将用户数量分别是100、1000、10000的时候制表进行比较,发现用户数量对于性能的影响规律。
【横向比较】
而横向比较则是将多次纵向比较的结果,并列在一张图表中,从中发现各因素之间的关系或者性能的变化趋势。这多用于判断性能的优化成果。比如针对表14-6中的数据,可以在优化前与优化后进行不同用户数量的测试,如果测试结果曲线变化明显不同,则可说明优化的效果好坏。
14.2.3 详实记录中间结论
详实记录中间结论对于分析性能测试数据是非常重要的。实际工作中,经常发生初始的结论与最终结论不一致的情况。在分析每张数据表格或者图之后,如果可能,我们都要记录下该图或者表格说明了什么问题,有什么疑问。通过这样的方式,测试工程师对于整个Web应用的性能图景会逐渐明晰,也有利于做出错误结论后的回溯,发现分析思路上的错误。
总之,对于性能测试结果的分析,要有认真负责的态度和细致科学的方法。有了它们,不难得出正确的结论。
14.3 性能测试报告编写技巧
在对结果进行分析并得出结论之后,性能测试工程师要把它们以文字报告的形式发送给相关人员。这就是性能测试报告。除了书面文字之外,可能的话,公司还会召集人员开专门的会议进行报告讲解和结果分析。所以,性能测试报告是性能测试工程师的工作成果,也是公司其他部门考察性能测试工程师能力的重要窗口,编写出一份优秀的报告对公司的决策以及个人的职业生涯都非常有益处。
14.3.1 什么是好的性能测试报告
实际工作中的性能测试报告,一般是以Word/PDF格式文档或者电子邮件形式存在。而测试报告的读者,一般是整个项目组的管理者甚至更高层面、相关同事比如开发人员等,他们并不一定具备多少测试背景知识,因此,测试报告要尽量避免测试术语,要用容易理解的话语进行叙述。另外,它不应该是性能测试结果的简单罗列:因为读者是上级或者其他同事,他们没有多少时间来关心测试的具体细节,而只关心报告中测试结论是否合理以及结论的内容。这是需要性能测试工程师注意的原则问题,即不能从自己出发来写报告,而应该为报告的读者考虑。
根据这样的原则,要完成一份好的性能测试报告,最好做到如下几点:
提交报告的时机。
可以与测试主管就报告进行讨论。
有效地总结概括测试数据。
报告应该清楚易读,结合图表,但不能滥用图表。
报告要具备较强的逻辑性。
报告要具有层次感,几个部分区分明显、清楚。
测试报告一般分为测试目的、测试方法、测试数据概括总结、测试结果分析、结论这几大部分。在实际工作中的要求不尽相同,有的公司会有自己的模板,因此在文档结构上并无一定之规。但内容方面,如果能做到如上几点,编写出一份很好的性能测试报告就不是困难的。
在下面几节中,本书将一一介绍如上几个规则。
14.3.2 提交报告时机
与功能测试等不同,性能测试在整个Web应用的开发过程中并不是连续进行的,因此性能测试报告一般只会在几个时间点附近(比如某阶段结束前)才能让有限的读者看到。这容易给人以一种印象,性能测试并不如功能测试那样重要,如果时间紧迫,甚至不用很系统地进行。这就会影响到性能测试工程师的成就感和积极性。因此,性能测试工程师有必要创建一种性能测试持续存在的氛围。这样做有如下几个益处:
(1)培养同事对于性能测试的关注,普及性能测试的一些知识。这有助于测试报告的读者更好地理解性能测试的过程与测试报告的内容。由于日常工作中主动介绍性能测试知识显得比较突兀,根据实际情况,可以选择在测试部门会议之中选取短暂的时间介绍一些性能测试的理念。
(2)利于项目组内团结协作精神的培养。分享自己可以使人获得更多。比如,在开发人员刚刚修改完一些代码的时候,性能测试工程师不妨做一次小小的测试,如果比之前性能有所改进,就可以将结果用电子邮件的方式,不那么正式地发出来,同时还可以将性能测试数据放置于项目组内的服务器之中共享给所有成员。通过这样的方式,开发人员可以得到性能改善的好消息,互相鼓励,性能测试工程师的工作也让整个项目组看到,喜欢钻研的同事还可以到服务器共享中查看数据,性能测试工程师或许就能获得更好的反馈。
总之,提交报告的时机需要掌握,有如下技巧:
正式的性能测试结束后,要尽快发送整理好的测试报告,供决策、优化之用,以体现效率。
在两次正式性能测试之间,可以执行若干轻量级的性能测试,将改善的地方非正式地通知全组,以普及性能测试常识、激励同事与自己,提高团队精神。
14.3.3 与测试主管的讨论
前文提到,性能测试报告的读者是其他同事、部门甚至更高级别的领导,因此在发送报告之前,有必要与测试主管就报告内容进行讨论。通过讨论,至少可以获得如下的信息:
(1)发现问题。测试主管一般来说测试经验更为丰富,遇到和解决过的问题较多,因此他/她可能会发现现有报告的问题,进而提出改进的意见。
(2)使得报告表达更清晰易懂。总体说来,测试主管与其他同事、部门乃至更高级别领导沟通机会较多,对于报告潜在的读者了解更深入,熟悉他们的阅读习惯与表达方式。如果有了更详实的读者信息,那么报告做有针对性的修改,会更清晰易懂。
(3)增加工作交流的机会。在一个团队当中,信息共享是很重要的,与测试主管的讨论有助于主管了解当前的工作,可以为性能测试工程师解决一些困难。
总之,多与测试主管进行工作上的讨论,对于一名初级性能测试工程师的成长是很有裨益的。
14.3.4 有效总结测试数据
有效地总结测试数据包含如下几个要点:
(1)在测试报告的内容中,测试数据不能分散在各个部分当中,而应该单独列为文档的某一部分。这样的安排可以使得文档结构更加清晰,读者在阅读测试数据的时候更加专注数据本身。
(2)对于测试数据,不可能将所有的数据都列于测试报告之中,可以将最能支持结论的数据列出一行并说明各数值的代表含义。同时,必须列出获取测试数据的方法,用尽可能简单的语言陈述清楚。
对于报告中的测试数据,我们需要掌握的原则就是它必须真实,并且能够有力地支持结论。测试数据与测试方法部分一般放置于报告的前半部分。
14.3.5 测试报告与图表的结合
前文多次提到测试报告要清晰易读,而图表就是增强可读性的一种有效方式。对于枯燥的数据来说,人们很难从数字中快速发现规律和趋势,而一旦将数据转换成图表,情况则会明显不同,趋势往往很直白。另外,颜色搭配合适的图表相对更容易吸引读者的关注。
【图表的副作用】
但是,需要注意的是,图表不是越多越好,因为那样的话单个图表所能吸引的关注就会被平均分配,最后降低到文字的水平甚至更低,这里边或许也有所谓"审美疲劳"的因素。因此,图表不在于多,在于精,在于支持结论,说明问题。
在Excel中将数据转换为图是非常容易的,14.3.6节中我们将介绍这样的方法。
14.3.6 在Excel中为数据生成图
在Excel中为数据生成图表的方法实际上利用了Office Web Component组件的功能,它默认是与Office一起安装在硬盘中的。如果在控制面板中没有发现该组件,可以在微软官方网站免费下载。
下面笔者通过简单的步骤,为表14-7中某Web应用各栏目首页的6次响应时间数据生成图。
表14-7 某次性能测试的响应时间数据
请求频道首页 | 响应时间(秒) |
网站首页 | 7.3 6.8 7.1 6.9 7.0 8.5 |
新闻栏目首页 | 8.5 8.4 8.0 7.8 7.9 8.3 |
论坛栏目首页 | 9.8 9.5 9.4 9.0 9.4 9.6 |
联系我们栏目首页 | 3.2 3.2 3.3 3.2 3.2 3.3 |
产品栏目首页 | 4.5 4.6 4.3 4.5 5.0 5.0 |
将上述的数据输入Excel的一个工作表,并全部选择数据与说明的单元格,如图14-7所示。
图14-7 在Excel中选择待生成图的数据表
【其他数据文件格式与Excel】
在实际工作中,测试结果绝大多数情况并不是Excel默认的xls文件,而以txt、log、csv为后缀名的文本文件居多。这是因为,这些文件没有附加的格式信息,生成容易并且相对快速。那么,这些文件中的数据是否也可以在Excel中生成图表呢?答案是肯定的。利用Excel的“文件”|“打开”菜单,选择打开文件类型为“文本文件”,就可以将很多使用Tab键、空格或者逗号对测试数据进行分隔的文本文件导入到Excel的工作表中,非常方便。
选择完毕后选择“插入”|“图表”菜单,即可以打开生成图表的向导,如图14-8所示。另外,在导航菜单中也可以单击图14-9中说明文字指向的“图表向导”(Graph)图标按钮达到相同的目的。
图表向导由4个步骤的设置对话框所组成,第1步需要确定的是图表的类型,界面如图14-10所示。
这里列出了日常工作中应用的绝大多数类型,如果有需要,也可以自定义新的图表类型。
【图表类型的选择】
不同类型的图表,适合于表现不同的数据关系。因此,在报告中应用正确的图表有利于表达与支持报告的结论。在性能测试领域,一般来说折线图适合表达响应时间等数值越小越好的数据;柱形图、条形图适合表达并发用户等数值越大越好的数据;饼图适合表达Web应用终端用户信息,比如浏览器版本、IP分布等;XY散点图适合表达整个领域各组成元素的同一类数据等。
图14-8 通过菜单打开图表向导
图14-9 通过导航条图标打开图表向导
图14-10 图表向导第1步:选择类型
在本节,笔者选择折线图来表现表14-6中的数据,因此,在图14-10中“图表类型”列表框中选择“折线图”,并在右边的“子图表类型”选项区域中选择默认的数据点折线图,单击“下一步”按钮,对话框显示界面如图14-11所示。
图14-11 图表源数据的选择
图14-11中的对话框需要使用者选择哪些数据用于生成图表,由于在前面的步骤中,我们已经将数据和说明选择好,因此这里一般不需要做改变。另外,通过单击“系列”标签,可以进一步增添或者删除数据系列(在此处的例子当中,就是图14-7中的任1行数据)。
单击“下一步”按钮,进入图表向导的第3个步骤:设置图表选项。在图14-12所示的对话框中,可以对图表上额外的说明信息进行自定义,其中用处较大的有如下几个设置。
图14-12 图表选项的设置
标题标签中的图表标题与X、Y轴标题,可以为整个图表起名字,并且对X、Y轴的数据进行说明、列出数值单位。
网格线标签中的显示网格线功能,使图表中各数值有公共参照物,利于比较。
选中数据标志标签中的各选项,可以使图表中线上各点附带上数值和说明。
数据表中显示数据表选项,可以将源表与由此生成的图表显示在一起。
依据实际的需要可以在这个步骤进行设置。感兴趣的读者可以亲自试验。
继续单击“下一步”按钮,将进入图表向导的最后一个步骤:图表位置的设置。它规定了图表是单独存在于一张Excel的新工作表,还是与源数据表格同处于一个工作表。我们在这里保持默认选择,即存在于当前工作表之中,如图14-13所示。
图14-13 设置图表的插入位置
单击“完成”按钮,将完成图表向导的设置。生成的图表如图14-14所示。如果打算更改图表中各说明文字的大小与字体,可以双击图片空白处,以打开“图例格式”对话框进行更改,如图14-15所示。
需要说明的是,本书所举出的这个例子是以Office 2003中的Excel为例的,在Office 2007的Excel表中,界面基本类似,就不再赘述了。
图14-14 最终生成的折线图效果
图14-15 对图表中的文字设置图例格式
14.4 本章小结
在本章中,我们学习了编写一份好的测试结果报告需要注意哪些问题。它们分别是:
首先要能判断测试数据的准确性。根据本章介绍的几种经验规则对数据进行筛选。
预先估计性能测试数据的大致状况。有了大致性能好坏的估计,对于报告结论就会有较清晰的认识。性能的大致信息可以通过本章介绍的一些统计学小知识来 获得。
对性能测试报告进行细致的分析。
讲究技巧、注重逻辑性和易读性,通过文字、数据与图表的有机结合,编写测试报告。
与测试经理和其他相关人员进行沟通,最终完成测试报告。
通过以上这几个步骤,结合工作中的实践经验,相信读者一定能够完成一份不错的性能测试报告,为本轮性能测试的最后步骤,性能优化过程打下坚实的基础。
(连载完)
相关链接:
捉虫记--大容量Web应用性能测试与LoadRunner实战(连载一)
捉虫记--大容量Web应用性能测试与LoadRunner实战(连载二)
捉虫记--大容量Web应用性能测试与LoadRunner实战(连载三)
捉虫记--大容量Web应用性能测试与LoadRunner实战(连载四)
捉虫记--大容量Web应用性能测试与LoadRunner实战(连载五)
捉虫记--大容量Web应用性能测试与LoadRunner实战(连载六)
捉虫记--大容量Web应用性能测试与LoadRunner实战(连载七)
采用Appium进行自动化的功能性测试最酷的一点是,你可以使用具有最适合你的测试工具的任何一门语言来写你的测试代码。大家选择最多的一个测试编程语言就是Python。 使用Appium和Python为iOS和Android应用编写测试代码非常容易。
在这篇博文中我们将详细讲解使用Appium下的Python编写的测试的例子代码对一个iOS的样例应用进行测试所涉及的各个步骤,而对Android应用进行测试所需的步骤与此非常类似。
开始,先自https://github.com/appium/appiumfork并clone Appium,然后按照安装指南,在你的机器上安装好Appium。
我还需要安装Appium的所有依赖并对样例apps进行编译。在Appium的工作目录下运行下列命令即可完成此任务:
编译完成后,就可以运行下面的命令启动Appium了:
现在,Appium已经运行起来了,然后就切换当前目录到sample-code/examples/python。接着使用pip命令安装所有依赖库(如果不是在虚拟环境virtualenv之下,你就需要使用sudo命令):
$ pip install -r requirements.txt |
接下来运行样例测试:
既然安装完所需软件并运行了测试代码,大致了解了Appium的工作过程,现在让我们进一步详细看看刚才运行的样例测试代码。该测试先是启动了样例应用,然后在几个输入框中填写了一些内容,最后对运行结果和所期望的结果进行了比对。首先,我们创建了测试类及其setUp方法:
classTestSequenceFunctions(unittest.TestCase): defsetUp(self): app=os.path.join(os.path.dirname(__file__), '../../apps/TestApp/build/Release-iphonesimulator', 'TestApp.app') app=os.path.abspath(app) self.driver=webdriver.Remote( command_executor='http://127.0.0.1:4723/wd/hub', desired_capabilities={ 'browserName':'iOS', 'platform':'Mac', 'version':'6.0', 'app': app }) self._values=[] |
“desired_capabilities”参数用来指定运行平台(iOS 6.0)以及我们想测试的应用。接下来我们还添加了一个tearDown方法,在每个测试完成后发送了退出命令:
deftearDown(self): self.driver.quit() |
最后,我们定义了用于填写form的辅助方法和主测试方法:
def_populate(self): # populate text fields with two random number elems=self.driver.find_elements_by_tag_name('textField') foreleminelems: rndNum=randint(0,10) elem.send_keys(rndNum) self._values.append(rndNum) deftest_ui_computation(self): # populate text fields with values self._populate() # trigger computation by using the button buttons=self.driver.find_elements_by_tag_name("button") buttons[0].click() # is sum equal ? texts=self.driver.find_elements_by_tag_name("staticText") self.assertEqual(int(texts[0].text),self._values[0]+self._values[1]) |
就是这样啦!Appium的样例测试代码中还有许多Python的例子。如果你对使用Nose和Python来运行Appium测试有任何问题或看法,烦请告知。
本文转载自:http://www.oschina.net/translate/automated-mobile-app-testing-with-python-and-nose
摘要: Oracle提供了索引监控特性来判断索引是否被使用。在Oracle 10g中,收集统计信息会使得索引被监控,在Oracle 11g中该现象不复存在。尽管如此,该方式仅提供的是索引是否被使用。索引被使用的频率未能得以体现。下面的脚本将得到索引的使用率,可以很好的度量索引的使用情况以及根据这个值来判断当前的这些索引是否可以被移除或改进。 1、索引使用频率报告--运行环境SQL> select ...
阅读全文
关于如何在同一台电脑上运行多个操作系统的文章数不胜数,比如有的文章介绍了如何同时安装Windows和Linux,有的文章介绍了如何同时安装Windows和OS X,还有一些其他的文章。但是,当你想卸载其中的某个操作系统,你应该怎么办呢?下面,我们就介绍一下你安装了“Windows+Linux”双系统后,如何卸载Windows或Linux。
这个过程其实非常简单,但很多人安装双系统后第一次遇到这类问题时总会向我们求助,因此我们决定把方法写在这里,以便大家能够很容易看到。当你想卸载某个操作系统时,只需要找到它在哪里,然后把对应的分区删除就可以了。当然,不同的操作系统操作起来可能不太一样,所以我们给出三种解决办法。
注意:在开始操作之前,一定要备份你要保留的那个操作系统。因为,一旦你操作失误,很有可能就会删错系统,后果会相当相当严重。
保留Windows删除Linux
如果你想将Linux从机器中删除,只保留Windows,你需要进行以下几步操作:
1、从开始菜单(或开始屏幕)找到“Disk Management”(磁盘管理工具)并启动.
2、找到Linux分区。在Windows下无法识别Linux分区,所以,你需要按照驱动器和分区大小去判断,确认好以后继续下面的步骤。
3、右键选好的分区,然后选择“删除卷”,这将会把分区删除成自由空间,如果你再选择自由空间,选择删除卷,就会变成未分配空间。
4、在Windows分区上右键,选择“扩展卷”,扩展它以填补删除Linux所留下的自由空间。
5、最后,插入Windows恢复光盘(或恢复USB驱动器),并从它启动。选择“修复计算机”,去“疑难解答”,然后输入一个命令提示符。键入以下命令
这将删除Linux的bootloader和恢复Windows'。
6、重新启动你的电脑,你会发现,它直接引导进入Windows,不会有Linux分区。
如果你设置了双启动不同或把一个单独的硬盘驱动器上的Linux,又或者有其他的操作系统在驱动器上的,操作方式可能会略有不同。但对于大多数人来说,这些指令就足够了。
保留 OS X 并移除 Windows 或 Linux
如果你在用 Mac,删除其它分区非常简易。同样的,假设你的分区都在同一块硬盘上。
更新:读者 MartyF81 指出 ,最好的卸载 Windows 的方法就是使用 Boot Camp 内置的卸载器。你只需打开 Boot Camp 助理,并跟随提示逐步完成。
若需要移除 Linux 分区(或者你在 Hackintosh) 上,你需要做:
1、打开“/应用/实用工具”中的“磁盘工具”。
2、在左侧面板上点击你的硬盘(硬盘,而非分区),并进入“分区”分页。找到要移除的 Windows 或 Linux 分区(你可能在创建时添加了卷)。
3、点击你要移除的分区,然后点击窗口底部的小减号按钮。这样分区将从你的系统中移除。
4、点击你的 Mac 分区的一角并下拉,这样它将占据出现的自由空间。完成操作后点击应用。
你的 Mac 可能会花一点时间完成一些必要的步骤,当它结束后,你的系统将恢复原来的 Macintosh。如果你的系统中安装了 rEFIt,你可以不管它——这不会损害任何东西——不过你只需要 删除几个文件就可以移除它。
保留 Linux 并删除 Windows
如果你喜爱冒险,决定全部时间都是用 Linux,那么你要做的事非常简单。发行版和你特别安装版的说明可能有些不同,但对于传统 Ubuntu 安装,应该类似于下面:
1、插入你所用 Linux 发行版的 Live CD 或 USB 并启动其分区管理器(例如 Gparted)。在 Gparted 的菜单中找到你的 Windows 分区——它将被列为 NTFS 分区。
2、右键点击 Windows 分区,在菜单中选择“删除”。你的电脑中可能还有其它与 Windows 相关的分区,如 “System Reserved” 和恢复分区。要是愿意,你也可以删除这些分区(但请在删除恢复分区前确定你有恢复盘)
3、右键点击你的 Linux 分区,选择“调整/移动”。调整它的大小,以使用你硬盘上的自由空间。
4、点击工具栏上的“确认所有操作”按钮,执行所选任务。。它可能警告你电脑将无法启动,但对多数 Linux 安装这都不成问题(如果有问题,查阅 此文以修复)。可能要耗些时间,没办法。
结束之后,你的硬盘里应该就只剩下Linux系统了。这时启动菜单中还会有些Windows系统痕迹,不删掉也没什么影响,但如果你想把这些痕迹清除,你可以在Linux中启动“终端”,并运行:
这样就可以把Windows的痕迹清除了。
就像我们说过的那样,每一个双系统都“跟雪花一样美丽且唯一”,所以在不同的环境下操作步骤也不尽然与我们提到的这几种一模一样,你需要酌情处理。希望我们的文章能够给你带去帮助。
结语:一定一定不要忘记先备份,祝你好运!