做一个快乐、自由的公主!

发布新日志

  • 一个网页通用的测试用例(借鉴他人的保存,加注释)

    green_star 发布于 2014-09-30 10:15:14

    具体需求: 有一个登陆页面, (假如上面有2个textbox, 一个提交按钮。 请针对这个页面设计30个以上的test case.)
      此题的考察目的: 面试者是否熟悉各种测试方法,是否有丰富的Web测试经验, 是否了解Web开发,以及设计Test case的能力
      这个题目还是相当有难度的, 一般的人很难把这个题目回答好。
      首先,你要了解用户的需求,比如这个登录界面应该是弹出窗口式的,还是直接在网页里面。对用户名的长度,和密码的强度(就是是不是必须多少位,大小写,特殊字符混搭)等。还有比如用户对界面的美观是不是有特殊的要求?(即是否要进行UI测试)。剩下的就是设计用例了 ,等价类,边界值等等。
      请你记住一点,任何测试,不管测什么都是从了解需求开始的。
      功能测试(Function test)
      0. 什么都不输入,点击提交按钮,看提示信息。(非空检查)
      1.输入正确的用户名和密码,点击提交按钮,验证是否能正确登录。(正常输入)
      2.输入错误的用户名或者密码, 验证登录会失败,并且提示相应的错误信息。(错误校验)
      3.登录成功后能否能否跳转到正确的页面(低)
      4.用户名和密码,如果太短或者太长,应该怎么处理(安全性,密码太短时是否有提示)
      5.用户名和密码,中有特殊字符(比如空格),和其他非英文的情况(是否做了过滤)
      6.记住用户名的功能
      7.登陆失败后,不能记录密码的功能
      8.用户名和密码前后有空格的处理
      9.密码是否加密显示(星号圆点等)
      10.牵扯到验证码的,还要考虑文字是否扭曲过度导致辨认难度大,考虑颜色(色盲使用者),刷新或换一个按钮是否好用
      11.登录页面中的注册、忘记密码,登出用另一帐号登陆等链接是否正确
      12.输入密码的时候,大写键盘开启的时候要有提示信息。
      界面测试(UI Test)
      1.布局是否合理,2个testbox 和一个按钮是否对齐
      2.testbox和按钮的长度,高度是否复合要求
      3. 界面的设计风格是否与UI的设计风格统一
      4. 界面中的文字简洁易懂,没有错别字。
      性能测试(performance test)
      1.打开登录页面,需要几秒
      2.输入正确的用户名和密码后,登录成功跳转到新页面,不超过5秒
      安全性测试(Security test)
      1.登录成功后生成的Cookie,是否是httponly (否则容易被脚本盗取)
      2.用户名和密码是否通过加密的方式,发送给Web服务器
      3.用户名和密码的验证,应该是用服务器端验证, 而不能单单是在客户端用javascript验证
      4.用户名和密码的输入框,应该屏蔽SQL 注入攻击
      5.用户名和密码的的输入框,应该禁止输入脚本 (防止XSS攻击)
      6.错误登陆的次数限制(防止暴力破解)
      7. 考虑是否支持多用户在同一机器上登录;
      8. 考虑一用户在多台机器上登录
      可用性测试(Usability Test)
      1. 是否可以全用键盘操作,是否有快捷键
      2. 输入用户名,密码后按回车,是否可以登陆
      3. 输入框能否可以以Tab键切换
      兼容性测试(Compatibility Test)
      1.主流的浏览器下能否显示正常已经功能正常(IE,6,7,8,9, Firefox, Chrome, Safari,等)
      2.不同的平台是否能正常工作,比如Windows, Mac
      3.移动设备上是否正常工作,比如Iphone, Andriod
      4.不同的分辨率
      本地化测试 (Localization test)
      1. 不同语言环境下,页面的显示是否正确。
      软件辅助性测试 (Accessibility test)
      软件辅助功能测试是指测试软件是否向残疾用户提供足够的辅助功能
      1. 高对比度下能否显示正常 (视力不好的人使用)
  • 如何更好的招聘软件测试人员?

    zzzmmmkkk 发布于 2013-05-18 17:02:54

    以前就有过一些招聘的经历,自己也面试过几次,碰到过各种各样的应聘者,也碰到过各种各样的面试官,关于招聘和面试也总结一些自己的心得。

    先说招聘吧!我觉得有几点是比较重要的:

    1. 不太去关注答案,应该更关注应聘者回答问题的思路及方法;

    2. 不要太关注工作经历,而更多的是经验;

    3. 面试过程最好更轻松随意一些,应聘者更自然和真实的表现才能了解他们更真实的东西。

    面试问题二三事

       我不是透露各大IT公司面试题的,而是说说面试中都会问到什么样的问题,总结来看,无非是在操作技能,知识面,工作经验,工作能力及沟通水平几方面做考察。但是,很多面试官和应聘者都不明白哪方面应该是面试中考察的重点。

    1. 操作技能

       如果你会被问到vi的一些命令没答上来,linux中如何查看进程,如何创建目录难倒你了,其他表现都很不错,面试官因为这个否定了你,这只能说明他们不知道操作技能意味着什么。我觉得,只要google或百度一搜索就可以找到答案,没有必要去记住它,如果每天都在用,自然而然就记住了,一年不用,谁都会忘记,但是到时候再需要的时候,又能轻松重拾。我们可以把这些常用的操作存到个人笔记中,Evernote,有道云笔记都是好选择,可以速查。

    2. 知识

       知识是一个人善于学习和认知的体现,可能是一些概念和理论基础。知道怎么做,那是操作技能,知道为什么这样做,才是知识。知识越丰富的人也才意味着对问题的认识才会越深入,知其然并知其所以然。也许,知道怎么做就足以应付工作了,但是当需要对更复杂问题进行处理的时候,光知道如何操作就难以应付了。就好比一个测试新人,提交bug的时候多是只说明了现象,而测试经验丰富的人会分析下出现这个bug的原因和条件,可以给开发人员一些提示,更快的定位问题。但是一定要给出有把握的分析,否则可能会误导开发人员。这里的经验其实就是知识的积累,积累的越多经验也就越丰富,在分析问题解决问题时也才更快速。

    3. 工作经验

       经验不等同于经历,只能说没有经历过的人肯定没有经验。我觉得,经验=知识+经历,对自己所做过的事情有所思考,并逐步学习积累个中知识,理顺前因后果,才能成为经验。经验是对所掌握知识的运用和驾驭。面试官可以问问,工作中你遇到过什么难以解决的问题?当时又是如何处理的?给一道即兴发挥的用例设计题,或者如何设计测试体系的。

    4. 潜力

       任何成功的人光有前面的三条:操作能力,知识,经验远远不够,还有更重要的潜力。潜力可能包括态度,工作方式,思维方式,做事风格及分析问题解决问题的能力等,而且这些软实力至关重要,决定了他能做的有多好,前面3条只能代表他能做什么。

       所以,对于一个应届毕业生来说,可能前面三条都不具备,不能说这个人没有能力,只要有端正的态度,良好的学习能力,沟通能力,总结能力,分析定位解决问题等方面的能力,获得大家的认可是迟早的事。而对于一个老手,如果缺乏知识及工作经验的话,肯定就是最后一条没有做到位。

       不容质疑,这四点具备的人才能真正算是一名优秀的测试人员,当然对于其他行当的人来说,这4点一样重要。他们不是独立的,是相辅相成的,有潜力的人一定可以更快的学到知识,积累到经验,通过知识和经验的积累又会反过来提高能力,增强潜能。所以,我的观点是面试官应该更关注潜能,这样招聘到的人才能更好的服务于企业。当然,如果像富士康一样,只想找会操作的人,没必要为他的潜能支付更多的报酬,这是个例外。在IT企业里,我想企业都是求贤若渴的吧?

    如何成功的面试?

    1. 如果光问一些操作上的东西,而忽视了应聘者其他方面,完完全全算是一次失败的面试;

    2. 如果面试只是问了一些工作经验和相关知识,只能算是了解了这个人做过什么和知道什么,算成功了一半;

    3. 只有更深入的了解他的潜能,对于未做过的事未解决过的问题,他的处理思路,思考方法以及对待这个问题的态度,才真正决定他还可以做什么。这样才算是一次成功的面试。

    4. 另外,是否遇到过这样的面试官,如果应聘者每个问题回答的都很好,他不甘心,非要出个难题难倒你,来证明他有多牛,应聘者回家告诉他的朋友今天又被BS了。其实没有必要,因为我们面试的目的是要应聘者证明他的实力,通过面试来找到他们的亮点和长处。


    ===========================

    zzzmmmkkk,本名赵敏科,6年测试经验,从事过多年功能测试,性能测试及自动化测试,乐于分享。

    不定期发布有关测试技术文章,测试经验分享,测试思考和问题探讨

    加入zzzmmmkkk,可以:

    1. 请在微信添加好友->搜索公众账号里查找zzzmmmkkk

    2. 或者点击本文右上角按钮后选择关注公众账号

    ===========================


  • 发现的bug不能重现怎么办?

    zzzmmmkkk 发布于 2013-05-30 20:57:08

             微博上抛出一个讨论话题:下午一test lead问到,有些测试的bug会在A版本里出现,然后记录它;但开发人员在当前B版本试图重现时发现不能重现,故reject它。那么测试就郁闷了,待到下一轮回归测试可能是C版D版本,如果再出现自然reopen,但如果不复现是否真的应该关掉它吗?各位对这种sometimes bug怎么处理的啊?

          这个问题可能每个测试人员都会遇到,我说说我个人观点,供大家讨论。


          1. 在A版本发现的bug应该在A版本进行重现
           我们知道,有很多原因会导致A版本的bug可能不能在B版本重现:1)开发人员自己偷偷解了bug,以免受到KPI考核;2)环境差异,可能B版本的代码在A版本的环境也会出问题,但是在开发环境可能就不能复现;3)代码变更,也许是其他的代码引起的bug,B版本时其他开发已经修改,此类可以归纳为相关联功能引起的bug;4)AB两版本进行复现的前置条件及步骤已不同。

           既然有这么多可能性,那我们就应该排除影响,让问题简单化,保持环境和代码一致的情况下进行复现。A版本的bug如果在B版本不能复现,时间和条件允许的话,那就回退代码到A版本,有个前提不用回退,那就是已准确定位问题了,并且确定在B版本已经解决它了。      


           2. 项目时间允许的情况下,开发人员应大力协作复现bug

            对于”疑难杂症“,开发人员应大力配合测试人员进行复现:1)如果对于不好调试的代码就打印更多log;2)可以通过连接测试环境数据库并回滚代码到A版本,根据获悉的已有情况添加断点调试代码;3)做更细致的code review等等方式。在自己负责的那部分代码确定完没有问题,这时候就需要考虑到接口,是否在接口数据处理的问题,就需要其他开发人员配合。而测试人员需要尽最大努力来还原当时的场景:环境,数据,前置条件及测试步骤等。


           3. 测试人员要再次确认用例设计的覆盖度及周密性
            有几种情况会导致不可复现:1)环境;2)代码;3)数据。而数据又可以归纳到代码容错性处理上,环境其实是可以很好还原的,那出现不容易复现的bug就大多数是归于代码和数据上了,对于测试而言,用例设计的覆盖不够,不够严谨就会导致bug不在我们的掌握中。
             这个时候,我们有两种情况:一是原本用例就没有好好设计过,未经评审过,大家测试时就很随意,勿容置疑,赶紧把用例好好琢磨琢磨,再叫上项目相关人员进行评审,这么做的目的也是为了保证测试用例得到了项目相关人员的认可,各种情况大家都讨论过,保证在需求上大家的一致性,保证软件覆盖度能满足本次项目需求的要求,做到需求100%覆盖,开发人员若再提出更多建议,那也可以弥补一些黑盒测试时可能遗漏的情况;二是该项目已经经过严格的需求评审及用例评审了。当然,即便如此也不能避免漏测以及对特殊情况的考虑。

             当然,要这么做的前提是这个bug很严重,影响了版本的发布,有必要召集大家协力解决掉它。


            4. 绞尽脑汁,它仍然不能复现时,保持关注

    我相信,通过以上步骤的努力,仍然不能复现的bug一定是优先级不高的,那就再评估重要度,若通过项目组决定不影响版本发布,就密切关注此bug,在发布后验证时也重点关注下。而且该bug不能关闭,依次往以后版本中顺延,并且每轮测试时都要尝试再次复现。那何时可以关闭呢?也许3,5个版本发布后,没有出问题就可以决定关闭它了。


            5. 思考测试流程及测试规范,及时更正走过的弯路,制定提交bug的规范,便于开发及我们自己复现
      有一次,就会有第二次,我们应该及时响应,即便不能亡羊补牢,也要防患未然。 提交bug的规范,这个可能每个公司情况不一样,有些公司木有限制,提交的bug也是千人千面,这对于开发人员理解bug和复现bug无疑增加了难度。而规范了bug提交,若记录了此bug的前置条件,使用的数据及操作步骤,可能会大有益处。当然,此处不是说每个bug都这么详细。

    ===========================

    添加微信zzzmmmkkk,可以通过:

    1. 请在微信添加好友->搜索公众账号里查找zzzmmmkkk

    2. 或者点击本文右上角按钮后选择关注公众账号

    zzzmmmkkk,本名赵敏科,6年测试经验,2年项目及团队管理经验,从事过多年功能测试,性能测试及自动化测试,乐于分享。

    不定期发布有关测试技术文章,测试经验分享,测试思考和问题探讨。

    ===========================


  • 应聘时的给力回答(仅供参考)

    xinxinxingxing 发布于 2011-09-02 14:58:53

    以下内容仅供参考,针对每个人应聘不同的职位的各种问题都会有更好的答案。

    1、请你自我介绍一下你自己?
    回答提示:一般人回答这个问题过于平常,只说姓名、年龄、爱好、工作经验,这些在简历上都有。其实,企业最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研究的知识领域、个性中最积极的部分、做过的最成功的事,主要的成就等,这些都可以和学习无关,也可以和学习有关,但要突出积极的个性和做事的能力,说得合情合理企业才会相信。企业很重视一个人的礼貌,求职者要尊重考官,在回答每个问题之后都说一句“谢谢”,企业喜欢有礼貌的求职者。
      
     
    2、你觉得你个性上最大的优点是什么?
    回答提示:沉着冷静、条理清楚、立场坚定、顽强向上、乐于助人和关心他人、适应能力和幽默感、乐观和友爱。我在北大青鸟经过一到两年的培训及项目实战,加上实习工作,使我适合这份工作。
     
     
    3、说说你最大的缺点?
    回答提示:这个问题企业问的概率很大,通常不希望听到直接回答的缺点是什么等,如果求职者说自己小心眼、爱忌妒人、非常懒、脾气大、工作效率低,企业肯定不会录用你。绝对不要自作聪明地回答“我最大的缺点是过于追求完美”,有的人以为这样回答会显得自己比较出色,但事实上,他已经岌岌可危了。企业喜欢求职者从自己的优点说起,中间加一些小缺点,最后再把问题转回到优点上,突出优点的部分,企业喜欢聪明的求职者。
     
     
    4、你对加班的看法?
    回答提示:实际上好多公司问这个问题,并不证明一定要加班,只是想测试你是否愿意为公司奉献。
    回答样本:如果是工作需要我会义不容辞加班,我现在单身,没有任何家庭负担,可以全身心的投入工作。但同时,我也会提高工作效率,减少不必要的加班。
     
     
    5、你对薪资的要求?
    回答提示:如果你对薪酬的要求太低,那显然贬低自己的能力;如果你对薪酬的要求太高,那又会显得你分量过重,公司受用不起。一些雇主通常都事先对求聘的职位定下开支预算,因而他们第一次提出的价钱往往是他们所能给予的最高价钱,他们问你只不过想证实一下这笔钱是否足以引起你对该工作的兴趣。
     
    回答样本一:我对工资没有硬性要求,我相信贵公司在处理我的问题上会友善合理。我注重的是找对工作机会,所以只要条件公平,我则不会计较太多。
    回答样本二:我受过系统的软件编程的训练,不需要进行大量的培训,而且我本人也对编程特别感兴趣。因此,我希望公司能根据我的情况和市场标准的水平,给我合理的薪水。
    回答样本三:如果你必须自己说出具体数目,请不要说一个宽泛的范围,那样你将只能得到最低限度的数字。最好给出一个具体的数字,这样表明你已经对当今的人才市场作了调查,知道像自己这样学历的雇员有什么样的价值。
     
     
    6、在五年的时间内,你的职业规划?
    回答提示:这是每一个应聘者都不希望被问到的问题,但是几乎每个人都会被问到,比较多的答案是“管理者”。但是近几年来,许多公司都已经建立了专门的技术途径。这些工作地位往往被称作“顾问”、“参议技师”或“高级软件工程师”等等。当然,说出其他一些你感兴趣的职位也是可以的,比如产品销售部经理,生产部经理等一些与你的专业有相关背景的工作。要知道,考官总是喜欢有进取心的应聘者,此时如果说“不知道”,或许就会使你丧失一个好机会。最普通的回答应该是“我准备在技术领域有所作为”或“我希望能按照公司的管理思路发展”。
     
     
    7、你朋友对你的评价?
    回答提示: 想从侧面了解一下你的性格及与人相处的问题。
    回答样本一:我的朋友都说我是一个可以信赖的人。因为,我一旦答应别人的事情,就一定会做到。如果我做不到,我就不会轻易许诺。
    回答样本二:我觉的我是一个比较随和的人,与不同的人都可以友好相处。在我与人相处时,我总是能站在别人的角度考虑问题。
     
     
    8、你还有什么问题要问吗?
    回答提示:企业的这个问题看上去可有可无,其实很关键,企业不喜欢说“没问题”的人,因为其很注重员工的个性和创新能力。企业不喜欢求职者问个人福利之类的问题,如果有人这样问:贵公司对新入公司的员工有没有什么培训项目,我可以参加吗?或者说贵公司的晋升机制是什么样的?企业将很欢迎,因为体现出你对学习的热情和对公司的忠诚度以及你的上进心。
     
     
    9、如果通过这次面试我们单位录用了你,但工作一段时间却发现你根本不适合这个职位,你怎么办?
    回答提示:一段时间发现工作不适合我,有两种情况:①如果你确实热爱这个职业,那你就要不断学习,虚心向领导和同事学习业务知识和处事经验,了解这个职业的精神内涵和职业要求,力争减少差距;②你觉得这个职业可有可无,那还是趁早换个职业,去发现适合你的,你热爱的职业,那样你的发展前途也会大点,对单位和个人都有好处。
     
     
    10、在完成某项工作时,你认为领导要求的方式不是最好的,自己还有更好的方法,你应该怎么做?
    回答提示:①.原则上我会尊重和服从领导的工作安排,同时私底下找机会以请教的口吻,婉转地表达自己的想法,看看领导是否能改变想法。②如果领导没有采纳我的建议,我也同样会按领导的要求认真地去完成这项工作。③.还有一种情况,假如领导要求的方式违背原则,我会坚决提出反对意见,如领导仍固执己见,我会毫不犹豫地再向上级领导反映。
     
     
    11、如果你的工作出现失误,给本公司造成经济损失,你认为该怎么办?
    回答提示:①我本意是为公司努力工作,如果造成经济损失,我认为首要的问题是想方设法去弥补或挽回经济损失。如果我无能力负责,希望单位帮助解决。②分清责任,各负其责,如果是我的责任,我甘愿受罚;如果是一个我负责的团队中别人的失误,也不能幸灾乐祸,作为一个团队,需要互相提携共同完成工作,安慰同事并且帮助同事查找原因总结经验。③总结经验教训,一个人的一生不可能不犯错误,重要的是能从自己的或者是别人的错误中吸取经验教训,并在今后的工作中避免发生同类的错误。检讨自己的工作方法、分析问题的深度和力度是否不够,以致出现了本可以避免的错误。
     
     
    12、如果你做的一项工作受到上级领导的表扬,但你主管领导却说是他做的,你该怎样?
     
    回答提示:我首先不会找那位上级领导说明这件事,我会主动找我的主管领导来沟通,因为沟通是解决人际关系的最好办法,但结果会有两种:①我的主管领导认识到自己的错误,我想我会视具体情况决定是否原谅他。②他更加变本加厉的来威胁我,那我会毫不犹豫地找我的上级领导反映此事,因为他这样做会造成负面影响,对今后的工作不利。
     
     
    13、谈谈你对跳槽的看法?
    回答提示:①正常的“跳槽”能促进人才合理流动,应该支持。②频繁的跳槽对单位和个人双方都不利,应该反对。
     
     
    14、工作中你难以和同事、上司相处,你该怎么办?
    回答提示:①我会服从领导的指挥,配合同事的工作。②我会从自身找原因,仔细分析是不是自己工作做得不好让领导不满意,同事看不惯。还要看看是不是为人处世方面做得不好,如果是这样的话我会努力改正。③如果我找不到原因,我会找机会跟他们沟通,请他们指出我的不足,有问题就及时改正。④作为优秀的员工,应该时刻以大局为重,即使在一段时间内,领导和同事对我不理解,我也会做好本职工作,虚心向他们学习,我相信,他们会看见我在努力,总有一天会对我微笑的。
     
     
    15、假设你在某单位工作,成绩比较突出,得到领导的肯定。但同时你发现同事们越来越孤立你,你怎么看这个问题?你准备怎么办?
    回答提示:①成绩比较突出,得到领导的肯定是件好事情,以后更加努力。②检讨一下自己是不是对工作的热心度超过同事间交往的热心了,加强同事间的交往及共同的兴趣爱好。③工作中,切勿伤害别人的自尊心④不再领导前拨弄是非。
     
     
    16、你最近是否参加了培训课程?谈谈培训课程的内容。是公司资助还是自费参加?
    回答提示:自费参加,就是北大青鸟的培训课程(可以多谈谈自己学的技术)。
     
     
    17、你对于我们公司了解多少?
    回答提示:在去公司面试前上网查一下该公司主营业务。如回答:贵公司有意改变策略,加强与国外大厂的OEM合作,自有品牌的部分则透过海外经销商。
     
     
    18、请说出你选择这份工作的动机?
    回答提示:这是想知道面试者对这份工作的热忱及理解度,并筛选因一时兴起而来应试的人,如果是无经验者,可以强调“就算职种不同,也希望有机会发挥之前的经验”。
     
     
    19、你最擅长的技术方向是什么?
    回答提示:说和你要应聘的职位相关的课程,表现一下自己的热诚没有什么坏处。
     
     
    20、你能为我们公司带来什么呢?
    回答提示:①假如你可以的话,试着告诉他们你可以减低他们的费用——“我已经接受过北大青鸟近两年专业的培训,立刻就可以上岗工作”。② 企业很想知道未来的员工能为企业做什么,求职者应再次重复自己的优势,然后说:“就我的能力,我可以做一个优秀的员工在组织中发挥能力,给组织带来高效率和更多的收益”。企业喜欢求职者就申请的职位表明自己的能力,比如申请营销之类的职位,可以说:“我可以开发大量的新客户,同时,对老客户做更全面周到的服务,开发老客户的新需求和消费。”等等。
     
     
    21、最能概括你自己的三个词是什么?
    回答提示:我经常用的三个词是:适应能力强,有责任心和做事有始终,结合具体例子向主考官解释,
     
     
    22、你的业余爱好是什么?
    回答提示:找一些富于团体合作精神的,这里有一个真实的故事:有人被否决掉,因为他的爱好是深海潜水。主考官说:因为这是一项单人活动,我不敢肯定他能否适应团体工作。
     
     
    23、作为被面试者给我打一下分?
    回答提示:试着列出四个优点和一个非常非常非常小的缺点(可以抱怨一下设施,没有明确责任人的缺点是不会有人介意的)。
     
     
    24、你怎么理解你应聘的职位?
    回答提示:把岗位职责和任务及工作态度阐述一下。
     
     
    25、喜欢这份工作的哪一点?
    回答提示:相信其实大家心中一定都有答案了吧!每个人的价值观不同,自然评断的标准也会不同,但是,在回答面试官这个问题时可不能太直接就把自己心理的话说出来,尤其是薪资方面的问题,不过一些无伤大雅的回答是不错的考虑,如交通方便,工作性质及内容颇能符合自己的兴趣等等都是不错的答案,不过如果这时自己能仔细思考出这份工作的与众不同之处,相信在面试上会大大加分。
     
     
    26、为什么要离职?
    回答提示:①回答这个问题时一定要小心,就算在前一个工作受到再大的委屈,对公司有多少的怨言,都千万不要表现出来,尤其要避免对公司本身主管的批评,避免面试官的负面情绪及印象。建议此时最好的回答方式是将问题归咎在自己身上,例如觉得工作没有学习发展的空间,自己想在面试工作的相关产业中多加学习,或是前一份工作与自己的生涯规划不合等等,回答的答案最好是积极正面的。②我希望能获得一份更好的工作,如果机会来临,我会抓住。我觉得目前的工作,已经达到顶峰,即沒有升迁机会。
     
     
    27、说说你对行业、技术发展趋势的看法?
    回答提示:企业对这个问题很感兴趣,只有有备而来的求职者能够过关。求职者可以直接在网上查找对你所申请的行业部门的信息,只有深入了解才能产生独特的见解。企业认为最聪明的求职者是对所面试的公司预先了解很多,包括公司各个部门,发展情况,在面试回答问题的时候可以提到所了解的情况,企业欢迎进入企业的人是“知己”,而不是“盲人”。
     
     
    28、对工作的期望与目标何在?
    回答提示:这是面试者用来评断求职者是否对自己有一定程度的期望、对这份工作是否了解的问题。对于工作有确实学习目标的人通常学习较快,对于新工作自然较容易进入状况,这时建议你,最好针对工作的性质找出一个确实的答案,如业务员的工作可以这样回答:“我的目标是能成为一个超级业务员,将公司的产品广泛的推销出去,达到最好的业绩成效;为了达到这个目标,我一定会努力学习,而我相信以我认真负责的态度,一定可以达到这个目标。”其他类的工作也可以比照这个方式来回答,只要在目标方面稍微修改一下就可以了。
     
     
    29、说你的家庭?
    回答提示:企业面试时询问家庭问题不是非要知道求职者家庭的情况,探究隐私,企业不喜欢探究个人隐私,而是要了解家庭背景对求职者的塑造和影响。企业希望听到的重点也在于家庭对求职者的积极影响。企业最喜欢听到的是:我很爱我的家庭,我的家庭一向很和睦,虽然我的父亲和母亲都是普通人,但是从小,我就看到我父亲起早贪黑,每天工作特别勤劳,他的行动无形中培养了我认真负责的态度和勤劳的精神。我母亲为人善良,对人热情,特别乐于助人,所以在单位人缘很好,她的一言一行也一直在教导我做人的道理。企业相信,和睦的家庭关系对一个人的成长有潜移默化的影响。
     
     
    30、就你申请的这个职位,你认为你还欠缺什么?
    回答提示:企业喜欢问求职者弱点,但精明的求职者一般不直接回答。他们希望看到这样的求职者:继续重复自己的优势,然后说:“对于这个职位和我的能力来说,我相信自己是可以胜任的,只是缺乏经验,这个问题我想我可以进入公司以后以最短的时间来解决,我的学习能力很强,我相信可以很快融入公司的企业文化,进入工作状态。”企业喜欢能够巧妙地躲过难题的求职者。
     
     
    31、你欣赏哪种性格的人?
    回答提示:诚实、不死板而且容易相处的人、有“实际行动”的人。
     
     
    32、你通常如何处理別人的批评?
    回答提示:①沈默是金,不必说什么,否则情况更糟,不过我会接受建设性的批评。②我会等大家冷靜下来再讨论。
     
     
    33、怎样对待自己的失敗?
    回答提示:我们大家生来都不是十全十美的,我相信我有第二个机会改正我的错误。
     
     
    34、什么会让你有成就感?
    回答提示:为贵公司竭力效劳,尽我所能,完成一个项目。
     
     
    35、眼下你生活中最重要的是什么?
    回答提示:对我来说,能在这个领域找到工作是最重要的,能在贵公司任职对我说最重要。
     
     
    36、你为什么愿意到我们公司来工作?
    回答提示:对于这个问题,你要格外小心,如果你已经对该单位作了研究,你可以回答一些详细的原因,像“公司本身的高技术开发环境很吸引我。”、“我同公司出生在同样的时代,我希望能够进入一家与我共同成长的公司。”、“你们公司一直都稳定发展,在近几年来在市场上很有竞争力。”、“我认为贵公司能够给我提供一个与众不同的发展道路。”这都显示出你已经做了一些调查,也说明你对自己的未来有了较为具体的远景规划。
     
     
    37、你和别人发生过争执吗?你是怎样解决的?
    回答提示:这是面试中最险恶的问题,其实是考官布下的一个陷阱,千万不要说任何人的过错,应知成功解决矛盾是一个协作团体中成员所必备的能力。假如你工作在一个服务行业,这个问题简直成了最重要的一个环节。你是否能获得这份工作,将取决于这个问题的回答。考官希望看到你是成熟且乐于奉献的。他们通过这个问题了解你的成熟度和处世能力。在没有外界干涉的情况下,通过妥协的方式来解决才是正确答案。
     
     
    38、问题:你做过的哪件事最令自己感到骄傲?
    回答提示:这是考官给你的一个机会,让你展示自己把握命运的能力。这会体现你潜在的领导能力以及你被提升的可能性。假如你应聘于一个服务性质的单位,你很可能会被邀请去午餐。记住:你的前途取决于你的知识、你的社交能力和综合表现。
     
     
    39、新到一个部门,一天一个客户来找你解决问题,你努力想让他满意,可是始终达不到群众得满意,他投诉你们部门工作效率低,你这个时候怎么作?
    回答提示:(1)首先,我会保持冷静。作为一名工作人员,在工作中遇到各种各样的问题是正常的,关键是如何认识它,积极应对,妥善处理。 (2)其次,我会反思一下客户不满意的原因。一是看是否是自己在解决问题上的确有考虑的不周到的地方,二是看是否是客户不太了解相关的服务规定而提出超出规定的要求,三是看是否是客户了解相关的规定,但是提出的要求不合理。 (3)再次,根据原因采取相对的对策。如果是自己确有不周到的地方,按照服务规定作出合理的安排,并向客户作出解释;如果是客户不太了解政策规定而造成的误解,我会向他作出进一步的解释,消除他的误会;如果是客户提出的要求不符合政策规定,我会明确地向他指出。 (4)再次,我会把整个事情的处理情况向领导作出说明,希望得到他的理解和支持。(5)我不会因为客户投诉了我而丧失工作的热情和积极性,而会一如既往地牢记为客户服务的宗旨,争取早日做一名领导信任、公司放心、客户满意的职员。
     
     
    40、对这项工作,你有哪些可预见的困难?
    回答提示:①不宜直接说出具体的困难,否则可能令对方怀疑应聘者不行。②可以尝试迂回战术,说出应聘者对困难所持有的态度——工作中出现一些困难是正常的,也是难免的,但是只要有坚忍不拔的毅力、良好的合作精神以及事前周密而充分的准备,任何困难都是可以克服。
    分析:一般问这个问题,面试者的希望就比较大了,因为已经在谈工作细节,但常规思路中的回答,又被面试官“骗”了。当面试官询问这个问题的时候,有两个目的。第一,看看应聘者是不是在行,说出的困难是不是在这个职位中一般都不可避免的问题。第二,是想看一下应聘者解决困难的手法对不对,及公司能否提供这样的资源。而不是想了解应聘者对困难的态度。
     
     
    41、如果我录用你,你将怎样开展工作?
    回答提示: ①如果应聘者对于应聘的职位缺乏足够的了解,最好不要直接说出自己开展工作的具体办法。②可以尝试采用迂回战术来回答,如“首先听取领导的指示和要求,然后就有关情况进行了解和熟悉,接下来制定一份近期的工作计划并报领导批准,最后根据计划开展工作。”。
    分析:这个问题的主要目的也是了解应聘者的工作能力和计划性、条理性,而且重点想要知道细节。如果向思路中所讲的迂回战术,面试官会认为回避问题,如果引导了几次仍然是回避的话,此人绝对不会录用了。
     
     
    42、你希望与什么样的上级共事?
    回答提示:①通过应聘者对上级的“希望”可以判断出应聘者对自我要求的意识,这既上一个陷阱,又是一次机会。②最好回避对上级具体的希望,多谈对自己的要求。③如“做为刚步入社会的新人,我应该多要求自己尽快熟悉环境、适应环境,而不应该对环境提出什么要求,只要能发挥我的专长就可以了。
    分析:这个问题比较好的回答是,希望我的上级能够在工作中对我多指导,对我工作中的错误能够立即指出。总之,从上级指导这个方面谈,不会有大的纰漏。
     
     
    43、在完成某项工作时,你认为领导要求的方式不是最好的,自己还有更好的方法,你应该怎么做?
    回答提示:①.原则上我会尊重和服从领导的工作安排;同时私底下找机会以请教的口吻,婉转地表达自己的想法,看看领导是否能改变想法。②如果领导没有采纳我的建议,我也同样会按领导的要求认真地去完成这项工作。③.还有一种情况,假如领导要求的方式违背原则,我会坚决提出反对意见,如领导仍固执己见,我会毫不犹豫地再向上级领导反映。
     
     
    44、与上级意见不一是,你将怎么办?
    回答提示:①一般可以这样回答“我会给上级以必要的解释和提醒,在这种情况下,我会服从上级的意见。”②如果面试你的是总经理,而你所应聘的职位另有一位经理,且这位经理当时不在场,可以这样回答:“对于非原则性问题,我会服从上级的意见,对于涉及公司利益的重大问题,我希望能向更高层领导反映。”
    分析:这个问题的标准答案是思路①,如果用②的回答,必死无疑。你没有摸清楚改公司的内部情况,先想打小报告,这样的人没有人敢要。
     
     
    45、你工作经验欠缺,如何能胜任这项工作?
    常规思路:①如果招聘单位对应届毕业生的应聘者提出这个问题,说明招聘公司并不真正在乎“经验”,关键看应聘者怎样回答。②对这个问题的回答最好要体现出应聘者的诚恳、机智、果敢及敬业。③如“作为应届毕业生,在工作经验方面的确会有所欠缺,因此在读书期间我一直利用各种机会在这个行业里做兼职。我也发现,实际工作远比书本知识丰富、复杂。但我有较强的责任心、适应能力和学习能力,而且比较勤奋,所以在兼职中均能圆满完成各项工作,从中获取的经验也令我受益非浅。请贵公司放心,学校所学及兼职的工作经验使我一定能胜任这个职位。”点评:这个问题思路中的答案尚可,突出自己的吃苦能力和适应性以及学习能力(不是学习成绩)为好。

  • 测试文档

    hemiao 发布于 2011-09-08 09:44:49

     

    每个测试过程有五个基本测试文档Test Document):

    《测试计划》:指明测试范围、方法、资源,以及相应测试活动的时间进度安排表的文档。

    《测试方案》:指明为完成软件或软件集成特性的测试而进行的设计测试方法的细节文档。

    《测试用例》:指明为完成一个测试项的测试输入、预期结果、测试执行条件等因素的文档。

    《测试规程》:指明执行测试时测试活动序列的文档。

    《测试报告》:指明执行测试结果的文档。

    1《测试计划》文档

    《测试计划》文档是计划测试阶段的测试文档,就是指明测试范围、方法、资源,以及相应测试活动的时间进度安排表的文档。包括如下内容:

    ① 目标

    表示该测试计划所达到的目标。

    ② 概述

    v       项目背景:简要描述项目背景及所要求达到的目标,如项目的主要功能特性,系统结构几简要历史等。

    v       范围:指明该技术的适用对象及范围。

    ③ 角色及职责

    定义角色及其职责,即在每一个角色与测试任务之间建立关联。

    ④ 测试对象

    

    列出所有将被作为测试目标的测试项(包括功能需求、非功能需求(性能、可移植性))。

    ⑤ 测试通过/失败标准

    测试标准是客观的陈述,该陈述指明了判断/确认测试何时结束,以及所测试的应用程序的质量。测试标准可以是一系列的陈述或对另一文档(测试标准)的引用。测试标准应该指明:

    v       什么将被测试?(确切的测试目标)

    v       度量尺度是如何建立的?

    v       使用了哪些标准对尺度进行评价

    ⑥ 测试任务安排

    明确测试任务,对每项测试任务都要说清楚以下7个主题:

    1)       任务:用简洁的句子对任务加以说明。

    2)       方法和标准:指明执行该任务时采用的方法以及遵循的标准。

    3)       输入/输出:给出该任务必要的输入输出。

    4)       时间安排:给出任务的起始及持续的时间。

    5)       资源:给出任务所需要的人力和物力资源。

    6)       风险和假设:指明启动该任务应该满足的假设,以及任务执行可能存在的风险。

    7)       角色和职责:指明由谁负责该任务的组织和执行,以及谁将担负怎样的职责。

    ⑦ 应交付的测试工作产品

    指明应交付的文档、测试代码及测试工具,一般包括这些文档测试计划、测试方案、测试用例、测试规程、测试日志、测试事故报告、测试输入及输出数据、测试工具。

    ⑧ 工作量估计

    给出前面所定义任务的人力需求及总计。

    2《测试方案》文档

    《测试方案》文档是计划测试阶段的测试文档,指明为完成软件或软件集成的特性测试而进行设计测试方法的细节文档。具体包括:

    ① 概述

    概述被测对象和特性,简要描述被测试对象的需求要素、测试设计准则,以及测试对象的历史。

    ② 被测对象

    确定被测试对象,包括其版本/修订级别,并说明软件的承载媒介极其对测试的影响。

    ③ 应测试的特性

    确定应测试的所有特性和特性组合。

    ④ 不被测试的特性

    确定被测试对象将有那些特性和特性组合将不被测试,并说明不被测试的原因。

    ⑤ 测试设计综述

    ⑥ 测试模型

    ⑦ 测试需求

    测试需求是根据本阶段的测试目标从不同的角度明确本阶段的各种需求因素,包括:环境需求、被测试对象需求、测试工具需求、测试代码需求、测试数据准备等。

    ⑧ 测试设计

    测试工具设计

    测试代码设计

    测试规程设计

    测试用例设计

    3《测试用例》文档

    《测试用例》文档是计划测试阶段的测试文档,指明为完成一个测试项的输入、预期结果、测试执行条件等因素的文档。包括如下内容:

    ① 测试用例清单

    ② 测试用例列表

    v       测试项目

    v       用例编号

    v       用例级别

    v       输入值

    v       预期输出结果

    v       实测结果

    '

    v       备注

    4《测试报告》文档

    《测试计划》文档是执行测试阶段的测试文档,指明执行测试结果的文档。包括如下内容:

    概述

    说明本报告是哪个测试活动的总结,指明该测试活动所依据的测试计划、测试方案及测试用例为本文档的参考文档,必须指明被测试对象及其版本/修订级别。

    测试时间、地点、人员环境描述

    总结和评价

    测试结果统计

    对本次测试项目进行统计,包括总项目通过多少项,失败多少项,部分通过多少项及百分比等,详细的测试项目通过情况清单表示放在附件里。此处的总结用下表表示。

     

     

    

    总测试项

    实际测试项

    OK

    POK

    NT

    NG

    无需测试项

    数目

     

     

     

     

     

     

    百分比

     

     

     

     

     

     

    测试结果统计

     

    其中:OK表示测试结果全部正确;POK表示测试结果大部分正确;NG表示测试结果有较大错误;NT表示由于各种原因本次无法测试。

    测试评估对被测对象以及测试活动分别给出总结性的评估,包括稳定性、测试充分性等。

    测试总结和改进建议

    总结本次测试活动的经验教训,总结主要的测试活动和事件。总结资源消耗数据,如总人员、总机时,每个主要测试活动花费的时间。

    提供对本次测试活动的测试设计和操作的改进建议。每一条建议的分析及其对软件测试的影响也应提供。

    问题报告

    在详细的问题报告前可以先建立一个问题统计表格,以便对问题的相关分布信息有整体的了解。

    问题总数

    致命问题

    严重问题

    一般问题

    提示问题

    其他统计项

    数目

     

     

     

     

     

    百分比

     

     

     

     

     

    问题统计记录测试过程中发生并且进行报告时仍尚未解决的遗留问题。

  • 深入浅出正则表达式(一)

    yujie6832 发布于 2009-12-03 13:14:04

    前言:

      半年前我对正则表达式产生了兴趣,在网上查找过不少资料,看过不少的教程,最后在使用一个正则表达式工具RegexBuddy时发现他的教程写的非常好,可以说是我目前见过最好的正则表达式教程。于是一直想把他翻译过来。这个愿望直到这个五一长假才得以实现,结果就有了这篇文章。关于本文的名字,使用“深入浅出”似乎已经太俗。但是通读原文以后,觉得只有用“深入浅出”才能准确的表达出该教程给我的感受,所以也就不能免俗了。

      本文是Jan Goyvaerts为RegexBuddy写的教程的译文,版权归原作者所有,欢迎转载。但是为了尊重原作者和译者的劳动,请注明出处!谢谢!

      1.什么是正则表达式

      基本说来,正则表达式是一种用来描述一定数量文本的模式。Regex代表Regular Express。本文将用<<regex>>来表示一段具体的正则表达式。

      一段文本就是最基本的模式,简单的匹配相同的文本。

      2.不同的正则表达式引擎

      正则表达式引擎是一种可以处理正则表达式的软件。通常,引擎是更大的应用程序的一部分。在软件世界,不同的正则表达式并不互相兼容。本教程会集中讨论Perl 5类型的引擎,因为这种引擎是应用最广泛的引擎。同时我们也会提到一些和其他引擎的区别。许多近代的引擎都很类似,但不完全一样。例如.NET正则库,JDK正则包。

      3.文字符号

      最基本的正则表达式由单个文字符号组成。如<<a>>,它将匹配字符串中第一次出现的字符“a”。如对字符串“Jack is a boy”。“J”后的“a”将被匹配。而第二个“a”将不会被匹配。

      正则表达式也可以匹配第二个“a”,这必须是你告诉正则表达式引擎从第一次匹配的地方开始搜索。在文本编辑器中,你可以使用“查找下一个”。在编程语言中,会有一个函数可以使你从前一次匹配的位置开始继续向后搜索。

      类似的,<<cat>>会匹配“About cats and dogs”中的“cat”。这等于是告诉正则表达式引擎,找到一个<<c>>,紧跟一个<<a>>,再跟一个<<t>>。

      要注意,正则表达式引擎缺省是大小写敏感的。除非你告诉引擎忽略大小写,否则<<cat>>不会匹配“Cat”。

      ·特殊字符

      对于文字字符,有11个字符被保留作特殊用途。他们是:

      [ ] \ ^ $ . | ? * + ( )

      这些特殊字符也被称作元字符。

      如果你想在正则表达式中将这些字符用作文本字符,你需要用反斜杠“\”对其进行换码(escape)。例如你想匹配“1+1=2”,正确的表达式为<<1\+1=2>>.

      需要注意的是,<<1+1=2>>也是有效的正则表达式。但它不会匹配“1+1=2”,而会匹配“123+111=234”中的“111=2”。因为“+”在这里表示特殊含义(重复1次到多次)。

      在编程语言中,要注意,一些特殊的字符会先被编译器处理,然后再传递给正则引擎。因此正则表达式<<1\+2=2>>在C++中要写成“1\\+1=2”。为了匹配“C:\temp”,你要用正则表达式<<C:\\temp>>。而在C++中,正则表达式则变成了“C:\\\\temp”。

      ·不可显示字符

      可以使用特殊字符序列来代表某些不可显示字符:

      <<\t>>代表Tab(0x09)

      <<\r>>代表回车符(0x0D)

      <<\n>>代表换行符(0x0A)

      要注意的是Windows中文本文件使用“\r\n”来结束一行而Unix使用“\n”。

      4.正则表达式引擎的内部工作机制

      知道正则表达式引擎是如何工作的有助于你很快理解为何某个正则表达式不像你期望的那样工作。

      有两种类型的引擎:文本导向(text-directed)的引擎和正则导向(regex-directed)的引擎。Jeffrey Friedl把他们称作DFA和NFA引擎。本文谈到的是正则导向的引擎。这是因为一些非常有用的特性,如“惰性”量词(lazy quantifiers)和反向引用(backreferences),只能在正则导向的引擎中实现。所以毫不意外这种引擎是目前最流行的引擎。

      你可以轻易分辨出所使用的引擎是文本导向还是正则导向。如果反向引用或“惰性”量词被实现,则可以肯定你使用的引擎是正则导向的。你可以作如下测试:将正则表达式<<regex|regex not>>应用到字符串“regex not”。如果匹配的结果是regex,则引擎是正则导向的。如果结果是regex not,则是文本导向的。因为正则导向的引擎是“猴急”的,它会很急切的进行表功,报告它找到的第一个匹配。

      ·正则导向的引擎总是返回最左边的匹配

      这是需要你理解的很重要的一点:即使以后有可能发现一个“更好”的匹配,正则导向的引擎也总是返回最左边的匹配。

      当把<<cat>>应用到“He captured a catfish for his cat”,引擎先比较<<c>>和“H”,结果失败了。于是引擎再比较<<c>>和“e”,也失败了。直到第四个字符,<<c>>匹配了“c”。<<a>>匹配了第五个字符。到第六个字符<<t>>没能匹配“p”,也失败了。引擎再继续从第五个字符重新检查匹配性。直到第十五个字符开始,<<cat>>匹配上了“catfish”中的“cat”,正则表达式引擎急切的返回第一个匹配的结果,而不会再继续查找是否有其他更好的匹配。

    5.字符集

      字符集是由一对方括号“[]”括起来的字符集合。使用字符集,你可以告诉正则表达式引擎仅仅匹配多个字符中的一个。如果你想匹配一个“a”或一个“e”,使用<<[ae]>>。你可以使用<<gr[ae]y>>匹配gray或grey。这在你不确定你要搜索的字符是采用美国英语还是英国英语时特别有用。相反,<<gr[ae]y>>将不会匹配graay或graey。字符集中的字符顺序并没有什么关系,结果都是相同的。

      你可以使用连字符“-”定义一个字符范围作为字符集。<<[0-9]>>匹配0到9之间的单个数字。你可以使用不止一个范围。<<[0-9a-fA-F] >>匹配单个的十六进制数字,并且大小写不敏感。你也可以结合范围定义与单个字符定义。<<[0-9a-fxA-FX]>>匹配一个十六进制数字或字母X。再次强调一下,字符和范围定义的先后顺序对结果没有影响。

      ·字符集的一些应用

      查找一个可能有拼写错误的单词,比如<<sep[ae]r[ae]te>>或<<li[cs]en[cs]e>>。

      查找程序语言的标识符,<<A-Za-z_][A-Za-z_0-9]*>>。(*表示重复0或多次)

      查找C风格的十六进制数<<0[xX][A-Fa-f0-9]+>>。(+表示重复一次或多次)

      ·取反字符集

      在左方括号“[”后面紧跟一个尖括号“^”,将会对字符集取反。结果是字符集将匹配任何不在方括号中的字符。不像“.”,取反字符集是可以匹配回车换行符的。

      需要记住的很重要的一点是,取反字符集必须要匹配一个字符。<<q[^u]>>并不意味着:匹配一个q,后面没有u跟着。它意味着:匹配一个q,后面跟着一个不是u的字符。所以它不会匹配“Iraq”中的q,而会匹配“Iraq is a country”中的q和一个空格符。事实上,空格符是匹配中的一部分,因为它是一个“不是u的字符”。

      如果你只想匹配一个q,条件是q后面有一个不是u的字符,我们可以用后面将讲到的向前查看来解决。

      ·字符集中的元字符

      需要注意的是,在字符集中只有4个字符具有特殊含义。它们是:“] \ ^ -”。“]”代表字符集定义的结束;“\”代表转义;“^”代表取反;“-”代表范围定义。其他常见的元字符在字符集定义内部都是正常字符,不需要转义。例如,要搜索星号*或加号+,你可以用<<[+*]>>。当然,如果你对那些通常的元字符进行转义,你的正则表达式一样会工作得很好,但是这会降低可读性。

      在字符集定义中为了将反斜杠“\”作为一个文字字符而非特殊含义的字符,你需要用另一个反斜杠对它进行转义。<<[\\x]>>将会匹配一个反斜杠和一个X。“]^-”都可以用反斜杠进行转义,或者将他们放在一个不可能使用到他们特殊含义的位置。我们推荐后者,因为这样可以增加可读性。比如对于字符“^”,将它放在除了左括号“[”后面的位置,使用的都是文字字符含义而非取反含义。如<<[x^]>>会匹配一个x或^。<<[]x]>>会匹配一个“]”或“x”。<<[-x]>>或<<[x-]>>都会匹配一个“-”或“x”。

      ·字符集的简写

      因为一些字符集非常常用,所以有一些简写方式。

      <<\d>>代表<<[0-9]>>;

      <<\w>>代表单词字符。这个是随正则表达式实现的不同而有些差异。绝大多数的正则表达式实现的单词字符集都包含了<<A-Za-z0-9_]>>。

      <<\s>>代表“白字符”。这个也是和不同的实现有关的。在绝大多数的实现中,都包含了空格符和Tab符,以及回车换行符<<\r\n>>。

      字符集的缩写形式可以用在方括号之内或之外。<<\s\d>>匹配一个白字符后面紧跟一个数字。<<[\s\d]>>匹配单个白字符或数字。<<[\da-fA-F]>>将匹配一个十六进制数字。

      取反字符集的简写

      <<[\S]>> = <<[^\s]>>

      <<[\W]>> = <<[^\w]>>

      <<[\D]>> = <<[^\d]>>

      ·字符集的重复

      如果你用“?*+”操作符来重复一个字符集,你将会重复整个字符集。而不仅是它匹配的那个字符。正则表达式<<[0-9]+>>会匹配837以及222。

      如果你仅仅想重复被匹配的那个字符,可以用向后引用达到目的。我们以后将讲到向后引用。

    6.使用?*或+进行重复

      ?:告诉引擎匹配前导字符0次或一次。事实上是表示前导字符是可选的。

      +:告诉引擎匹配前导字符1次或多次

      *:告诉引擎匹配前导字符0次或多次

      <[A-Za-z][A-Za-z0-9]*>匹配没有属性的HTML标签,“<”以及“>”是文字符号。第一个字符集匹配一个字母,第二个字符集匹配一个字母或数字。

      我们似乎也可以用<[A-Za-z0-9]+>。但是它会匹配<1>。但是这个正则表达式在你知道你要搜索的字符串不包含类似的无效标签时还是足够有效的。

      ·限制性重复

      许多现代的正则表达式实现,都允许你定义对一个字符重复多少次。词法是:{min,max}。min和max都是非负整数。如果逗号有而max被忽略了,则max没有限制。如果逗号和max都被忽略了,则重复min次。

      因此{0,}和*一样,{1,}和+的作用一样。

      你可以用<<\b[1-9][0-9]{3}\b>>匹配1000~9999之间的数字(“\b”表示单词边界)。<<\b[1-9][0-9]{2,4}\b>>匹配一个在100~99999之间的数字。

      ·注意贪婪性

      假设你想用一个正则表达式匹配一个HTML标签。你知道输入将会是一个有效的HTML文件,因此正则表达式不需要排除那些无效的标签。所以如果是在两个尖括号之间的内容,就应该是一个HTML标签。

      许多正则表达式的新手会首先想到用正则表达式<< <.+> >>,他们会很惊讶的发现,对于测试字符串,“This is a <EM>first</EM> test”,你可能期望会返回<EM>,然后继续进行匹配的时候,返回</EM>。

      但事实是不会。正则表达式将会匹配“<EM>first</EM>”。很显然这不是我们想要的结果。原因在于“+”是贪婪的。也就是说,“+”会导致正则表达式引擎试图尽可能的重复前导字符。只有当这种重复会引起整个正则表达式匹配失败的情况下,引擎会进行回溯。也就是说,它会放弃最后一次的“重复”,然后处理正则表达式余下的部分。

      和“+”类似,“?*”的重复也是贪婪的。

      ·深入正则表达式引擎内部

      让我们来看看正则引擎如何匹配前面的例子。第一个记号是“<”,这是一个文字符号。第二个符号是“.”,匹配了字符“E”,然后“+”一直可以匹配其余的字符,直到一行的结束。然后到了换行符,匹配失败(“.”不匹配换行符)。于是引擎开始对下一个正则表达式符号进行匹配。也即试图匹配“>”。到目前为止,“<.+”已经匹配了“<EM>first</EM> test”。引擎会试图将“>”与换行符进行匹配,结果失败了。于是引擎进行回溯。结果是现在“<.+”匹配“<EM>first</EM> tes”。于是引擎将“>”与“t”进行匹配。显然还是会失败。这个过程继续,直到“<.+”匹配“<EM>first</EM”,“>”与“>”匹配。于是引擎找到了一个匹配“<EM>first</EM>”。记住,正则导向的引擎是“急切的”,所以它会急着报告它找到的第一个匹配。而不是继续回溯,即使可能会有更好的匹配,例如“<EM>”。所以我们可以看到,由于“+”的贪婪性,使得正则表达式引擎返回了一个最左边的最长的匹配。

      ·用懒惰性取代贪婪性

      一个用于修正以上问题的可能方案是用“+”的惰性代替贪婪性。你可以在“+”后面紧跟一个问号“?”来达到这一点。“*”,“{}”和“?”表示的重复也可以用这个方案。因此在上面的例子中我们可以使用“<.+?>”。让我们再来看看正则表达式引擎的处理过程。

      再一次,正则表达式记号“<”会匹配字符串的第一个“<”。下一个正则记号是“.”。这次是一个懒惰的“+”来重复上一个字符。这告诉正则引擎,尽可能少的重复上一个字符。因此引擎匹配“.”和字符“E”,然后用“>”匹配“M”,结果失败了。引擎会进行回溯,和上一个例子不同,因为是惰性重复,所以引擎是扩展惰性重复而不是减少,于是“<.+”现在被扩展为“<EM”。引擎继续匹配下一个记号“>”。这次得到了一个成功匹配。引擎于是报告“<EM>”是一个成功的匹配。整个过程大致如此。

      ·惰性扩展的一个替代方案

      我们还有一个更好的替代方案。可以用一个贪婪重复与一个取反字符集:“<[^>]+>”。之所以说这是一个更好的方案在于使用惰性重复时,引擎会在找到一个成功匹配前对每一个字符进行回溯。而使用取反字符集则不需要进行回溯。

      最后要记住的是,本教程仅仅谈到的是正则导向的引擎。文本导向的引擎是不回溯的。但是同时他们也不支持惰性重复操作。

    7.使用“.”匹配几乎任意字符

      在正则表达式中,“.”是最常用的符号之一。不幸的是,它也是最容易被误用的符号之一。

      “.”匹配一个单个的字符而不用关心被匹配的字符是什么。唯一的例外是新行符。在本教程中谈到的引擎,缺省情况下都是不匹配新行符的。因此在缺省情况下,“.”等于是字符集[^\n\r](Window)或[^\n]( Unix)的简写。

      这个例外是因为历史的原因。因为早期使用正则表达式的工具是基于行的。它们都是一行一行的读入一个文件,将正则表达式分别应用到每一行上去。在这些工具中,字符串是不包含新行符的。因此“.”也就从不匹配新行符。

      现代的工具和语言能够将正则表达式应用到很大的字符串甚至整个文件上去。本教程讨论的所有正则表达式实现都提供一个选项,可以使“.”匹配所有的字符,包括新行符。在RegexBuddy, EditPad Pro或PowerGREP等工具中,你可以简单的选中“点号匹配新行符”。在Perl中,“.”可以匹配新行符的模式被称作“单行模式”。很不幸,这是一个很容易混淆的名词。因为还有所谓“多行模式”。多行模式只影响行首行尾的锚定(anchor),而单行模式只影响“.”。

      其他语言和正则表达式库也采用了Perl的术语定义。当在.NET Framework中使用正则表达式类时,你可以用类似下面的语句来激活单行模式:Regex.Match(“string”,”regex”,RegexOptions.SingleLine)

      ·保守的使用点号“.”

      点号可以说是最强大的元字符。它允许你偷懒:用一个点号,就能匹配几乎所有的字符。但是问题在于,它也常常会匹配不该匹配的字符。

      我会以一个简单的例子来说明。让我们看看如何匹配一个具有“mm/dd/yy”格式的日期,但是我们想允许用户来选择分隔符。很快能想到的一个方案是<<\d\d.\d\d.\d\d>>。看上去它能匹配日期“02/12/03”。问题在于02512703也会被认为是一个有效的日期。

      <<\d\d[-/.]\d\d[-/.]\d\d>>看上去是一个好一点的解决方案。记住点号在一个字符集里不是元字符。这个方案远不够完善,它会匹配“99/99/99”。而<<[0-1]\d[-/.][0-3]\d[-/.]\d\d>>又更进一步。尽管他也会匹配“19/39/99”。你想要你的正则表达式达到如何完美的程度取决于你想达到什么样的目的。如果你想校验用户输入,则需要尽可能的完美。如果你只是想分析一个已知的源,并且我们知道没有错误的数据,用一个比较好的正则表达式来匹配你想要搜寻的字符就已经足够。

      8.字符串开始和结束的锚定

      锚定和一般的正则表达式符号不同,它不匹配任何字符。相反,他们匹配的是字符之前或之后的位置。“^”匹配一行字符串第一个字符前的位置。<<^a>>将会匹配字符串“abc”中的a。<<^b>>将不会匹配“abc”中的任何字符。

      类似的,$匹配字符串中最后一个字符的后面的位置。所以<<c$>>匹配“abc”中的c。

      ·锚定的应用

      在编程语言中校验用户输入时,使用锚定是非常重要的。如果你想校验用户的输入为整数,用<<^\d+$>>。

      用户输入中,常常会有多余的前导空格或结束空格。你可以用<<^\s*>>和<<\s*$>>来匹配前导空格或结束空格。

      ·使用“^”和“$”作为行的开始和结束锚定

      如果你有一个包含了多行的字符串。例如:“first line\n\rsecond line”(其中\n\r表示一个新行符)。常常需要对每行分别处理而不是整个字符串。因此,几乎所有的正则表达式引擎都提供一个选项,可以扩展这两种锚定的含义。“^”可以匹配字串的开始位置(在f之前),以及每一个新行符的后面位置(在\n\r和s之间)。类似的,$会匹配字串的结束位置(最后一个e之后),以及每个新行符的前面(在e与\n\r之间)。

      在.NET中,当你使用如下代码时,将会定义锚定匹配每一个新行符的前面和后面位置:Regex.Match("string", "regex", RegexOptions.Multiline)

      应用:string str = Regex.Replace(Original, "^", "> ", RegexOptions.Multiline)--将会在每行的行首插入“>”。

      ·绝对锚定

      <<\A>>只匹配整个字符串的开始位置,<<\Z>>只匹配整个字符串的结束位置。即使你使用了“多行模式”,<<\A>>和<<\Z>>也从不匹配新行符。

      即使\Z和$只匹配字符串的结束位置,仍然有一个例外的情况。如果字符串以新行符结束,则\Z和$将会匹配新行符前面的位置,而不是整个字符串的最后面。这个“改进”是由Perl引进的,然后被许多的正则表达式实现所遵循,包括Java,.NET等。如果应用<<^[a-z]+$>>到“joe\n”,则匹配结果是“joe”而不是“joe\n”。

  • 转:Android上的Webkit的测试

    xiaoxie59 发布于 2010-11-29 16:06:38

    啥叫webkit:

      WebKit是Mac OS X v10.3及以上版本所包含的软件框架(对v10.2.7及以上版本也可通过软件更新获取)。 同时,WebKit也是Mac OS X的Safari网页浏览器的基础。WebKit是一个开源项目,主要由KDE的KHTML修改而来并且包含了一些来自苹果公司的一些组件。

      传统上,WebKit包含一个网页引擎WebCore和一个脚本引擎JavaScriptCore,它们分别对应的是KDE的KHTML和KJS。不过,随着JavaScript引擎的独立性越来越强,现在WebKit和WebCore已经基本上混用不分(例如Google Chrome和Maxthon 3采用V8引擎,却仍然宣称自己是WebKit内核)。

      目前常见的采用webkit的浏览器有:  Chromium · Google Chrome · 傲游 3 · Epiphany · iCab · Midori · OmniWeb · Safari  · Shiira, iphone, android, Symbian S60

      测试的时候选定一个或两个参照对象,不妨选择Chrome这个新生事物,确实是个不错的浏览器。

      Webkit的特性:

      Css1, Css2.1的支持(测试网页http://www.w3.org/Style/CSS/Test/#CSS2.1),CSS3 Selectors的支持,SVG,MathML,CSS,DOM

      浏览器的标准测试:

      引入浏览器的标准测试,大致包含以下几类:

      网页主要由三部分组成:结构(Structure)、表现(Presentation)和行为(Behavior)。对应的标准也分三方面:结构化标准语言主要包括XHTML和XML,表现标准语言主要包括CSS,行为标准主要包括对象模型(如W3C DOM)、ECMAScript等。这些标准大部分由W3C起草和发布,也有一些是其他标准组织制订的标准,比如ECMA(European Computer Manufacturers Association)的ECMAScript标准。

      1.结构标准语言

      (1)XML

      XML是The Extensible Markup Language(可扩展标识语言)的简写。目前推荐遵循的是W3C于2000年10月6日发布的XML1.0,参考(www.w3.org/TR/2000/REC-XML-20001006)。和HTML一样,XML同样来源于SGML,但XML是一种能定义其他语言的语。XML最初设计的目的是弥补HTML的不足,以强大的扩展性满足网络信息发布的需要,后来逐渐用于网络数据的转换和描述。

      (2)XHTML

      XHTML是The Extensible HyperText Markup Language可扩展标识语言的缩写。目前推荐遵循的是W3C于2000年1月26日推荐XML1.0(参考http://www.w3.org/TR/xhtml1)。 XML虽然数据转换能力强大,完全可以替代HTML,但面对成千上万已有的站点,直接采用XML还为时过早。因此,我们在 HTML4.0的基础上,用XML的规则对其进行扩展,得到了XHTML。简单的说,建立XHTML的目的就是实现HTML向XML的过渡。

      2. 表现标准语言

      CSS是Cascading Style. Sheets层叠样式表的缩写。目前推荐遵循的是W3C于1998年5月12日推荐CSS2(参考http://www.w3.org/TR/CSS2/)。W3C创建CSS标准的目的是以CSS取代HTML表格式布局、帧和其他表现的语言。纯CSS布局与结构式XHTML相结合能帮助设计师分离外观与结构,使站点的访问及维护更加容易。
    3.行为标准

      (1)DOM

      DOM是Document Object Model文档对象模型的缩写。根据W3C DOM规范(http://www.w3.org/DOM/),DOM 是一种与浏览器,平台,语言的接口,使得你可以访问页面其他的标准组件。简单理解,DOM解决了Netscaped的Javascript和 Microsoft的Jscript之间的冲突,给予web设计师和开发者一个标准的方法,让他们来访问他们站点中的数据、脚本和表现层对像。

      (2)ECMAScript

      ECMAScript是ECMA(European Computer Manufacturers Association)制定的标准脚本语言(JAVAScript)。目前推荐遵循的是ECMAScript. 262(http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM)。

      W3C网页的标准测试

      页面校验地址 http://validator.w3.org/

      CSS文档校验 http://jigsaw.w3.org/css-validator/

      XHTML 1.0 标准规格 : The Extensible HyperText Markup Language

      W3C标准测试网址 http://validator.w3.org/

      测试时一定要有文件类别宣告还有指定文件编码

      <meta. http-equiv="Content-Type" content="text/html; charset=gb2312" />

      才能顺利进行测试动作,开始打造一个万维标准的网站吧!

      -W3C Markup Validation    网址: http://validator.w3.org/

      -W3C CSS Validation        网址:http://jigsaw.w3.org/css-validator/

      -W3C mobileOK Checker    网址:http://validator.w3.org/mobile/

      -W3C Link Checker         网址:http://validator.w3.org/checklink

      -W3C Feed Validation Service 网址:http://validator.w3.org/feed/

      浏览器的标准测试链接:

      CSS测试:http://www.w3.org/Style/CSS/Test/(CSS2.1的测试页面:http://www.w3.org/Style/CSS/Test/CSS2.1/current/)

      ACID3测试: http://acid3.acidtests.org/  各浏览器的测试结果(http://www.anomalousanomaly.com/2008/03/06/acid-3/)

      Acid2测试:http://acid2.acidtests.org/

      各种ACID测试可以到http://www.acidtests.org/上面测试

      可以参考IE8的测试中心网站:http://samples.msdn.microsoft.com/ietestcenter/ ,当然IE不是很全了

  • Android介绍

    paulinetina 发布于 2010-08-10 10:35:35

    转自:http://yahaitt.javaeye.com/blog/453018

    Android平台是一组面向移动设备的软件包,它包含了一个操作系统、中间件和关键应用程序。开发人员可以使用Android SDK(软件开发工具包)为这个平台创造应用程序。应用程序使用Java语言编写并在Dalvik之内运行。Dalvik是一款量身定制的虚拟机,它专为嵌入式应用设计,运行在Linux内核上层。

    如果你想了解如何为Android平台开发应用程序,你就来对地方了!为了帮助大家了解Android平台进而开发移动应用程序,这里 提供了各种丰富的文档。

    Android SDK 的预览版已经可以下载 了。其中包括了附含源代码的样例工程、开发工具、仿真器,当然了,还有你构建工程所必需的类库。

    Android是什么?

    机器人?

    android_robot                                 

    Android是一组面向移动设备的软件包,包含了一个操作系统,中间件和关键应用程序。Android SDK 的预览版提供了必需的开发工具和应用程序接口,基于这些,我们就可以使用Java编程语言在Android平台上开发应用程序了。

    androidos 有点Linux风格吧

     

    特性

    • 应用程序框架 支持组件的复用和更换
    • Dalvik 虚拟机 专门为移动设备进行过优化
    • 集成的浏览器 基于开源的 WebKit 引擎
    • 优化的图形机制 自定义的2D图形库,基于OpenGL ES 1.0规范的3D图形实现(本项为硬件加速器可选)
    • SQLite 轻量级的数据库,支持结构化数据的存储
    • 媒体支持 面向常见的音频、视频以及静态图形档案格式 (MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF)
    • GSM 技术 GSM:global system for mobile communications (依赖硬件支持)
    • Bluetooth, EDGE, 3G, and WiFi (依赖硬件支持)
    • Camera, GPS, compass, and accelerometer (依赖硬件支持)
    • Rich development environment 丰富的开发环境,包含一套硬件仿真器,一些用于程序调试、内存和性能剖析的工具,以及支持Eclipse集成开发环境的插件(ADT )。

    Android架构

    下方图表显示了Android操作系统的主要组件。要知道关于各个部分更多的细节,下文还有描述,请继续看。

    system-architecture

     

    Applications (应用)

    Android将预装一组核心应用程序,包括email客户端、短信服务、日历日程、地图服务、浏览器、联系人和其他应用程序。所有应用程序都是Java编程语言编写的。

     

     

    Application Frameworks (应用框架)

    上文所提的核心应用程序就是依赖框架层次API开发的,程序员们当然也可以充分使用这些API。应用架构设计的初衷是:简化组件复用机制;任何应用都能发布自己的功能,这些功能又可以被任何其他应用使用(当然要受来自框架的强制安全规范的约束)。和复用机制相同,框架允许组件的更换。

    所有应用都是一组服务和系统,一般包含:

    • 一套丰富且可扩展的视图 组件,含有lists, grids, text boxes, buttons, 甚至嵌入的网络浏览器
    • Content Providers (内容提供器) 使一个应用可以访问另外一个应用的数据(如联系人),或者使一个应用内部可以共享自身数据
    • Resource Manager (资源管理器),提供对非编码资源——例如本地化字符串、图形和布局文件——的访问通道
    • Notification Manager (通告管理器),使应用在状态栏显示自定义的警报通知。
    • Activity Manager (行动管理器)负责管理应用的生命周期,提供通用导航回退支持

    要知道更多细节,了解应用内幕,请参考教程 《Android应用编写》

     

     

     

    Libraries (库)

    Android包含一套C/C++库,Android系统的各式组件都在使用。这些功能通过Android应用框架暴露给开发人员。下面列举一些核心库:

     

    • System C library - 衍生于BSD的标准C系统库(libc)实现(注:BSD:Berkeley Software Distribution,伯克利软件套件,是Unix的衍生系统,1970年代由伯克利加州大学开创),尤其支持嵌入式的基于Linux的设备。
    • Media Libraries - 媒体库基于PacketVideo's OpenCORE;媒体库支持很多流行音频和视频格式、静态图形文件(包括MPEG4, H.264, MP3, AAC, AMR, JPG, and PNG )的播放和录制
    • Surface Manager - 管理范围:对子系统显示功能的访问,跨应用的无缝组合2D和2D图形层
    • LibWebCore - 是流行的浏览器引擎,可以支持Android浏览器和嵌入应用的WEB视图组件
    • SGL - 底层的2D图形引擎
    • 3D libraries - 基于OpenGL ES 1.0 API的实现; 该类库使用硬件3D加速器(如果硬件支持的话)或者内置的、高度优化的3D软件加速机制。
    • FreeType - 支持位图和矢量字体
    • SQLite - 能干、轻量级的关系型数据库引擎,面向所有应用

    Android Runtime (Android运行时)

    Android的核心类库提供Java类库所提供的绝大部分功能。

    每个Android应用都运行在自己的进程上,享有Dalvik虚拟机为它分配的专有实例。为了支持多个虚拟机在同一个设备上高效运行,Dalvik被改写过。

    Dalvik虚拟机执行的是Dalvik格式的可执行文件(.dex)——该格式经过优化,以降低内存耗用到最低。Java编译器将Java源文件转为class文件,class文件又被内置的dx工具转化为dex格式文件,这种文件在Dalvik虚拟机上注册并运行。

    在一些底层功能——比如线程和低内存管理方面,Dalvik虚拟机是依赖Linux内核的。

     

    Linux Kernel (Linux内核)

    Android依赖Linux 2.6版,提供核心系统服务:安全、内存管理、进程管理、网络组、驱动模型。内核部分还相当于一个介于硬件层和系统中其他软件组之间的一个抽象层次。

  • Android自动化测试工具

    hansen.liu 发布于 2010-06-21 13:22:51

    Android自动化测试相对来说还是比较难,Instrumentation比较难以使用。下面和大家分享一个Android自动化测试工具Robotium

    Robotium是一款测试Android App的测试框架,它使得编写黑盒测试代码更加容易和稳定。通过使用Robotium,测试用例开发人员能够跨越多个Activity,开发出功能,系统以及验收测试用例。

    下面的例子为测试Android Calculator应用程序:

    public class NotePadTest extends ActivityInstrumentationTestCase2<Calculator> {

    private Solo solo;

    public NotePadTest() {
    super("com.android.calculator2", Calculator.class);

    }

    public void setUp() throws Exception {
    solo = new Solo(getInstrumentation(), getActivity());
    }

    @Override
    public void tearDown() throws Exception {
    try {
    solo.finalize();
    } catch (Throwable e) {
    e.printStackTrace();
    }
    getActivity().finish();
    super.tearDown();
    }

    public void testPreferenceIsSaved() throws Exception {
    solo.clickOnText("7");
    solo.clickOnText("\\+");
    solo.clickOnText("9");
    solo.clickOnText("=");
    Assert.assertTrue(solo.searchText("16"));
    }
    }
  • Android自动化测试

    hansen.liu 发布于 2010-06-18 15:45:20

  • 学习资料的一些网站收藏

    张晓南 发布于 2011-02-17 11:38:18

    一、新手必看资料


    1、软件开发的科学和艺术之软件测试
    http://bbs.51testing.com/thread-137737-1-29.html
    2、回报社会大集合
    http://bbs.51testing.com/thread-179155-1-1.html
    3、web测试的一些经验分享
    http://bbs.51testing.com/thread-171903-1-1.html
    4、软件测试综合资料库
    http://bbs.51testing.com/thread-79154-1-20.html
    5、软件测试总结----新手必看 【
    http://bbs.51testing.com/thread-107659-1-2.html
    软件测试基本理论简介,介绍了软件测试中基本所有的术语、自动化工具分类。可以作为面试基础教材看。很全面,但比较简略。
    6、软件测试新手学习宝典
    http://bbs.51testing.com/thread-96312-1-1.html
    7、软件测试职业道德和工作责任
    http://bbs.51testing.com/thread-55158-1-1.html
    8、关于web测试资料集
    http://bbs.51testing.com/thread-253078-1-1.html

    二、做好测试工程师要会哪些知识技能、自学方向


    1、知识技能、空闲时自学方向
    http://bbs.51testing.com/thread-137662-1-7.html
    说的比较宽泛,感觉对我没太多帮助,建议还是根据自己的需求来。。
    2、软件测试培训、是否可以自学测试
    http://bbs.51testing.com/thread-140054-1-1.html
    挺有道理的,适合没上路的新人朋友
    3、软件测试从这里开始V1.0.0.0
    http://bbs.51testing.com/thread-78735-1-1.html
    4、经典《测试指南》
    http://bbs.51testing.com/thread-134848-1-1.html
    5、软件测试基础知识培训PDF
    http://bbs.51testing.com/thread-2160-1-1.html
    6、软件测试基本方法
    http://bbs.51testing.com/thread-13775-1-3.html

    三、了解别人的测试经历,学习别人经验


    1、我的测试历程[精华] 【
    http://bbs.51testing.com/thread-173152-1-2.html
    很好的资料,前两篇介绍的经验很重要,安装测试文档很经典。
    2、6年的测试经历
    http://bbs.51testing.com/thread-95214-1-4.html
    感觉写的是软件开发经历,不过某些观点可以看看
    3、对于测试感到迷茫该怎么办
    http://bbs.51testing.com/thread-139934-1-3.html
    我很迷茫,但我看了这个没啥收获。没有实质内容。
    4、写给新朋友的,我的经历
    http://bbs.51testing.com/thread-131041-1-10.html
    挺朴实,挺感人的
    5、写给测试新手——作者阳光
    http://bbs.51testing.com/thread-113232-1-2.html
    6、半年内学好软件测试不是神话
    http://bbs.51testing.com/thread-151951-1-5.html

    四、借鉴别人的经验


    1、我的测试观
    http://bbs.51testing.com/thread-172024-1-1.html
    2、[新手上路]给想要学习软件测试同学们的建议
    http://bbs.51testing.com/thread-65437-1-1.html
    3、经典软件测试网站
    http://bbs.51testing.com/thread-51985-1-17.html
    4、软件测试从零开始
    http://bbs.51testing.com/thread-145021-1-1.html
    5、新手怎么入手软件测试
    http://bbs.51testing.com/thread-155804-1-1.html
    6、【转帖】我的测试观点与经验--cleverman
    http://bbs.51testing.com/thread-184349-1-1.html
    7.写给软件测试新手:我的软件测试的学习过程加资料。
    http://bbs.51testing.com/thread-209521-1-2.html


    五.测试人员要掌握的知识及模板


    1、测试的基本概念
    http://bbs.51testing.com/thread-51190-1-9.html
    2、软件测试网络资料大集合
    http://bbs.51testing.com/thread-3229-1-10.html
    3、测试资料
    http://bbs.51testing.com/thread-129350-1-29.html
    4、测试基础资料
    http://bbs.51testing.com/thread-119493-1-31.html
    5、测试人员要掌握的数据库知识
    http://bbs.51testing.com/thread-133499-1-3.html
    6、软件测试专业术语对照表
    http://bbs.51testing.com/thread-107534-1-10.html
    7、软件测试的详细流程
    http://bbs.51testing.com/thread-131087-1-5.html
    8、教你如何书写测试计划
    http://bbs.51testing.com/thread-81583-1-24.html
    9、一个可供参考的软件测试报告
    http://bbs.51testing.com/thread-36263-1-3.html
    10、精典测试计划模板实例
    http://bbs.51testing.com/thread-24839-1-4.html

    六.测试类书籍


    1、软件测试的艺术[第二版中文]
    http://bbs.51testing.com/thread-67373-1-2.html
    2、《软件测试自动化》
    http://bbs.51testing.com/thread-73329-1-3.html
    5、测试书籍
    http://bbs.51testing.com/thread-130536-1-6.html
    3、《软件测试工程师培训教程》
    http://bbs.51testing.com/thread-134377-1-3.html
    4、有效软件测试的50条建议中文版+英文原版
    http://bbs.51testing.com/thread-112262-1-4.html
    5、《软件测试经验与教训》
    http://bbs.51testing.com/thread-117962-1-5.html
    6、软件测试(原书中文第二版)PDF版
    http://bbs.51testing.com/thread-140368-1-1.html
    7、软件测试[(美)Ron Patton]基础知识读书笔记
    http://bbs.51testing.com/thread-66400-1-26.html
    雪舞奉天的读书笔记,原来他是17testing的版主。该笔记通俗易懂,很多概念和思想都来源于此。
    8、软件测试文件编制规范和单元测试
    http://bbs.51testing.com/thread-171480-1-1.html

    七、QTP资料



    QTP 功能自动化工具,适合在回归测试阶段和冒烟测试中使用,局限性比较大。
    1、QTP9.2软件下载
    http://hi.baidu.com/%B9%FE%C2%DE ... 3102d98db10d91.html
    3、QTP视频----入门与实践
    http://bbs.51testing.com/thread-106440-1-1.html
    4、QTP板块上的常用辅助工具
    http://bbs.51testing.com/thread-75966-1-1.html
    5、【QTP版资料大汇总】
    http://bbs.51testing.com/thread-137554-1-1.html
    6、QTP学习入门资料征集
    http://bbs.51testing.com/thread-170892-1-1.html
    7、征集QTP的问题
    http://bbs.51testing.com/thread-146249-1-1.html
    8、QuickTest Pro资料大集合(第20楼有好东西哦Main_Users_Guide.pdf这个很难找但很有用哈哈)
    http://bbs.51testing.com/thread-30476-1-1.html

        八、软件评测师考试资料
    1、软考 软件评测师复习知识点
    http://bbs.51testing.com/viewthread.php?tid=115736&highlight=%C8%ED%BC%FE%C6%C0%B2%E2%CA%A6
    2、软件评测师考试考点分析与真题详解[下载][pdg]
    http://bbs.51testing.com/viewthread.php?tid=141580&highlight=%C8%ED%BC%FE%C6%C0%B2%E2%CA%A6
    3、分享05-09年软件评测师试题及答案
    http://bbs.51testing.com/viewthread.php?tid=147078&highlight=%C8%ED%BC%FE%C6%C0%B2%E2%CA%A6
    4、软件评测师考试交流群
    http://bbs.51testing.com/viewthread.php?tid=283225&highlight=%C8%ED%BC%FE%C6%C0%B2%E2%CA%A6
    http://bbs.51testing.com/viewthread.php?tid=132143&highlight=%C8%ED%BC%FE%C6%C0%B2%E2%CA%A6
    http://bbs.51testing.com/viewthread.php?tid=295911&highlight=%C8%ED%BC%FE%C6%C0%B2%E2%CA%A6

    九、附加资料学习类


    1、要学SQL的往这看,sql学习资料(免费)更新
    http://bbs.51testing.com/thread-101279-1-1.html
    2、想学习sql的,看看这个吧
    http://bbs.51testing.com/thread-170231-1-1.html
    3、Oracle学习资料
    http://bbs.51testing.com/thread-173195-1-1.html
    4、oracle傻瓜手册
    http://bbs.51testing.com/thread-72991-1-7.html
    5、历史上最全的Oracle SQL函数大总结
    http://bbs.51testing.com/thread-66758-1-7.html
    6、sql试题查询答案
    http://bbs.51testing.com/thread-175348-1-1.html
    7、《Red Hat Linux 9系统管理员完全学习手册》
    http://bbs.51testing.com/thread-48966-1-28.html
    8、关于linux系统学习资料大全
    http://bbs.51testing.com/thread-171168-1-1.html
    9、分享---职业发展板块好文
    http://bbs.51testing.com/thread-171277-1-1.html
    *资源共享篇
    1.软件测试资料大派送中
    http://bbs.51testing.com/thread-165543-1-1.html
    2.软件测试视频大派送
    http://bbs.51testing.com/thread-283175-1-1.html
  • Verification and Validation

    lhd85 发布于 2011-02-27 12:21:01

    以下是本人在网上搜罗的一些关于Verification 和 Validation 两者之间比较的区别, 仅供参考 
     
    改行做tester已经一个月左右,我的mentor远在万里之外的美国,记得第一次指导,他通过远洋电话说tester除了要测试对与错之外,还要侧重是否是有效的。换言之,就是本文说得是Verification和Validation。Verification也就是说要做正确、而Validation是看经过Verification是否是我们想要的。       Verificaiton是我们可以预见的,在测试以前就知道我们期望一个什么结果。例如我要找GF,首先对方要是个女的,if(Person.gender!=female) return false;做IC的,读卡器芯片,必须能够读相应的数码卡;做sales的,评价Performance的标准每个月的销售额就是Verification的标准,Verification是否可以说是理性思维大于感性。1是1,2是2。而Validation首先前提是经过Verification,重要的是做的是否是customer需要的。拿刚才三个例子,我相信任何一个人找对象,不会只需要一个异性。验证Validation,还要看是否是自己喜欢的; IC做出来了,是否市场真的需要。做sales,除了销售额,是否让客户买对了产品,是否增加了客户的忠诚度,是否合乎客户使用习惯应该是Validation过程。 可以说Validation更多的是感性因素多,也是一个及其难以掌握的事情。毕竟,think from others是一件非常难的事情。      看看windows xp,尽管安全问题依旧,但是很多用户会毫不犹豫地抛弃win98。其实经过调查,大多数原因是界面比以前漂亮友好了很多。而且使用方面,和之前的版本对于绝大多数人来说能够最大程度保持一致。 Microsoft的可怕不在于技术,而在于它能够让我们养成了习惯,习惯是很难改变的,而掌握了客户的习惯和心态,这正是做Validation的极高境界。      不多说了,下周末又有一场婚礼要参加。看样又有一对新人经历了Verifiaction和Validation。
     
    Verification
    Although “verification” and “validation” at first seem quite similar in
    CMMI models, on closer inspection you can see that each addresses
    different issues. Verification confirms that work products properly reflect
    the requirements specified for them. In other words, verification ensures
    that “you built it right".
     
    Validation
    Validation confirms that the product, as provided, will fulfill its intended
    use. In other words, validation ensures that “you built the right thing.”
     
    Verification - 确证 -- 对已有结果加以核实, 关键在于 verify -- 再次证明
    Validation - 验证 -- 对结果的有效合理性加以验证, 关键在于validity -- 合理性
     
    Verification是验证,是通过提供客观证据证明规定的要求是否得到满足,也就是说,输入与输出比较.
    Validation是确认,是在验证好的基础上,对预期的使用和应用要求是否得到满足,也就是说,在确认时,应考虑使用和应用的条件范围要远远大于输入时确定的范围.一般是由客户或代表客户的人执行.
     
  • 转载:深入Android【八】 —— Activity间数据传输

    51_51testing 发布于 2010-10-05 15:32:11

    转载自:http://www.cnblogs.com/duguguiyu/archive/2010/05/29/1747244.html

    Activity间数据传输

    当对Android有一些了解后,不难发现,Android程序UI框架接近于Web页面的概念。每一个用于呈现页面的组件,Activity,都是彼此独立的,它们通过系统核心来调度整合,彼此之间的通过Intent机制来串联。
    每一种架构都会有其利弊,Android当然也不能超然脱俗。由于Activity之间的松耦合关系,使得其复用能力特别的出色,Mash-Up方式可以有效的提高开发效率。但另一方面,由于Activity过于的独立,它们之间的数据共享,成为一个麻烦的事情。

    基于消息的传输

    最标准的Activity之间的数据传输,就是通过Intent的Extra对象。比如,你在A这个Activity上拿到一坨用户输入的文本信息,兴高采烈的想把它放到B这个Activity上展示并发送,一个很可行的方式,是通过Intent的putExtra接口,把用户输入的那些字符信息,按照key/value的形式放进Intent,传输到B这个Activity上。



    如上图示,从A到B的传输,看上去是一个直连,但其实,Intent都是要经由系统核心层去分析调度的,这个操作,跨越了进程边界,自然而然,其中的数据,就是需要序列化和反序列化的,而不可以仅通过一个指针就倒腾过去了。
    基于这样类消息的传输模式,好处不多说,直接谈问题:
    • 首先,对于大数据,就是一场杯具,不可能一坨上M的数据,也来来回回的传来传去,慢死了谁来负责;
    • 再则,Activity之间,维系的是一种线性关系,当我想把一份数据,从队尾一级级传到队头的话,自己历经磨难不提,会把中间所有的Activity都搭上,他们明明自己可能不需要这份数据,也得拿着搁着,为他人做嫁衣裳,不惆怅都不行;
    • 此外,基于消息的传输,会把同一份数据生成若干个副本,有时候,这样很好,没有副作用,大家自己玩自己的不需要看别人脸色,但还有些时候,你就上杆子需要把这些数据都修改一下,同步起来那就太惨烈了;
    • 最后,写序列化代码实在是太无聊了,稍微复杂点的代码,就要自己写个序列化接口,整个吃力不讨好的活计。

    基于外部存储的传输

    既然兽兽手手相传太幸苦,自然而然的想法就是找个地方,A把数据搁在那里,把地址信息告诉B,B需要的话,按图索骥,自取就好。这个搁东西的地方,可以考虑选择外部存储
    在Android中,预设了一些快捷便利类和模块,更好的支持不同类别数据的存取。如果,需要存储的是一些小数据量的配置信息,可以选择Preference,它等同于传统意义上的设置文件。Preference提供了一些基于key/value的存取接口,可以放置一些简单的基本数据或者派生了Parcelable接口的对象。一个很好的应用场景是Cookie的存放。你在登录界面获得了一份Cookie,你可以把它扔进Preference,谁想要谁去拿,再也不要来来回回的折腾了。
    Preference适合于小数据、设置信息,如果大数据,你可以考虑使用数据库。在Android中,使用的是Sqlite,相关的类,堆放在android.database名字空间下,自查,无需赘述。
    在Android里,数据库是私有的,如果想分享给第三方组件使用,就需要用ContentProvider来封装了。比如你用系统的录音机组件即时搞一段音频信息,它不是返回可能大到恐怖的录音数据,而是会返回给你一个Uri,它标明了这份数据在ContentProvider的地址信息,拿着这个Uri,领取数据就好。
    当然当然,如果你足够淡定,也可以用赤果果的File来存储。如果这个文件存在手机私有目录下,那就内部使用,放在SD卡上,那就可以所有应用,一切分享。



    基于这样外部存储的数据传输,优缺点显而易见,它解决了困扰Intent的传输路径复杂,不利于传输大批量数据的问题,但同时,它有留下了效率隐患,复杂了编程模型。因为面对外部存储,开发者必须要考虑效率问题,很多时候,多线程就会被提上议程,这样,想不麻烦,都不行鸟。

    基于Service的传输

    既然存在外部太慢,那么还是在内存级别解决问题好了,这时候,你可能就需要请出Android四大组件之一的Service了。Service设计的本意,就是提供一些后台的服务,数据存取,也可以归于其职责的一部分。
    Service是提供了直连机制,调用的Activity,可以通过bindService方法,与目标Service建立一条数据通路,拿到IBinder。这样,通过Android提供的IPC模型,就可以进行远程方法的调用和数据的传输了。 



    如上,通过这种模式,可以解决一定问题,但是对于Service来说,实在是太大才小用了,Service的专长,不是在数据,还是在逻辑。对于传数据而言,Service还是重量了一点,不但是有连接耗精力,传输经由IPC,写起来也够费劲。而且作为组件,Service随时可能死掉,你还是要费劲心机的处理数据的持久化,得不偿失。

    利用Application传输

    好吧,如果你需要在不同页面之间共有某个内存对象,很合适的一种方式是把它们扔到Application里面。Application是Context的一个子类,它会在整个应用任何一个组件起来之前,先起来嘘嘘。它的生命周期会贯穿整个应用所有组件的生命旅途,因此,放在其中的对象,不会被处理掉。
    在Activity中,可以通过getApplication接口,随时获得Application对象的引用,用于实现一些全局对象的存储,和处理,真是最合适不过的地方了。



    当然,好东西也不要使用过度,可以想象,由于Application存活周期长,其上引用的对象一直缺少被释放的机会,如果你把它当成垃圾场,什么东西都往里扔,污染环境,混乱逻辑不提,单就是滥用内存资源这一项,就够罪孽深重一把了。
    因此,如果数据不是真的需要全局使用,不要搁在其中,如果数据太大,不要全部load出来,合理使用数据库等外存储设备,还是必须要的。

    结语

    还有一些特殊情况,可以考虑用一些特殊的方式。比如子Activity之间,可以通过调用getParent获得父Activity的引用,来访问期间的对象,云云。小众情况,姑且不提。
    以上这些概念,我相信所有的coder都了如指掌,如何处理这样的数据,都心如明镜。我只是给它们套上了一件Android的外衣,让初入Android的coder们,能迅速找到心仪的兵器,劈山砍石,攻城拔寨。
  • 转载:深入Android【七】 —— 资源文件

    51_51testing 发布于 2010-10-05 15:30:20

    转载自:http://www.cnblogs.com/duguguiyu/archive/2010/05/02/1726069.html

    资源文件

    作为一枚coder,做界面,很多时候都是一场梦魇。很多时候,我们会感觉对于底层逻辑实现的很有把握性,哪怕需求一直在变,也可以通过不断的重构一直跟进,一切尽在掌握。但遭遇界面,往往就不再如此,它的好坏总是和审美、体验之类的词汇扯在一起,在凤姐芙蓉出没的年头,谈审美成为一件恐怖的事情。你可能会被要求不停的改代码,就为了移动一个像素,调整一枚按钮,琐碎而无聊。
    为了改变这样的状况,挽救coder们于水生活热之中,很多开发平台,都采用了类似于资源文件的解决方案。此类方案的基本思想是,将界面的实现与底层逻辑的实现完全剥离开来,用资源文件这样的东西来描述界面。资源文件的描述语言,往往是结构化很强,比如Html,Xml(及其变形体)之类的。于开发语言相比,此类语言逻辑性较弱但结构更好可读性更强更容易理解,并对自动化工具非常友好,可以于界面的拖拽配置结合的更加完美。这样的剥离,可以是的底层逻辑和上层界面独立变化,甚至不同的人员开发(这一点在web开发上表现的应该很明显...),两者之间的耦合性非常的小,coder们的负担,陡然减少(好吧,一个很挫的资源架构也会额外增加开发人员的负担,Symbian同学,请不要对号入座...)。

    结构和格式

    Android的资源文件,是由目录结构Xml格式的文件,和纯数据文件构成。从格式上来看,无疑,学习门槛非常低。Xml作为coder们的瑞士军刀,哪怕使不习惯,弄得清楚并会用至少是没有问题。从配套的工具来看,Android的ADT,提供了一套可视化的配置工具,说不上特别好用,但至少是差强人意能凑合着用,比不上iPhone的,调戏Symbian还是没有问题的[强档广告首播:有道词典 for iPhone新版火热上线,增加了超强单词本功能,特有的触电式颤抖单词切换功能,让你欲罢不能,持有相关设备的童鞋不要犹豫,一拥而上吧...]。
    Android的资源文件,覆盖面超级广,只要是和界面相关的,都可以用资源文件表示,比如:UI的样式,菜单,配置文件,各种描述性字符串,图片,音频视频文件,动画,颜色,尺寸,风格和样式,等等等。所有的资源文件(不考虑asset,它和讨论暂无关联...),都放在res目录下,不同类别的资源,需要放置在不同的特定名称的子文件夹中,或者是写在特定文件名的文件中(或者ms不是必须的,但,不用在这里特立独行,寻章办事也挺好...)。比如,所有作为UI背景之类的图片,都需要扔在drawable这类的文件夹中,所有字符串相关的,都会放到values目录下形如strings.xml这样的文件中(如下图所示,是一个资源文件目录结构的截图...)。

    每个xml文件,都有一定的约定。比如一个字符串,会放在<string></string>这样的xml element中(如下图所示...),你可以通过eclipse的ADT插件提供的可是界面去填而不关注具体规范,也可以直接人肉打造,前者对于新手来说更为直观,后者对于老鸟而言更为迅捷。


    可配置性

    程序逻辑总是不变应万变的,但界面往往是需要能够72变。首先一种变化因素,就是状态。想象一下,我们往往会有这样类似的需求,一个按钮,我们需要没有按下去的时候是一种背景,按的过程中刷的变成另一副模样,当它可用的时候需要鲜鲜亮的一个样子,不可用的时候最好是灰不溜秋没人愿点的怂样,诸如此类。传统编程模型下(Symbian,哥叫你出来当模特...),我们总是需要不厌其烦的用代码控制这样的事情。监听不同的事件,见缝插针的切换背景,并祈祷上天,千万别让哥调整,否则哥和你没完。



    在Android中,做这个事情,变得简单许多,通过预设的一些Xml属性,能够轻松的搞定。如上图所示,是Radio Button的背景。通过搭配不同的属性,就可以自动转换背景。比如第一个<item>,说的是当Radio Button被选中,并且具有焦点的时候,显示btn_radio_on这幅图片,而最后一个<item>,说的是前述条件都不满足,并且处于选中状态,那么显示btn_radio_on这幅图片。
    另外一个更易变的因素,就是手机硬件/软件环境了,毕竟,不是家家都是苹果,一个平台搭一款手机,手机款形多样化,几乎是避免不了的问题。没有人希望自己做的软件在大屏幕手机上闪亮光鲜,换个小屏幕就惨不忍睹,竖屏看像那么回事横屏看就挤做一团。还有就是语言环境了,做为一个有国际眼光的coder,作面向世界的NB软件是咱的梦想,但我们不能因为自己的梦想逼迫大家都去学中文,做一款软件可以根据手机的语言环境选择最合适展示的语言,很多时候,是一个需要具备的功能点。
    在Android中,实现这些,都是举手之劳。方法就是将和环境相关的资源,放入特定名称的文件夹中。比如,表示简体中文字符信息的资源,可以放到values-zh-rCN中去,当系统语言环境为简体中文时,就会呈现出中文的字符信息。在Android中,很多相关配置项,都可以按照这样的方式参与到资源自适应的活动中来,包括屏幕大小,屏幕朝向,屏幕分辨率,语言环境,触屏类型,SDK版本等等。系统会给所有配置项一个优先级(或者说权重,次序之类的),当用户提供了多份资源的时候,系统会根据优先级从高到底淘汰备选资源,如果淘汰仅剩了一个,那就是最符合当前系统软硬件语言环境的资源项,如果一个不剩,择启用默认项(最是形如values这样没有任何尾巴目录中的资源...)。因此,默认的资源是非常重要的,它必须是其他所有可选资源项的超集,否则在资源选择失败的情况下,应用会凄凉的崩溃。
    关于资源配置,以及选择的详情,参见SDK中的:guide/topics/resources/resources-i18n.html部分。

    R类

    在使用资源后,界面逻辑与底层逻辑的耦合被降低了,但这不意味着,两者没有关联了。比如,需要为某个按钮增加一个点击事件,就需要定位到所需的那个按钮;再比如,你需要使用某个字符串资源,通知用户某件事情,就需要能定位到资源中放置的该字串。
    最显而易见的一种方式,就是通过字符串比较,用名字信息在资源的xml描述文件中定位到所需的内容,加载并使用。这种方式,解决了查找的问题,但反复的字符串比较,势必带来严重的效率隐患。因此,在Android中,类似于Symbian的方法,引入了一个R类。
    它的基本思想是,通过增加一个额外的编译器,为所有的资源项,都赋予一个32位的整形数来表示,同一个资源像的不同配置,都使用同一个id。这个整形数,就相当于这个资源项的门牌号码,能够帮助定位到对应的资源项。所有的这些整形数,都以常量的方式,整合到一个Java类中,这个类就是R类。这样,在程序中,就可以通过使用这个R类,来查找所需的资源,这就将字符串比较,简化成了一个整形数的比较,大大的节约了开销。
    不得不说,这整套逻辑和Symbian中的资源文件预编译一致。但两者很不同的点在于Symbian中的整形数,代表的是一个二进制流的偏移量,资源中的内容在编译时决定了。而Android中的整形数,是一个有逻辑意义的数值,它表达了这个资源所处的资源包,类别,和脚标,它的具体内容在运行时才确定,这使得它的灵活性大大增强,付出的则是一定的效率代价

    实现

    按照惯例,还是要说实现的,以一个查找流程为示例。当在Activity中需要使用字符串的,会调用它的getString方法,传入R.stirng.xxx的一个整形数,换取一个符合当前机器环境配置的字符串。
    getString,追根溯源,来到AssetManager类中。Asset类,其实是一个空壳,它仅仅是提供了一些便利的接口,而将请求,通过JNI的接口,传入到了底层C++实现的类库中。
    在底层的实现,主要是在C++实现的,AssetManager,ResourceTypes等等之中。其中:
    • JNI文件在:framework/base/core/jni
    • 头文件在:framework/base/include/utils
    • CPP文件在:framework/base/libs/utils

    具体实现,和前述的算法逻辑是一致的。每一个资源的id,32位,高8位表示资源包,低16位用于描述脚标,中间8位,用来说明类别。所有资源中的文件,都被预处理了,放入到了一系列的队列和表中,通过id,可以查到具体的位置。然后根据缓存的环境设置对象,跑一次淘汰算法,获得匹配的资源对象的对应文件和偏移量。然后将值读取出来,通过JNI接口,拷贝回去。
    以上这些描述,并不能帮助了解真实的实现细节,主要是为了促使大家对读取资源的效率有一个比较直观的认知。整个资源读取的流程比较长,但是实现在C++中,可以预想,效率比Java高一些,开发人员,应该能够根据自己的需求,决定是否将内容写入资源文件中(还是写在代码中...),是不是需要自己稍微缓存一下,诸如此类。 
  • 转载:深入Android 【六】 —— 界面构造

    51_51testing 发布于 2010-10-05 15:25:34

    转载自:

    界面构造

    UI界面,对于每个应用而言,是它与用户进行交互的门脸。好的门脸,不只是是要亮丽可人,最好还能秀色可餐过目不忘,甚至还应该有涵养有气质,彬彬有理温柔耐心。
    对于开发者来说,锻造这样的面容,不但需要高超的技艺,也需要有称手的工具和对得起党的料子。俗话说,朽木不可雕也,芙蓉不是一日炼成的,不是什么平台都能叫特能书。有套好用的UI框架,对于开发者而言,真有如沙漠中的甘露,而要是撞见了杯具的UI套件,整个界面开发就有如梦魇了。
    Android的UI框架,最核心的,是资源Layout体系,然后,通过完善的控件库,简明的接口设计,进一步帮助开发者,能够最快的搭建自己需要界面(听到这里,Symbian同学开始钻土...)。

    UI控件

    做UI,有时候就像搭积木,在Android中,这个最原子的积木块,就是View。所有其他的UI元素,都是派生于此类的子孙类们。



    又从SDK中偷来张图,用来描述Android的UI控件结构,在每一个window下,这都是一个标准而完整的树结构。View有一个子类ViewGroup,它相当于一个容器类或者是复合控件,所有派生与ViewGroup的子类在这颗UI树中都可以承担着父节点的职责,而另一些绕过ViewGroup从View直通下来的,就只能蜷局在叶节点的范畴内了。
    之所有说这是一个很标准的控件树,是因为父控件对子控件有绝对的掌控权,每个子控件的占地面积和位置,都是基于父控件来分配的,它能够接受和处理的事件,也是父控件派发下去的。这样的结构,被很多平台和框架广泛的认可,和传统的win开发和杯具的Symbian相比,虽然因为事件传播途径变长了,很多操作的效率变低了,但整个结构更有层次性,每个控件只需要多其父控件负责指挥子控件就好,职责明确,逻辑简单,利于开发和设计。
    谈及任何平台的控件,都有一些不可避免的主题,比如,每个控件如何标识,如何设定大小和位置,如何接受和处理事件,如何绘制,诸如此类。

    标识

    在Android中,你可以为每个控件选择设定一个id,这个id的全局的唯一性不需要保证,但在某个局部的范围内具有可识别性,这样就可以通过这个id找到这个控件(如果不需要查找,就别设置了...)。
    但是,在父控件中逐级的find比较,找到id匹配的控件,然后再做转型,是一个比较重量的操作,于是Android又为控件憋出另一个属性,tag。它接受任意object类型的数据,你可以把和这个控件对象相关的内容堆在里面。比如,在list中,我们常常将和每个list item相关的所有控件元素封装成一个object,扔到tag中,就不需要每次都去比较id进行寻找,更加高效快捷。

    尺寸

    在Android中,控件最重要的大小属性,就是width/height,开发者可以明确的指明控件的大小,可以设定成为fill_parentwrap_content,这样的概念性的大小。丈量并设定控件的位置,是通过两步来进行的。
    第一步是measure。它传入此控件的width/height信息,控件会根据自己的参数,计算出真实需要的width/height,然后调用setMeasuredDimension方法,缓存成成员变量,留作后用。
    在计算出大小之后,会进行另一个步骤,layout。在这个过程中,父控件会计算其上各个子控件的位置,从而完成整个大小和位置的确定流程。整个measure和layout的流程,都是自上到下,从树顶往叶子来推进的。
    当开发人员需要自定义控件的时候,可能需要关注这些内容,通过重载onMeasureonLayout方法,可以定义自己控件的丈量方式。

    事件

    在Android中,所有的按键,触屏等事件,都是从顶至下进行分发的。每个ViewGroup的对象,会维系一个focused变量,它表示在这个父控件中具备focus的控件,当有按键时间发生的时候,会找到这个focused子控件,并传递给它。同理,触屏事件的分发也是类似,只不过和focus无关,父控件会遍历所有子控件,看看谁处于触碰位置,从而传递给谁。
    另外还有一些事件,逻辑上并不是从顶至下发起的。比如,当你修改某个子控件的内容,使得该子控件的大小和内容都发生了变化,就需要进行控件的重排和重绘,这些操作不仅是子控件自己的事情,需要整个控件树上的所有控件都需要配合。在Android中,处理这类事情的实现策略是子控件维系一个ViewParent对象,该对象象征着整个控件树的管理者,子控件产生影响整个控件树的事件时,会通知到ViewParent,ViewParent会将其转换成一个自顶向下的事件,分发下去。
    Android的事件处理逻辑,采用的是观察者模式。Android的控件提供了一些列的add/set Listener的接口,使得外部观察者,有机会处理控件事件。比如,你需要在某个button被点击时做一些事情,你就需要派生一个View.OnClickListener对象作为观察者,调用该控件的setOnClickListener接口注册进去,当button被点击,就可以获得处理点击事件的机会了。当然,有的时候,你需要处理的逻辑更为复杂,光是站在外面围观叫好不能解决问题,可能就需要派生某个控件,去重载onXXXX之类的事件处理函数,进行更完整的控制。

    焦点

    对于一个非触屏的机器,焦点的维系是一个极其重要的事情,而在有触屏的年代,焦点的地位虽有所下降,但依然还是需要妥善保护的。
    Android中,是以控件树为单位,来管理焦点的。每个控件,可以设置上下左右四向的focus转移对象。当在一个控件上发生焦点转移事件,Android会如前述,自顶向下根据设定好的焦点转移逻辑,跳转到正确的控件上。和Symbian相比,真是,真是。。。

    Layout

    Layout是一类特殊的ViewGroup控件,它们本身没有任何可显示内容,形如透明的玻璃盒子,存活的唯一理由,就是其中的内部结构,能够更好的摆放它的子控件们。
    比如线性的Layout,LinearLayout。放入这个Layout的子控件,会按水平或垂直方向,排排坐,一个挨着一个按顺序排列下去。TableLayout,可以将子控件按照表格的形式,一枚枚放置好。而RelativeLayout则更灵活,可以设定各个控件之间的对齐和排列关系,适合定制复杂的界面。
    有了Layout的存在,控件和控件之间不再割裂的存在,而是更有机的结合在了一起,设定起来也更为方便。比Symbian那样人肉维系各个控件的关系,轻松自在多了。

    更多

    这些问题的完整答案,参见SDK中View的页面:/reference/android/view/View.html

    实现

    有了这些对Android的UI控件的认知,可以看更整体性的实现细节,那就是Activity的UI实现。



    如上图所示,假设你做了个如同虚线框中结构的一个界面,通过Activity的setContentView方法,塞进了Activity中,就会形成图示的一个逻辑关系。每一个Activity,都包含一个Window对象,它表示的是一个顶级的一整屏幕上面的界面逻辑。在Android源码中,其实现是MidWindow,它包含了一个FrameLayout对象,呈现出来就是那种带着一个title的界面样子。自定义的一堆控件,会插进Window的界面部分,在Activity中,所有事件的处理逻辑,是Window先享用,没消费掉在交由这堆控件吃剩的。
    在整个控件树的最顶端,是一个逻辑的树顶,ViewParent,在源码中的实现是ViewRoot。它是整个控件树和WindowManager之间的事件信息的翻译者。WindowManager是Android中一个重要的服务。它将用户的操作,翻译成为指令,发送给呈现在界面上的各个Window。Activity,会将顶级的控件注册到WindowManager中,当用户真是触碰屏幕或键盘的时候,WindowManager就会通知到,而当控件有一些请求产生,也会经由ViewParent送回到WindowManager中。从而完成整个通信流程。
  • 转载:深入Android 【三】 —— 组件入门

    51_51testing 发布于 2010-10-05 14:21:47


    横看成岭侧成峰,远近高低各不同。 -- 《题西林壁》
    组件(Component),在谈及所谓架构和重用的时候,是一个重要的事情。很多时候都会说基于组件的软件架构,指的是期望把程序做乐高似的,有一堆接口标准封装完整的组件放在哪里,想用的时候取上几个一搭配,整个程序就构建完成了。
    在开篇的时候就在说,Android是一个为组件化而搭建的平台,它引入所谓Mash-Up的概念,这使得你在应用的最上层,想做的不组件化都是很困难的一件事情(底层逻辑,好吧,管不了...)。具体说来,Android有四大组件四喜丸子:Activity、Service、Broadcast Receiver、Content Provider。

    Activity

    做一个完整的Android程序,不想用到Activity,真的是比较困难的一件事情,除非是想做绿叶想疯了。因为Activity是Android程序与用户交互的窗口,在我看来,从这个层面的视角来看,Android的Activity特像网站的页面。
    首先,一个网站,如果一张页面都没有,那...,真是一颗奇葩。而一张页面往往都有个独立的主题和功能点,比如登录页面,注册页面,管理页面,如是。
    在每个页面里面,会放一些链接,已实现功能点的串联,有的链接点了,刷,跑到同一站点的另一个页面去了;有的链接点了,啾,可能跳到其他网站的页面去;还有的链接点了,恩...,这次没跑,但当前页面的样子可能有所变化了。这些模式,和Activity给人的感觉很像,只不过实现策略不同罢了,毕竟Android这套架构的核心思想,本身就来自源于Web的Mash-Up概念,视为页面的客户端化,也未尝不可。
    Activity,在四大组件中,无疑是最复杂的,这年头,一样东西和界面挂上了勾,都简化不了,想一想,独立做一个应用有多少时间沦落在了界面上,就能琢磨清楚了。从视觉效果来看,一个Activity占据当前的窗口,响应所有窗口事件,具备有控件,菜单等界面元素。从内部逻辑来看,Activity需要为了保持各个界面状态,需要做很多持久化的事情,还需要妥善管理生命周期,和一些转跳逻辑。对于开发者而言,就需要派生一个Activity的子类,然后埋头苦干上述事情。对于Activity的更多细节,先可以参见:reference/android/app/Activity.html。后续,会献上更为详尽的剖析。

    Service

    服务,从最直白的视角来看,就是剥离了界面的Activity,它们在很多Android的概念方面比较接近,都是封装有一个完整的功能逻辑实现,只不过Service不抛头露脸,只是默默无声的做坚实的后盾。
    但其实,换个角度来看,Android中的服务,和我们通常说的Windows服务,Web的后台服务又有一些相近,它们通常都是后台长时间运行,接受上层指令,完成相关事务的模块。用运行模式来看,Activity是跳,从一个跳到一个,呃...,这有点像模态对话框(或者还像web页面好了...),给一个输入(抑或没有...),然后不管不顾的让它运行,离开时返回输出(同抑或没有...)。
    而Service不是,它是等,等着上层连接上它,然后产生一段持久而缠绵的通信,这就像一个用了Ajax页面,看着没啥变化,偷偷摸摸的和Service不知眉来眼去多少回了。
    但和一般的Service还是有所不同,Android的Service和所有四大组件一样,其进程模型都是可以配置的,调用方和发布方都可以有权利来选择是把这个组件运行在同一个进程下,还是不同的进程下。这句话,可以拿把指甲刀刻进脑海中去,它凸显了Android的运行特征。如果一个Service,是有期望运行在于调用方不同进程的时候,就需要利用Android提供的RPC机制,为其部署一套进程间通信的策略。


    Android的RPC实现,如上图所示(好吧,也是从SDK中拿来主义的...),无甚稀奇,基于代理模式的一个实现,在调用端和服务端都去生成一个代理类,做一些序列化和反序列化的事情,使得调用端和服务器端都可以像调用一个本地接口一样使用RPC接口。
    Android中用来做数据序列化的类是Parcel,参见:/reference/android/os/Parcel.html,封装了序列化的细节,向外提供了足够对象化的访问接口,Android号称实现非常高效。
    还有就是AIDL (Android Interface Definition Language) ,一种接口定义的语言,服务的RPC接口,可以用AIDL来描述,这样,ADT就可以帮助你自动生成一整套的代理模式需要用到的类,都是想起来很乏力写起来很苦力的那种。更多内容,可以再看看:guide/developing/tools/aidl.html,如果有兴致,可以找些其他PRC实现的资料lou几眼。
    关于Service的实现,还强推参看API Demos这个Sample里面的RemoteService实现。它完整的展示了实现一个Service需要做的事情:那就是定义好需要接受的Intent,提供同步或异步的接口,在上层绑定了它后,通过这些接口(很多时候都是RPC的...)进行通信。在RPC接口中使用的数据、回调接口对象,如果不是标准的系统实现(系统可序列化的),则需要自定义aidl,所有一切,在这个Sample里都有表达,强荐。
    Service从实现角度看,最特别的就是这些RPC的实现了,其他内容,都会接近于Activity的一些实现,也许不再会详述了。

    Broadcast Receiver

    在实际应用中,我们常需要等,等待系统抑或其他应用发出一道指令,为自己的应用擦亮明灯指明方向。而这种等待,在很多的平台上,都会需要付出不小的代价。
    比如,在Symbian中,你要等待一个来电消息,显示归属地之类的,必须让自己的应用忍辱负重偷偷摸摸的开机启动,消隐图标隐藏任务项,潜伏在后台,监控着相关事件,等待转瞬即逝的出手机会。这是一件很发指的事情,不但白白耗费了系统资源,还留了个流氓软件的骂名,这真是卖力不讨好的正面典型。
    在Android中,充分考虑了广泛的这类需求,于是就有了Broadcast Receiver这样的一个组件。每个Broadcast Receiver都可以接收一种或若干种Intent作为触发事件(有不知道Intent的么,后面会知道了...),当发生这样事件的时候,系统会负责唤醒或传递消息到该Broadcast Receiver,任其处置。在此之前和这以后,Broadcast Receiver是否在运行都变得不重要了,及其绿色环保。
    这个实现机制,显然是基于一种注册方式的,Broadcast Receiver将其特征描述并注册在系统中,根据注册时机,可以分为两类,被我冠名为冷热插拔。所谓冷插拔,就是Broadcast Receiver的相关信息写在配置文件中(求配置文件详情?稍安,后续奉上...),系统会负责在相关事件发生的时候及时通知到该Broadcast Receiver,这种模式适合于这样的场景。某事件方式 -> 通知Broadcast -> 启动相关处理应用。比如,监听来电、邮件、短信之类的,都隶属于这种模式。而热插拔,顾名思义,插拔这样的事情,都是由应用自己来处理的,通常是在OnResume事件中通过registerReceiver进行注册,在OnPause等事件中反注册,通过这种方式使其能够在运行期间保持对相关事件的关注。比如,一款优秀的词典软件(比如,有道词典...),可能会有在运行期间关注网络状况变化的需求,使其可以在有廉价网络的时候优先使用网络查询词汇,在其他情况下,首先通过本地词库来查词,从而兼顾腰包和体验,一举两得一石二鸟一箭双雕(注,真实在有道词典中有这样的能力,但不是通过Broadcast Receiver实现的,仅以为例...)。而这样的监听,只需要在其工作状态下保持就好,不运行的时候,管你是天大的网路变化,与我何干。其模式可以归结为:启动应用 -> 监听事件 -> 发生时进行处理。
    除了接受消息的一方有多种模式,发送者也有很重要的选择权。通常,发送这有两类,一个就是系统本身,我们称之为系统Broadcast消息,在reference/android/content/Intent.html的Standard Broadcast Actions,可以求到相关消息的详情。除了系统,自定义的应用可以放出Broadcast消息,通过的接口可以是Context.sendBroadcast,抑或是Context.sendOrderedBroadcast。前者发出的称为Normal broadcast,所有关注该消息的Receiver,都有机会获得并进行处理;后者放出的称作Ordered broadcasts,顾名思义,接受者需要按资排辈,排在后面的只能吃前面吃剩下的,前面的心情不好私吞了,后面的只能喝西北风了。
    当Broadcast Receiver接收到相关的消息,它们通常做一些简单的处理,然后转化称为一条Notification,一次振铃,一次震动,抑或是启动一个Activity进行进一步的交互和处理。所以,虽然Broadcast整个逻辑不复杂,却是足够有用和好用,它统一了Android的事件广播模型,让很多平台都相形见绌了。更多Broadcast Receiver相关内容,参见:/reference/android/content/BroadcastReceiver.html。

    Content Provider

    Content Provider,听着就和数据相关,没错,这就是Android提供的第三方应用数据的访问方案。在Android中,对数据的保护是很严密的,除了放在SD卡中的数据,一个应用所持有的数据库、文件、等等内容,都是不允许其他直接访问的,但有时候,沟通是必要的,不仅对第三方很重要,对应用自己也很重要。
    比如,一个联系人管理的应用。如果不允许第三方的应用对其联系人数据库进行增删该查,整个应用就失去了可扩展力,必将被其他应用抛弃,然后另立门户,自个玩自个的去了。
    Andorid当然不会真的把每个应用都做成一座孤岛,它为所有应用都准备了一扇窗,这就是Content Provider。应用想对外提供的数据,可以通过派生ContentProvider类,封装成一枚Content Provider,每个Content Provider都用一个uri作为独立的标识,形如:content://com.xxxxx。所有东西看着像REST的样子,但实际上,它比REST更为灵活。和REST类似,uri也可以有两种类型,一种是带id的,另一种是列表的,但实现者不需要按照这个模式来做,给你id的uri你也可以返回列表类型的数据,只要调用者明白,就无妨,不用苛求所谓的REST。
    另外,Content Provider不和REST一样只有uri可用,还可以接受Projection,Selection,OrderBy等参数,这样,就可以像数据库那样进行投影,选择和排序。查询到的结果,以Cursor(参见:reference/android/database/Cursor.html )的形式进行返回,调用者可以移动Cursor来访问各列的数据。
    Content Provider屏蔽了内部数据的存储细节,向外提供了上述统一的接口模型,这样的抽象层次,大大简化了上层应用的书写,也对数据的整合提供了更方便的途径。Content Provider内部,常用数据库来实现,Android提供了强大的Sqlite支持,但很多时候,你也可以封装文件或其他混合的数据。
    在Android中,ContentResolver是用来发起Content Provider的定位和访问的。不过它仅提供了同步访问的Content Provider的接口。但通常,Content Provider需要访问的可能是数据库等大数据源,效率上不足够快,会导致调用线程的拥塞。因此Android提供了一个AsyncQueryHandler(参见:reference/android/content/AsyncQueryHandler.html),帮助进行异步访问Content Provider。
    在各大组件中,Service和Content Provider都是那种需要持续访问的。Service如果是一个耗时的场景,往往会提供异步访问的接口,而Content Provider不论效率如何,都提供的是约定的同步访问接口。我想这遵循的就是场景导向设计的原则,因为Content Provider仅是提供数据访问的,它不能确信具体的使用场景如何,会怎样使用它的数据;而相比之下,Service包含的逻辑更复杂更完整,可以抉择大部分时候使用某接口的场景,从而确定最贴切的接口是同步还是异步,简化了上层调用的逻辑。

    配置

    四大组件说完了,四大组件幕后的英雄也该出场了,那就是每个应用都会有一份的配置文件,名称是AndroidManifest.xml,在工程的根目录下。在这个配置文件中,不仅会描述一些应用相关的信息,很重要的,会包含一个应用中所有组件的信息。如果你派生Activity或者Service实现了一个相关的类,这只是把它组件化的第一步,你需要把这个类的相关信息写到配置文件中,它才会作为一个组件被应用到,否则只能默默无闻的黯淡度过余生。
     
     
     
    摆了一幅图出来,这次不是偷来的,是敝帚自珍原创,所以没有意外的画的很丑,但基本还是可以体现出一些意思。在In Others的部分,这里是一般平台应用之间通信和交互的模型,每个应用都有很强烈的应用边界(往往表现为进程边界...),App 1的还是App 2的,分得很是清楚。每个应用内部,都有自己的逻辑去切分功能组件,这样的切分通常没有什么标准,率性而为。应用间的交互逻辑也比较零散,App 1与App 2交互,往往需要明确知道对方应用的具体信息,比如进程ID,进程名称之类的,这样使得应用和应用之间的联系,变得很生硬。而上层应用和系统应用的通信,往往有很多特定的模式,这种模式,很可能是无法直接应用在普通应用之间的,换而言之,系统应用是有一定特殊性的。
    重点,在图的下半部,描述的是Android的应用情形。在Android中,应用的边界,在组件这个层面,是极度模糊,什么进程、什么应用,都可以不必感知到。举个例子,App 1,实现了A和B两个组件,App 2,实现了C这个组件。A和C,都想使用B这个组件,那么它们的使用方式是完全一致的,都需要通过系统核心的组件识别和通信机制,找到和使用组件B。A,虽说和B是一个娘胎里蹦出来的,很不好意思,没有任何特殊的后面和捷径,还是要跑规矩的途径才能用到,一片和谐社会的景象油然而生。
    在Android中,所有组件的识别和消息传递逻辑都必须依赖底层核心来进行(通信可以没有底层核心的参与,比如一旦Service找到了,就可以和它产生持久的通信...),没有底层核心的牵线搭桥,任何两个组件都无法产生联系。比如一个Activity,跳到另一个Activity,必须要向底层核心发起一个Intent,有底层解析并认可后,会找到另一个Activity,把相关消息和数据传给它。一个Activity想使用Content Provider中的数据,必须通过底层核心解析相关的uri,定位到这个Content Provider,把参数传递给它,然后返回Activity需要的Cursor。这样的设计,保证了底层核心对所有组件的绝对掌控权和认知权,使得搭积木似的开发变成可能。
    为了,使得核心系统能够完整的掌握每个组件的信息,这就需要配置文件了。配置文件,就是将组件插到底层核心上的这个插头。只有通过这个插头插在底层核心的插座上(不要乱想,非十八禁...),组件才能够发光发热,闪耀光芒。
    组件的配置信息在我看来主要包含两个方面,一部分是描述如何认知。比如,Activity、Service、Broadcast Receiver都会有名字信息,和希望能够把握的Intent信息(姑且看成消息好了...),Content Provider会有一个描述其身份的uri。当其他组件通过这样的名字或者Intent,就可以找到它。
    另一部分是运行相关的信息。这个组件,期望怎么来运行,放在单独的进程,还是和调用者一个进程,还是找相关的其他组件挤在同一个进程里面,这些内容,都可以在配置的时候来决定(调用者在这个约束范围内,有进一步的选择权...)。更多配置项,请参见:guide/topics/manifest/manifest-intro.html。

    通过前续内容,也许可以帮助大家对Android组件有个初略的了解。但这些了解都还停留在静态层面,程序是个动态的概念,关于各个组件具体是怎么联系在一起的,如何手拉手运行起来完成一项功能的,这便是后话了。
  • 转载:深入Android 【二】 —— 架构和学习

    51_51testing 发布于 2010-10-05 14:16:45

    转载自: http://www.cnblogs.com/duguguiyu/archive/2010/01/23/1654559.html

    千呼万唤始出来,犹抱琵琶半遮。 -- 《琵琶行》
    虽贵为富二代,但Android要是没任何可圈点的地方,开不过70迈,在玲琅满目的手机平台竞争中,充其量也就做几个俯卧撑打一桶酱油,然后被落的远远的。说到底,出来混,靠的还是技术。

    架构


    从SDK文档中,偷来一幅Android平台的架构图,如上。在整个架构最底层红彤彤的部分,是Linux Kernel在移动平台的一个移植,它隐藏了硬件、网络等相关的细节,为上层提供了一个相对纯洁的统一接口。除非要做的是Android到不同设备的移植工作,否则对于大部分普通开发者而言,基本上是远观而不必亵玩的。Google一直强调,Android的底层实现异常NB,可移植性超强,暂没有功夫研读,实属遗憾。
    靠上一层,是一些核心的和扩展的类库,它们都是原生的C++实现。在这一层,你可以看到很多熟悉的面孔,一如SQLite、WebKit、OpenGL,开源的力量与贡献由此可见。如果,该层类库需要被上层函数调用,就必须要通过JNI的导出相应的接口函数,否则就只能在层次内部自个把玩。
    也是在这一层次上,还有为上层Java程序服务的运行时。Dalvik虚拟机,是Android的Java虚拟机,之所以不采用J2ME的虚拟机,一方面是因为J2ME的设计是为了低端机器而优化,而Dalvik则是为了高端一些的机器进行优化,提供更好的性能。另一方面,从商业角度来看,必须绕开J2ME虚拟机,Android才能彻底解放,想怎么开源就怎么开源,不再需要考虑License的问题。
    再往上,终于有Java出没了。首先是框架层,这里包含所有开发所用的SDK类库,另外还有一些未公开接口的类库和实现,它们是整个Android平台核心机制的体现。
    而在最上面,就是应用层了,系统的一些应用和第三方开发的所有应用都是位于这个层次上,也许要纠结两者的差别,就是系统应用会用一些隐藏的类,而第三方的应用,总是基于SDK提供的东西来搞。
    一般来说,Android开发,就是在SDK的基础上,吭哧吭哧用Java写应用。但自从有了NDK,一切有了写小变化。NDK的出现意味着,最上面应用层的内容,可以穿越Java部署的框架层,直接和底层暴露出来的,或者自行开发的C++库直接对话,当然在这些库中需要包含JNI的接口。
    人说,这就不是Android也可以用C++开发应用么,但其实,这样的说法不够确切,纯C++应用,是无法被接受的。因为在Android中,大量的核心机制部署在框架层,它们都是用Java实现的,比如控件库,Activity的调度之类的。因此,没了界面,没了调度,还是只用C++做类库比较合适,否则一切都乱了套了。

    特征

    基于这样的架构,Android有很多的设计显得很有意思。纵览整个SDK和核心机制的设计,工整漂亮,是Android给人的第一感觉。为了说明这一点,找一个反面教材是很有必要的,Symbian同学毫无悬念的担当这个伟岸的角色。
    写Symbian程序,感觉就像是在玩一个猜谜游戏。哪怕你是一个Symbian老手,当需要用到Symbian中某块陌生功能的时候,你可能依然束手无策。你往往需要猜并反复找寻,在这里我需要使用哪一种奇巧淫技呢,是该臆想某些事件,还是应该用一个神秘的UID寻找某个特定应用,诸如此类。
    而做Android应用的时候,就像是做高考模拟试题,题看上去不一样,解答模式摸清楚,就一通百通,一了百了。监听某个系统事件,查一下SDK就好;访问某个应用的数据,看看它有没有提供Content Provider就可以。所有的一切,都是按套路出牌,只要你了解了套路,再陌生的牌也可以看得懂,出的顺。人说武林高手,都应该是无招胜有招,而一个好的应用框架,也应该做到举重若轻,可触类旁通。
    而Android框架最文采飞扬的一点,就是引入了Mash-Up的思想。所谓Mash-Up,就是把写应用搞成搭积木,要出效果的时候,东家一块西家一块现场拼起来就好。这里面关键有两点,一个是模块化,另一个就是动态性。所谓模块化,就是一个应用的功能要明确的被封成一个个边界清晰的功能点,每一个功能点都像是一个黑盒,由预先定义的规则描述出其交互方式;而动态性,就是这些独立的模块能够在运行的时候,按照需求描述,连接在一起,共同完成某项更大的功能。在这两点上,Android都做得非常出色。
    站在可Mash-Up构造应用这一点去看其他的一些Android中的核心功能设计,就显得很有章可循了。比如为什么要把文件私有化,为什么要让进程被托管,等等(当然也可以站在别的角度看出不同的效果,视角不同,视野自然不同...)。
    在UI机制方面,Android也有很不错的表现。它采取xml格式的资源文件,描述所有界面相关的内容。资源文件不是什么新东西了,xml格式也是老调重弹,但可贵的是Android做的更为的丰富和彻底,基本把界面相关的逻辑,全部从代码中剥离到了资源文件中,和Symbian那四不像的资源文件相比,真是强大了不知多少倍了。

    Android学习入门
    不积跬步,无以至千里。 -- 《劝学》
    说,万事开头难。想开始Android的开发,最重要的应该是先把马步扎稳,套路摸清楚,后面的事情就顺当多了。打开怀抱,拥抱Android,也许可以先做下面这些事。

    开发环境

    辣手摧花成性的GFW,无情的把Android开发者官网关在了墙外。不过没关系,猛击这里,同样可以殊途同归(Shit,一直在用代理,刚试了下,发现竟然也被盾了,如果不行,那就只能翻墙了...)。
    如果旅途顺利,你可以在路径sdk/index.html下找到安装说明,成功配置好Android的开发环境(【注】:在以后,如果要给开发者页面上的链接,都会给一个像sdk/index.html这样的相对路径,你可以在前面加上官网地址,或者本地SDK的doc地址拼凑成完整的路径,在一个盾牌横行的朝代,只能用这样委屈求全的方法保证能更好的使用...)。
    在2.0之前,每一次版本更新,你都要自己去下个全新的SDK,然后按照说明,小心翼翼的一步步修改eclipse的设置,甚是麻烦。在2.0后,这个模式有所改善,你会先下到一个类似于下载器的插件,通过它可以来管理和升级SDK,不仅简化了整个升级模式,还使得你可以更好的在各个不同的SDK版本间游走,利国利民。
    Eclipse + ADT(Android Development Tool),是正牌的Android开发环境。你可以在Windows,Linux,Mac下做开发,甚为自由。比之Symbian的开发环境,ADT显得尤为强大,它对SDK提供的一堆优秀的命令行工具进行了UI上的封装,提供了图形界面(命令行控当然同样幸福,具体参见:guide/developing/tools/index.html)。通过ADT,你可以用运行和管理模拟器,使用调试器进行调试,过滤和查看Log,浏览模拟器上的文件信息,模拟拨号、短信等手机才有的事件,等等。

    文档

    我知道,有很多人在学习一个新平台开发的时候,都习惯去买一些《xxx 21天精通》之类的书籍。但其实,最好的入门学习资料,就是SDK文档。因为只有做平台的自己,才能最了解平台中的各个玄机,各方面的轻重缓急,从而能够更好的对症下药药到病除。
    在Android的SDK中,guide/index.html是由浅入深的教学文档,reference/packages.html是标准的API文档。对于教学文档,我的意见是,一字不拉的通读一遍甚至多遍,至少做到能对Android摸着头脑,并且碰到问题的时候,能够快速想起在哪里可以找到,回来深刻阅读。
    而API文档方面,Android做的算是还不错了。基本上每个类,每个接口,都有标准而详尽的说明,在一些尤为重要的类中,还具有大量的学习性的内容,不和Symbian似的,有太多的太监类,只有光秃秃的一个函数,一行文档说明都没有。整个文档结构是按照Java包来组织的,本身Java包命名的结构性和可读性很强,找起来也颇为方便。
    很多人对SDK文档有抵触情绪,我想,有两方面的原因。一则是SDK文档普遍缺少文学性,麻木不仁的八股文,难以下咽。Android在这方面做得算是乏善可陈,虽然算不上文采华丽,但还是挺适合阅读的。另一则,就会是语言方面的原因了。SDK文档多为英语,偶尔像MSDN这样有中文的,也停留在机器翻译的水平上,阅读起来颇为难受。特地在网上搜了下,找到一些翻译SDK的中文文档,比如这里。虽然是基于1.5 r1版本SDK所著,稍显过时,但翻译的还是有小用心的,作为辅助,也不失为一份好资料,特代表广大看官向这些为人民福利着想的同志致敬。

    Tutorials

    光说不练假把式,除了读,在入门阶段,写也是一项不能少的运动。同样是在SDK中,Android提供了一组Tutorials和一些列的Samples,详见:resources/index.html。
    Tutorials很简单,Hello World只是在教你如何在eclipse中,在ADT的帮助下,创建一个Android项目。相比之下,Hello Views复杂了些,它集中展示了几种标准的Android Layout 样式是如何构建的,很多时候,你都是在这些样式下扩展所需的UI。
    Hello Localization,是教你如何使用资源的,做完这个,就可以了解Android的资源有多杀~。最后收官的是一个更为完整的Notepad Tutorial,它展示了很多Android的核心机制,比如基于Intent的Activity整合,Activity的生命周期等。迈过这个Tutorial,欢迎你,进入Android的大门。
    当然,做完Tutorials,对于Android而言,只是管中窥豹略见一斑。在SDK中,还提供了一系列的Samples。可以根据自己的需求,挑选合适的Sample编译运行和学习。但其中,有一个是不论你做什么,都需要必看必读必熟悉的,就是API Demos。在这个Sample中,集中展示了Android重点功能的API使用,把这个Sample用熟悉,需要做什么的时候过去找一下就可以很快的入手了。

    源码

    到这里,很多看官一定很不屑,前面所谓的学习入门介绍,只不过是围着SDK打转。其实,事实也是如此,SDK中包含的内容是真的非常重要,我只是期望通过一些简短的介绍,激起一些初学者的重视,如是而已。
    当然,SDK每一个平台都有,没什么稀罕的。但Android有另一个非常稀罕而值钱的看家法宝,就是源代码。从Android Source的主站上:http://source.android.com/,你可以获得整个平台的源码以及相关介绍。非常苦口婆心的期望大家都去down一份源码放在机器上,哪怕你不需要进行修改编译,放在机器上当百科全书也是远胜于任何一本Android教学书籍的。本系列文章后续很多内容,都是从源码中学习到的一些浅薄见识。
    对于大部分开发者都有学习价值的源码,主要在源码的frameworks和packages目录下。前者包含的是平台核心的一些实现,比如你需要自定义一个控件,也许你就可以翻到一个系统控件的实现中去,看看它是怎么来做的。后者包含一些系统的应用实现,比如你想做个播放器,也许你可以先去参考参考系统自带的是具体怎么做的。这样的实现,即便不算是最华美,至少也是最标准,其价值不容小视。
    另外,你也可以把它当个代码库来使,不会使用某个类,grep一把,也许就能获得一份最漂亮的Sample。当然,如果你有时候对某些系统机制表示费解,抑或有一些bug不知道源头在哪,都可以跟着源码顺藤摸瓜的搞清楚。这样的好东西,可不是每个平台都能够享用的。

    其他

    论坛,其实对于开发和学习都是很重要的资源。毕竟,所有的资料都是死的,只有人是活得,能够最大限度的因地制宜解决问题。
    只不过,标准的官方论坛,放在Google Group上,已经惆怅的被盾了。中文论坛方面,没有特别优秀和活跃的,这一方面是由于Android的发展现状还不算很磅礴,另一方面是由于Android的开发相对于Symbian而言,奇技淫巧少了很多,没有那么多好问的。也许你可以去去csdn这样的传统论坛,或者eoe这样专门的论坛。有的时候,还是多少能获得一些帮助的。
    书籍方面,真没有什么推荐,豆瓣上搜索一下,你可以看到,目前的书籍,基本上还是集中在SDK使用层面上,很少有解析的很透彻,做的很深入的。而SDK的使用,看SDK的文档就足够了,如果实在对e文不感冒,买一两本评价不太差的中文书籍,放着翻翻也还是挺好。
    更进一步,也许可以读读一些经验性的文档,去Google Code上搜索一些代码回来看看。比如,SDK文档中,有个经验性文档的集合:resources/articles/index.html,就可以翻看一下。

    最后,更多的一切还需要自己在工程和思考中,慢慢总结。相信,好的代码,会垂青一个勤于动手和思考的人。
  • 转载:使用Junit对Android应用进行单元测试(二)

    51_51testing 发布于 2010-10-29 09:18:01

    转载自:http://tech.it168.com/a2010/1027/1118/000001118903_all.shtml

    步骤12 SimpleCalc计算器中的加法测试用例

      我们首先针对SimpleCalc中的加法进行测试用例的编写。这个测试用例中,会输入两个数(24和74),并测试是否其结果等于98。为了模拟在输入数字后点按钮的效果,我们使用了sendkeys方法,这个方法的优点在于可以在输入后自动将焦点切换到下一个控件上。最后,我们使用assertTrue的断言去判断实际结果是否就是等于98,代码如下:

      private static final String NUMBER_24 = "2 4 ENTER ";

      private static final String NUMBER_74 = "7 4 ENTER ";

      private static final String ADD_RESULT = "98";

      public void testAddValues() {

      sendKeys(NUMBER_24);

      // now on value2 entry

      sendKeys(NUMBER_74);

      // now on Add button

      sendKeys("ENTER");

      // get result

      String mathResult = result.getText().toString();

      assertTrue("Add result should be 98", mathResult.equals(ADD_RESULT));

      }


      步骤13 改进测试用例

      由于每次测试时,其实都是使用同一个activity的,因此在每次测试时不需要清除旧的值,我们可以在一个sendKeys()方法中,发送一系列的输入命令,如下所示:

      sendKeys(NUMBER_24 + NUMBER_74 + "ENTER");

      我们测试一个小数的情况如下,看结果是否等于79.5

      public void testAddDecimalValues() {

      sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + "ENTER");

      String mathResult = result.getText().toString();

      assertTrue("Add result should be " + ADD_DECIMAL_RESULT + " but was "

      + mathResult, mathResult.equals(ADD_DECIMAL_RESULT));

      }

      同样,我们去编写乘法的单元测试用例,这里我们继续使用sendKeys()方法,由于乘法的按钮就在加法的按钮右边,所以我们在用sendkey模拟输入了两个数后,发送“DRAD_RIGHT”的消息,就可以了。

      public void testMultiplyValues() {

      sendKeys(NUMBER_24+NUMBER_74+ " DPAD_RIGHT ENTER");

      String mathResult = result.getText().toString();

      assertTrue("Multiply result should be " + MULTIPLY_RESULT + " but was "

      + mathResult, mathResult.equals(MULTIPLY_RESULT));

      }


      步骤14 在模拟器中运行单元测试

      运行单元测试的方法很简单,鼠标右键项目,在弹出的菜单中选择“Debug ASàAndroid JUnit Test”即可,运行结果如下两图所示:


     


      其中红色的表示测试没办法通过,绿色的条状表示测试已经通过。


      步骤15 Android中对屏幕显示的单元测试

      在Android 的单元测试中,还可以针对界面的显示位置等进行单元测试。比如我们在Eclipse时开发采用的界面模拟器是在800*480的模式下的,但如果在其他尺寸规格的移动设备上是否能正常运行呢?这就需要对界面设置部分进行单元测试了。

      我们另外创建一个单元测试用例,用前文所讲的方法新建立一个名为LayoutTests的单元测试用例,如下图:

    十五、Android中对屏幕显示的测试

      并编写如下代码:

    package com.mamlambo.article.simplecalc.test;

      import android.test.ActivityInstrumentationTestCase2;

      import android.view.View;

      import android.widget.Button;

      import com.mamlambo.article.simplecalc.MainActivity;

      import com.mamlambo.article.simplecalc.R;

      
    public class LayoutTests extends ActivityInstrumentationTestCase2 {

      
    private Button addValues;

      
    private Button multiplyValues;

      
    private View mainLayout;

      
    public LayoutTests() {

      super(
    "com.mamlambo.article.simplecalc", MainActivity.class);

      }

      protected void setUp() throws Exception {

      super.setUp();

      MainActivity mainActivity 
    = getActivity();

      addValues 
    = (Button) mainActivity.findViewById(R.id.addValues);

      multiplyValues 
    = (Button) mainActivity

      .findViewById(R.id.multiplyValues);

      mainLayout 
    = (View) mainActivity.findViewById(R.id.mainLayout);

      }

      }

     

      这里,分别获得了加法按钮和乘法按钮的实例。接下来,增加一个testAddButtonOnScreen

      的方法,以测试按钮的位置是否正确。在这个方法中,首先你要决定屏幕的大小。有很多方

      法去检测屏幕的大小,比如用getWidth()和getHeight()方法,当然在考虑尺寸时,还必须考

      虑象标题栏,状态栏等所占用的位置大小。下面是其代码:

    public void testAddButtonOnScreen() {

      
    int fullWidth = mainLayout.getWidth();

      
    int fullHeight = mainLayout.getHeight();

      
    int[] mainLayoutLocation = new int[2];

      mainLayout.getLocationOnScreen(mainLayoutLocation);

      
    int[] viewLocation = new int[2];

      addValues.getLocationOnScreen(viewLocation);

      Rect outRect 
    = new Rect();

      addValues.getDrawingRect(outRect);

      assertTrue(
    "Add button off the right of the screen", fullWidth

      
    + mainLayoutLocation[0> outRect.width() + viewLocation[0]);

      assertTrue(
    "Add button off the bottom of the screen", fullHeight

      
    + mainLayoutLocation[1> outRect.height() + viewLocation[1]);

      }

     

      在各类尺寸的模拟器上运行,可以得到如下结果所示的测试结果:

      480x800, portrait 模式 (通过)

      800x480, landscape mode (失败)

      320x480, portrait mode (失败)

      480x320, landscape (失败)

      480x854, portrait mode (通过)

      854x480, landscape mode (失败)?

      大家可以思考下为什么有的测试用例成功有的失败。

      总结

      本文讲解了如何使用junit配合Android的应用进行单元测试及详细步骤,以及如何在

      Junit测试Android时的小技巧。可以看到,在设计完应用后应该编写单元测试用例,测试用

      例越多和越详细,则对程序的正确性提高越有好处。

  • 转载:使用Junit对Android应用进行单元测试(一)

    51_51testing 发布于 2010-10-29 09:10:21

    转载自http://tech.it168.com/a2010/1027/1118/000001118903_all.shtml

    在本文中,你将会学习到如何在Eclipse中创建Android JUnit的单元测试工程以及在不同的条件下创建及运行自动测试用例。

      准备工作

      本文假设读者已经有一定的Android基础知识,并且已经安装了Eclipse和Android SDK等开发工具。本文将指导读者如何将Android Junit框架应用到Android应用中去。本文还特别重点展示了如何测试Android中的Activity和如何识别程序中的错误。

      本文的示例代码可以在http://code.google.com/p/simple-calc-unit-testing/中下载

      步骤1 被测试的应用SimpleCalc概况

      在本文中,将以一个写好了的应用SimpleCalc简单计算器为例子进行讲解。这个简单计算器有两个功能,允许用户输入两个数并将它们相加或相乘,最后显示结果,如下图所示:

    准备工作

                               


            步骤2 SimpleCalc的的界面设计

      由于应用比较简单,只占一屏,所以我们在/res/layout/main.xml中设计如下代码所示:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation
    ="vertical" android:layout_width="fill_parent"
        android:layout_height
    ="fill_parent">
        
    <TextView android:layout_width="fill_parent"
            android:layout_height
    ="wrap_content" android:text="@string/hello"
            android:gravity
    ="center_horizontal" android:textSize="48px"
            android:padding
    ="12px" />
        
    <EditText android:layout_height="wrap_content" android:id="@+id/value1"
            android:hint
    ="@string/hint1" android:inputType="numberDecimal"
            android:layout_width
    ="fill_parent" android:textSize="48px"></EditText>
        
    <EditText android:layout_height="wrap_content" android:id="@+id/value2"
            android:hint
    ="@string/hint2" android:inputType="numberDecimal"
            android:layout_width
    ="fill_parent" android:textSize="48px"></EditText>
        
    <FrameLayout android:id="@+id/FrameLayout01"
            android:layout_width
    ="wrap_content" android:layout_height="wrap_content"
            android:padding
    ="12px" android:background="#ff0000">
            
    <LinearLayout android:id="@+id/LinearLayout02"
                android:layout_width
    ="wrap_content" android:layout_height="wrap_content"
                android:orientation
    ="horizontal" android:background="#000000"
                android:padding
    ="4px">
                
    <TextView android:layout_width="wrap_content"
                    android:layout_height
    ="wrap_content" android:text="@string/resultLabel"
                    android:textSize
    ="48px" android:id="@+id/resultLabel"></TextView>
                
    <TextView android:layout_width="wrap_content"
                    android:layout_height
    ="wrap_content" android:id="@+id/result"
                    android:textSize
    ="48px" android:textStyle="bold"
                    android:layout_marginLeft
    ="16px"></TextView>
            
    </LinearLayout>
        
    </FrameLayout>
        
    <LinearLayout android:id="@+id/LinearLayout03"
            android:layout_height
    ="wrap_content" android:layout_width="fill_parent">
            
    <Button android:layout_height="wrap_content" android:id="@+id/addValues"
                android:text
    ="@string/add" android:textSize="32px"
                android:layout_width
    ="wrap_content"></Button>
            
    <Button android:layout_height="wrap_content" android:id="@+id/multiplyValues"
                android:text
    ="@string/multiply" android:textSize="32px"
                android:layout_width
    ="wrap_content"></Button>
        
    </LinearLayout>
    </LinearLayout>

            简单解析一下这个界面设计,我们使用了LinearLayout,以使得控件能在垂直方向竖向排列。界面中包括了显示标题“Unit Testing Sample”的textview,两个输入数字的edittext控件,一个FrameLayout控件中包含了一个水平的LinearLayout,在这个LinearLayout包含了一个显示结果的textview以及其提示文字“Result”,注意的是FrameLayout的背景颜色设置为红色,而LinearLayou设置成了黑色背景。


            步骤3 SimpleCale Activity

      本程序中只有一个Actity:MainActity.java,代码如下:

    package com.mamlambo.article.simplecalc;

    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;

    public class MainActivity extends Activity {
       
    /** Called when the activity is first created. */
       @Override
       
    public void onCreate(Bundle savedInstanceState) {
           final 
    String LOG_TAG = "MainScreen";
           super.onCreate(savedInstanceState);
           setContentView(R.layout.main);

           final EditText value1 
    = (EditText) findViewById(R.id.value1);
           final EditText value2 
    = (EditText) findViewById(R.id.value2);

           final TextView result 
    = (TextView) findViewById(R.id.result);

           Button addButton 
    = (Button) findViewById(R.id.addValues);
           addButton.setOnClickListener(
    new OnClickListener() {

               
    public void onClick(View v) {
                   try {
                       
    int val1 = Integer.parseInt(value1.getText().toString());
                       
    int val2 = Integer.parseInt(value2.getText().toString());

                       
    Integer answer = val1 + val2;
                       result.setText(answer.toString());
                   } catch (Exception e) {
                       
    Log.e(LOG_TAG, "Failed to add numbers", e);
                   }
               }
           });

           Button multiplyButton 
    = (Button) findViewById(R.id.multiplyValues);
           multiplyButton.setOnClickListener(
    new OnClickListener() {

               
    public void onClick(View v) {
                   try {
                       
    int val1 = Integer.parseInt(value1.getText().toString());
                       
    int val2 = Integer.parseInt(value2.getText().toString());

                       
    Integer answer = val1 * val2;
                       result.setText(answer.toString());
                   } catch (Exception e) {
                       
    Log.e(LOG_TAG, "Failed to multiply numbers", e);
                   }
               }
           });
       }
    }

     

      上面的代码十分简单,分别在两个按钮的onclick事件中,对用户输入的数进行了相加和相乘,看上去代码似乎没问题,但接下来,我们将通过Junit去发现其中的bug。


      步骤4 创建Android 单元测试工程

      可以有两种方法去增加单元测试工程:一种是在创建新的Android工程时,在创建向导时同时创建单元测试工程,另外是针对已有的项目工程添加一个单元测试工程。本文由于已经有了一个项目工程,所以用如下步骤增加单元测试工程:

    四、创建Android 单元测试工程

      在Eclipse中,选择存在的工程SimpleCalc,鼠标右键后在弹出的菜单中选择Android Tools-àNew Test Project,如下图所示:


      步骤5 设置测试工程

      接下来需要对单元测试的工程进行设置,我们采用如下的设置方法:

      l 测试工程名称:我们采用SimpleCalcTest

      l 工程的位置:这个可以随便设置

      l 选择被测试的工程:这里我们选择已经存在的SimpleCalc

      l 构建的目标版本:这里我们选择Android 2.1

      l 测试用例的包名:设置为com.mamlambo.article.simplecalc.test,

      l 设置界面如下图所示。

    五、设置测试工程


      步骤6 SimpleCalcTest单元测试项目的结构

      我们审视下SimpleCalcTest的项目结构如下图所示,可以看到这跟普通的Android工程没什么两样:

    六、SimpleCalcTest测试项目结构


      步骤7 创建单元测试用例

      下面创建第一个单元测试用例,鼠标右键点击simplecalc.test的包,在弹出的菜单中选择NewàJUnit Test Case,如下图所示:

    七、创建单元测试用例


      步骤8 设置单元测试用例

      接下来对单元测试进行如下设置

      l 设置选择使用Junit 3

      l 源代码目录:这里要设置为SimpleCalcTest工程的代码目录

      l Package:这里设置为com.mamlambo.article.simplecalc.test,

      l 测试用例名称:设置为MathValidation

      l 测试的父类:这里选择“android.test.ActivityInstrumentationTestCase2.",这个是用来测试activity的Android的测试用例

      l 将多选框中的setup,constructor两个都勾选上

      如下图所示

    八、设置单元测试用例


      步骤9 查看MatthValidation测试用例

      在上图中,点”Finish”按钮后,MathVlidatiton.java测试用例就创建了。在单元测试中包括如下几个部分:construction, setUp(), 针对方法的测试用例, tearDown(), 和destruction。在setup()方法中,主要是实现一些在测试工作前的资源及环境设置等的初始化设置;而针对方法的测试用例中,需要用户自己编写,一般是以“test+方法名”;而tearDown()在每个测试方法之后运行,用来撤消其初始化的测试环境。

      代码如下:

    package com.mamlambo.article.simplecalc.test;

    import android.test.ActivityInstrumentationTestCase2;

    public class MathValidation extends
           ActivityInstrumentationTestCase2
    <MainActivity> {   

       
    public MathValidation(String name) {
           super(name);
       }

       protected void setUp() throws Exception {
           super.setUp();
       }
    }

      步骤10 修改MathValidation的构造函数

      在测试用例的构造函数中,写入如下代码,以将我们正在使用的测试父类与测试环境设置进行绑定。

      public MathValidation() {

      super("com.mamlambo.article.simplecalc", MainActivity.class);

      }


      步骤11 编写setUp方法

      现在可以收集数据去验证SimpleCalc的计算方法了。在setUp方法中,首先应该通过getActivity()方法获得当前的Activity,如下所示:

      MainActivity mainActivity = getActivity();

      接着,需要获得名为R.id.result的textview控件的实例,这个控件实际上保存计算器应用的运算结果的,代码如下所示:

    package com.mamlambo.article.simplecalc.test;

    import android.test.ActivityInstrumentationTestCase2;
    import android.widget.TextView;
    import com.mamlambo.article.simplecalc.MainActivity;
    import com.mamlambo.article.simplecalc.R;

    public class MathValidation extends ActivityInstrumentationTestCase2<MainActivity> {

       
    private TextView result;

       
    public MathValidation() {
           super (
    "com.mamlambo.article.simplecalc", MainActivity.class);
       }

       @Override
       protected void setUp() throws Exception {
           super.setUp();

           MainActivity mainActivity 
    = getActivity();

           result 
    = (TextView) mainActivity.findViewById(R.id.result);
       }
    }
  • Android Virtual Devices 更改创建目录.

    liyun100 发布于 2010-04-08 19:01:11

    转自:http://hewei1107.blog.163.com/blog/static/1275671372009910101747758/

    AVD quickview

    • You need to create an AVD to run any app in the Android emulator
    • Each AVD is a completely independent virtual device, with its own hardware options, system image, and data storage.
    • You create AVD configurations to model different device environments in the Android emulator.

    In this document

    1. Creating an AVD
      1. Listing targets
      2. Selecting a target
      3. Creating the AVD
      4. Setting hardware emulation options
      5. Default location of the AVD files
    2. Managing AVDs
      1. Moving an AVD
      2. Updating an AVD
      3. Deleting an AVD
    3. Command-line options

    See Also

    1. Android Emulator

    Android Virtual Devices (AVDs) are configurations of emulator options that let you better model an actual device.

    Each AVD is made up of:

    • A hardware profile.  You can set options to define the hardware features of the virtual device. For example, you can define whether the device has a camera, whether it uses a physical QWERTY keyboard or a dialing pad, how much memory it has, and so on.
    • A mapping to a system image.  You can define what version of the Android platform. will run on the virtual device. You can choose a version of the standard Android platform. or the system image packaged with an SDK add-on.
    • Other options.  You can specify the emulator skin you want to use with the AVD, which lets you control the screen dimensions, appearance, and so on. You can also specify the emulated SD card to use with the AVD.
    • A dedicated storage area on your development machine, in which is stored the device's user data (installed applications, settings, and so on) and emulated SD card.

    You can create as many AVDs as you need, based on the types of devices you want to model and the Android platforms and external libraries you want to run your application on.

    In addition to the options in an AVD configuration, you can also specify emulator command-line options at launch or by using the emulator console to change behaviors or characteristics at run time. For a complete reference of emulator options, please see the Emulatordocumentation.

    To create and manage AVDs, you use the android tool provided in the Android SDK. For more information about how to work with AVDs from inside your development environment, see Developing in Eclipse with ADT or Developing in Other IDEs, as appropriate for your environment.

    Creating an AVD

    The Android SDK does not include any preconfigured AVDs, so you need to create an AVD before you can run any application in the emulator (even the Hello World application).

    To create an AVD, you use the android tool, a command-line utility available in the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; "><sdk>/tools/</COde> directory. Managing AVDs is one of the two main function of the android tool (the other is creating and updating Android projects). Open a terminal window and change to the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; "><sdk>/tools/</COde>directory, if needed

    To create each AVD, you issue the command <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">android create avd</COde>, with options that specify a name for the new AVD and the system image you want to run on the emulator when the AVD is invoked. You can specify other options on the command line also, such as to create an emulated SD card for the new AVD, set the emulator skin to use, or set a custom location for the AVD's files.

    Here's the command-line usage for creating an AVD:

    android create avd -n <name> -t <targetID> [-<option> <value>] ...

    You can use any name you want for the AVD, but since you are likely to be creating multiple AVDs, you should choose a name that lets you recognize the general characteristics offered by the AVD.

    As shown in the usage above, you must use the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-t</COde> (or <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">--target</COde>) argument when creating a new AVD. The argument sets up a mapping between the AVD and the system image that you want to use whenever the AVD is invoked. You can specify any Android system image that is available in your local SDK — it can be the system image of a standard Android platform. version or that of any SDK add-on. Later, when applications use the AVD, they'll be running on the system that you specify in the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-t</COde> argument.

    To specify the system image to use, you refer to its target ID — an integer — as assigned by the android tool. The target ID is not derived from the system image name, version, or API Level, or other attribute, so you need to have the android tool list the available system images and the target ID of each, as described in the next section. You should do this before you run the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">android create avd</COde> command.

    Listing targets

    To generate a list of system image targets, use this command:

    android list targets

    The android tool scans the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; "><sdk>/platforms</COde> and <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; "><sdk>/add-ons</COde> directories looking for valid system images and then generates the list of targets. Here's an example of the command output:

    Available Android targets:id:1    Name: Android 1.1    Type: platform    API level: 2    Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-Pid:2    Name: Android 1.5    Type: platform    API level: 3    Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-Pid:3    Name: Google APIs    Type: add-on    Vendor: Google Inc.    Description: Android + Google APIs    Based on Android 1.5 (API level 3)    Libraries:    * com.google.android.maps (maps.jar)        API for Google Maps    Skins: HVGA (default), HVGA-L, QVGA-P, HVGA-P, QVGA-L

    Selecting a target

    Once you have generated the list of targets available, you can look at the characteristics of each system image — name, API Level, external libraries, and so on — and determine which target is appropriate for the new AVD.

    Keep these points in mind when you are selecting a system image target for your AVD:

    • The API Level of the target is important, because your application will not be able to run on a system image whose API Level is less than that required by your application, as specified in the<COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">minSdkVersion</COde> attribute of the application's manifest file. For more information about the relationship between system API Level and application <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">minSdkVersion</COde>, see Specifying Minimum System API Version.
    • Creating at least one AVD that uses a target whose API Level is greater than that required by your application is strongly encouraged, because it allows you to test the forward-compatibility of your application. Forward-compatibility testing ensures that, when users who have downloaded your application receive a system update, your application will continue to function normally.
    • If your application declares a <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">uses-library</COde> element in its manifest file, the application can only run on a system image in which that external library is present. If you want your application to run on the AVD you are creating, check the application's <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">uses-library</COde> element and select a system image target that includes that library.

    Creating the AVD

    When you've selected the target you want to use and made a note of its ID, use the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">android create avd</COde> command to create the AVD, supplying the target ID as the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-t</COde> argument. Here's an example that creates an AVD with name "my_android1.5" and target ID "2" (the standard Android 1.5 system image in the list above):

    android create avd -n my_android1.5 -t 2

    If the target you selected was a standard Android system image ("Type: platform"), the android tool next asks you whether you want to create a custom hardware profile.

    Android 1.5 is a basic Android platform.Do you wish to create a custom hardware profile [no]

    If you want to set custom hardware emulation options for the AVD, enter "yes" and set values as needed. If you want to use the default hardware emulation options for the AVD, just press the return key (the default is "no"). The android tool creates the AVD with name and system image mapping you requested, with the options you specified.

    If you are creating an AVD whose target is an SDK add-on, the android tool does not allow you to set hardware emulation options. It assumes that the provider of the add-on has set emulation options appropriately for the device that the add-on is modeling, and so prevents you from resetting the options.

    For a list of options you can use in the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">android create avd</COde> command, see the table in Command-line options for AVDs, at the bottom of this page.

    Setting hardware emulation options

    When are creating a new AVD that uses a standard Android system image ("Type: platform"), the android tool lets you set hardware emulation options for virtual device. The table below lists the options available and the default values, as well as the names of properties that store the emulated hardware options in the AVD's configuration file (the config.ini file in the AVD's local directory).

    Characteristic Description Property
    Device ram size The amount of physical RAM on the device, in megabytes. Default value is "96". hw.ramSize
    Touch-screen support Whether there is a touch screen or not on the device. Default value is "yes". hw.touchScreen
    Trackball support Whether there is a trackball on the device. Default value is "yes". hw.trackBall
    Keyboard support Whether the device has a QWERTY keyboard. Default value is "yes". hw.keyboard
    DPad support Whether the device has DPad keys. Default value is "yes". hw.dPad
    GSM modem support Whether there is a GSM modem in the device. Default value is "yes". hw.gsmModem
    Camera support Whether the device has a camera. Default value is "no". hw.camera
    Maximum horizontal camera pixels Default value is "640". hw.camera.maxHorizontalPixels
    Maximum vertical camera pixels Default value is "480". hw.camera.maxVerticalPixels
    GPS support Whether there is a GPS in the device. Default value is "yes". hw.gps
    Battery support Whether the device can run on a battery. Default value is "yes". hw.battery
    Accelerometer Whether there is an accelerometer in the device. Default value is "yes". hw.accelerometer
    Audio recording support Whether the device can record audio. Default value is "yes". hw.audioInput
    Audio playback support Whether the device can play audio. Default value is "yes". hw.audioOutput
    SD Card support Whether the device supports insertion/removal of virtual SD Cards. Default value is "yes". hw.sdCard
    Cache partition support Whether we use a /cache partition on the device. Default value is "yes". disk.cachePartition
    Cache partition size Default value is "66MB". disk.cachePartition.size

    Default location of the AVD files

    When you create an AVD, the android tool creates a dedicated directory for it on your development computer. The directory contains the AVD configuration file, the user data image and SD card image (if available), and any other files associated with the device. Note that the directory does not contain a system image — instead, the AVD configuration file contains a mapping to the system image, which it loads when the AVD is launched.

    The android tool also creates a <AVD name>.ini file for the AVD at the root of the .android/avd directory on your computer. The file specifies the location of the AVD directory and always remains at the root the .android directory.

    By default, the android tool creates the AVD directory inside <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">~/.android/avd/</COde> (on Linux/Mac), <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">C:\Documents and Settings\<user>\.android\</COde> on Windows XP, and<COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">C:\Users\<user>\.android\</COde> on Windows Vista. If you want to use a custom location for the AVD directory, you can do so by using the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-p <path></COde> option when you create the AVD:

    android create avd -n my_android1.5 -t 2 -p path/to/my/avd

    If the .android directory is hosted on a network drive, we recommend using the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-p</COde> option to place the AVD directory in another location. The AVD's .ini file remains in the .android directory on the network drive, regardless of the location of the AVD directory.

    Managing AVDs

    The sections below provide more information about how to manage AVDs once you've created them.

    Moving an AVD

    If you want to move or rename an AVD, you can do so using this command:

    android move avd -n <name> [-<option> <value>] ...

    The options for this command are listed in Command-line options for AVDs at the bottom of this page.

    Updating an AVD

    If, for any reason, the platform/add-on root folder has its name changed (maybe because the user has installed an update of the platform/add-on) then the AVD will not be able to load the system image that it is mapped to. In this case, the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">android list targets</COde> command will produce this output:

    The following Android Virtual Devices could not be loaded: Name: foo Path: <path>/.android/avd/foo.avd Error: Invalid value in image.sysdir. Run 'android update avd -n foo'

    To fix this error, use the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">android update avd</COde> command to recompute the path to the system images.

    Deleting an AVD

    You can use the android tool to delete an AVD. Here is the command usage:

    android delete avd -n <name>

    When you issue the command, the android tool looks for an AVD matching the specified name deletes the AVD's directory and files.

    Command-line options for AVDs

    The table below lists the command-line options you can use with the android tool.

    Action Option Description Comments
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">list avds</COde>   List all known AVDs, with name, path, target, and skin.  
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">create avd</COde> <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-n <name> or 

    </COde>

    The name for the AVD. Required
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-t <targetID></COde> Target ID of the system image to use with the new AVD. Required. To obtain a list of available targets, use <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">android list targets</COde>.
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-c <path></COde> or 

    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-c <size>[K|M]</COde>

    The path to the SD card image to use with this AVD or the size of a new SD card image to create for this AVD. Examples: <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-c path/to/sdcard</COde> or <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-c 1000M</COde>
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-f</COde> Force creation of the AVD By default, if the name of the AVD being created matches that of an existing AVD, the android tool will not create the new AVD or overwrite the existing AVD. If you specify the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-f</COde> option, however, the android tool will automatically overwrite any existing AVD that has the same name as the new AVD. The files and data of the existing AVD are deleted.
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-p <path></COde> Path to the location at which to create the directory for this AVD's files.  
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-s <name></COde> or 

    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-s <width>-<height></COde>

    The skin to use for this AVD, identified by name or dimensions. The android tool scans for a matching skin by name or dimension in the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">skins/</COde> directory of the target referenced in the <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-t <targetID></COde> argument. Example: <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-s HVGA-L</COde>
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">delete avd</COde> <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-n <name></COde> Delete the specified AVD. Required
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">move avd</COde> <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-n <name></COde> The name of the AVD to move. Required
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-p <path></COde> The path to the new location for the AVD.  
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">-r <new-name></COde> Rename the AVD.  
    <COde style="color: rgb(0, 112, 0); font-family: monospace; line-height: 1em; ">update avds</COde>
851/512345>
Open Toolbar