qileilove

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

Java字节码深入解析

     摘要: 一:Java字节代码的组织形式  类文件{  OxCAFEBABE,小版本号,大版本号,常量池大小,常量池数组,访问控制标记,当前类信息,父类信息,实现的接口个数,实现的接口信息数组,域个数,域信息数组,方法个数,方法信息数组,属性个数,属性信息数组  }  二:查看方法 --- javap命令  例子:有一个Java类Demo.javapublic class Demo&nb...  阅读全文

posted @ 2011-12-06 11:10 顺其自然EVO 阅读(7940) | 评论 (0)编辑 收藏

可用性测试的权衡之道

可用性测试的权衡之道(一)

  对于可用性测试,业内人士存在一些普遍认可的原则。它们神圣地如同自然科学里的理论,似乎我们只能对其言听计从、俯首称臣才能践行出“好的可用性测试”。其实,即便是科学,它的一个特征也是“可证伪性”——理论的正确性总是存在前提条件的。真理再向前一步就成为谬误!

  可用性测试中的原则同样如此,需要根据目的、资源、环境的不同,灵活把握、权衡取舍,而非一味恪守某一个或某几个原则,也许这才是可用性从业人员经验重要性的体现。

  一、任务设置:精细 VS 宽泛

  制定的任务过于精细,一般原则上是反对的。理由很清楚,如果你的任务精细到一步一步“引导”用户进行操作,那太不符合用户现实中的使用情境,平时没有人在旁边“引导”用户的每一步操作;而且过于控制用户的操作步骤,用户缺乏真实使用时的灵活性。

  是不是我们设置的任务只能是宽泛的,不能细化呢?这就必须根据研究的目的来做抉择。如果产品处在设计的初期,我们需要关注一些宏大的问题(如:网站的整体架构、导航和分类的合理性、页面的逻辑关系),此时就需要通过宽泛而有弹性的任务,来查找宏观层面的问题。如果产品的设计已经非常完善,开始进行细节的修改迭代,此时就需要通过设置相对具体的任务来查找特定的细节问题(如:对某个命名的理解、按钮的使用、链接的点击、表单的填写)。按照《Don’t make me think》一书的观点:一般用户使用互联网产品时满足于能用就行,不会寻求最好的使用方法;只扫描网页,不会仔细阅读。所以,如果完全宽泛有弹性地设置任务,虽然更吻合实际使用情况,但是很可能用户直接跳过你想考察的细节。

  实际工作中,由于时间和资源的限制,无法做到每个产品从设计初期到上线前后进行多次可用性测试。可能在一次的可用性测试中即需要同时关注宏观方面和细节上的问题。此时,还是需要和产品经理、交互设计师反复沟通,确认测试的主要目的,同时通过对任务设置精细程度的权衡把握,使次要目的也尽量得以满足。

  不过,即便是想考察细节的任务,也要尽量避免“直接指导操作”式的语言描述方式,这样能让任务与真实使用情境不会相距太远。例如:想考察豆瓣读书页面【想要】按钮是否能被看到、是否具备可点击感。下面列出两种表述方式,以作对比:

  A、请找到您喜欢的那本书,并在该页面点击【想要】。(×)

  B、请找到您喜欢的那本书,并在该页面对其作个标记。(√)

  二、任务数量:多VS少

  任务数量的多少与可用性测试考察范围有关,与任务的精细程度也有关。如果对网站全站进行考察和只对其中某个页面、某个操作流程进行考察,所需的任务数量自然不一样。在同样的考察范围下,如果任务设置得越精细,所需任务数量也就越多。

  Lindgaard和Chattratichart(2007)的研究发现任务数量与发现可用性问题比例存在显著的相关关系(r=0.82,p<0.01)。为了尽可能多地发现可用性问题,我们就尽量多地设置任务给用户吗?

  此时要考虑任务数量过多可能带来的弊端:学习效应和疲劳效应,尤其是靠后的任务更可能会受影响。心理学实验中处理此问题的方法是顺序平衡,抵消影响。但是可用性测试中设置的场景和任务存在特定的先后次序,不适合采用顺序平衡的方法。基于我们的经验,还是通过对测试的任务数量进行控制,确保正式测试环节最多不超过1小时,加上前后的欢迎语、访谈、问答等,整个过程不超过1.5小时。

  此外,任务数量的多少还会间接影响到测试所需参与者数量的多少。

  三、用户人数:5个足够VS 5个不够

  Nielsen的研究发现,5个用户可以发现80%以上的可用性问题。这个结论得到许多人的推崇,因此称之为“魔法数字5”。这个结论的来源依据是每个用户平均可以发现30%的可用性问题,且假设所有问题都有同等被发现的概率。不过,当设置的任务数量过多,且任务的精细程度和难度多种多样时,这个前提有可能不成立。

  Lindgaard和Chattratichart(2007)的研究发现测试用户数量与发现的可用性问题比例并不存在显著的相关关系。这个结论似乎又支持我们选择少量用户进行测试即可。
\

 其实,在用户招募阶段,比用户数量更需要重视是用户的代表性的问题。能否招募到有代表性的用户将直接影响可用性测试的成败。如测试一个医疗软件产品,招募到医护人员和患者作为测试用户,那5个用户可能就足够了;但如果只招募到医学实习生来测试,就必须超过5个以上的用户(即便这样,也未必能推论到整个产品的用户群)。

  由此看来,招募用户的人数和任务的数量、精细程度、用户的代表性也是息息相关的。参考Tom Tullis(2009)和本人经验:当可用性测试范围限定在一定的范围(20个任务内、或30个网页之内),且招募到很强代表性的用户,那么5个足够了。如果存在着差别较大的亚群体,争取做到每个亚群组有5个左右的代表性的用户(当然,目标用户的特征及分类应该是在可用性测试之前的用户调研阶段就解决的问题);一次测试最多不会超过12个用户。

  四、用户表现:行为VS言语

  在可用性测试中强调对用户操作行为的关注,是毋庸置疑的。因为:

  1、用户的行为指标更明确、具体、客观,易观察和记录。

  2、如果完全把关注点放在用户的操作行为上,那么就无需跟用户进行多余的(指导语之外的)语言交流。类似于心理学研究规范,对实验或测试中的指导语进行统一,对一切无关变量(包括主试的语言、体态表情)进行控制,以减少对研究过程的干扰。

  3、即便你直接询问用户某些问题,也极可能得到错误的答案。30年前Richard Nisbett和Timothy Wilson的实验、2年前Peter Johansson在《science》的文章,都证实了某些情况下人们无法解释清楚自己行为的真正原因。另外,用户还可能揣摩主试的喜好,回答他们认为主试期望的答案。

  因此,有必要强调在可用性测试过程中关注的重点永远应该是用户的操作行为,而且尽量减少任何无关变量的干扰。但这个原则被有些人引申到极端,认为只有观察用户的操作行为才有意义,其他信息都是无需关注的,甚至轻率地怀疑用户的话都是不可信的。

  可用性测试的主要目的虽然是发现问题,但也需要了解问题背后的原因,而仅仅依靠观察用户的操作行为是无法获悉所有问题背后的原因的,此时,我们就希望用户能采用“出声思维法”,出声思维就是集中于如何与产品进行交互的意识流。如果测试中的氛围比较平等、自然、融洽,用户又特别愿意表达,那么用户就会在进行任务操作同时,表达他们想做什么、打算如何做、背后的原因是什么。此时,不仅是操作行为、用户表达出来的想法和原因、以及语言中透露出的疑惑、失望、不满、惊讶、犹豫等情绪同样是需要我们加以关注的。但是,有些用户比较内向,不善于主动表达自己的想法,此时就需要主试跟他进行简单的交流,以引导用户说出背后的原因(注:不是引导用户说出你期望得到答案)。

  所以,在实际的可用性测试,基本应该以关注用户的行为为主,少量、适时地进行询问交流也是需要的。但这个度如何把握呢?

  1、当用户出现犹豫、惊讶、任务失败(过程节点上出现自然而然地稍微中断/暂停)的时候才进行简单的询问。

  2、询问采用一般疑问句的句式,重复用户刚才的行为表现(要具体客观):“你刚才没有……,是吗?”——虽然没有直接问“为什么”,但暗示了希望听到他进一步的解释。

  3、如果用户没有自己主动说出原因,可以“顺便”问一下“为什么?”或通过身体前倾、目光注视等非语言方式来暗示用户你希望能听到更多内容。若用户很快、坚定地说出原因,则该理由的可信度较高;如果用户犹豫、或难以说出原因,就不要继续追问。

  除了上述的语言、情绪、行为都需要得到关注,还有一种特殊情况是需要听懂用户“没有说的”语言。例如,我们预计网站的某二级导航标签和一级导航标签存在分类逻辑上的不合理;但用户在测试中,导航相关的操作步骤进行得很流畅,用户也什么都没说。这通常表明用户认为这些是理所当然的、不影响操作的——此时你需要听懂用户“没有说的”语言。如果你简单粗暴地打断用户并询问:“你觉得这两个导航标签如何?”,则变成了一种诱导性地提问。

  总结一下关于此部分内容的实践应用:

  1、用户的操作行为永远是可用性测试的重点。

  2、鼓励用户采用“出声思维法”。

  3、适时、少量地向用户提问,禁止对同一个问题反复追问“为什么”。

  4、采用真正地“倾听”技术保持和用户的交流状态,而非通过过多的话语。

  5、开放、不预设立场地观察、倾听用户“没有说的”语言。

  在可用性测试中考虑需要遵循的原则时,一定要理解它的适用条件,以及它和其它原则之间的互相影响,并结合本次用户研究的目的、资源、环境综合考虑,以尽可能形成一个最优方案。由于博文长度所限,先总结这么多,在下次的文章中会继续总结其它几方面的原则。

可用性测试的权衡之道(二)

  继续讨论可用性测试中各种原则的灵活运用和注意事项。

  五、发现问题:真的 VS 假的

  判断发现问题的真假,初看上去似乎不是个困难。多数或全部参与者都遇到的问题毫无疑问是明显的可用性问题。或许有人会建议,根据参与者中发现该问题的人数比例来判断:比例高是真问题,比例低是假问题。前半句话可以接受,后半句话则有待商榷。

  虽然可用性测试是相对严谨的用户研究方法,但是其对无关变量控制的严格程度和真正的心理学实验还是有一定的差距;并且心理学实验对每组参与者数量的最低要求是30人,这样得出的结论(数量比例)才具有推论至一般的意义。而可用性测试一般才8人左右的参与人数(尽管招募的参与者在质的方面非常具有代表性),但却无法把可用性测试中出现的所有数量比例简单推论至一般。8个参与者中有1人发现某个问题,不代表现实中出现同样问题的真实用户只有12.5%,更不代表这个问题不是真正的/严重的可用性问题。

  问题的真假除了根据问题出现的次数比例,还有很重要的考虑点是:用户“错误行为”背后的认知/思考方式是否合乎逻辑?

  这里顺便借用一下诺曼《设计心理学》里谈到的理论:概念模型——系统表象——心理模型。概念模型可认为是产品设计人员对产品的设计思想;系统表象可认为是产品展现出的交互界面;而心理模型则是用户按照既往经验对如何操作该产品的设想。从这个角度来认识,可用性问题则是“概念模型、系统表象、心理模型”三者的不吻合或矛盾。

  通过分析用户行为背后的认知是否符合逻辑,来判断发现的问题的真假,主要体现在以下几点:

  1、“概念模型、系统表象”的不一致

  产品设计人员突然发现,界面的交互形式根本没有反映出他原先的设计思想!

  2、“系统表象、心理模型”的不一致

  (1)用户的思维方式受已有的同类产品的影响,并内化接受,而新产品的“系统表象”和已有同类产品并不一致。

  (2)用户在日常生活经验中形成了许多并不科学地通俗理解世界的方式(比如通俗物理学、通俗心理学),但产品设计人员没有意识到用户在以这样一种“自认正确”的错误方式来理解和使用产品。

  如果发现的可用性问题属于以上情况,那么即使只有一个参与者碰到,它也非常可能是一个真正的可用性问题。

  例如:让用户登录购彩网站,查看自己上次购彩结果。大多数用户点击【个人中心】去查看,有2个用户点击【开奖公告】去查看,发现只有开奖号码,没有任何购彩结果信息后,再去点击【个人中心】。仅2个人出现了稍微的偏差,而且很快就找到了正确的页面,这貌似应该不算什么问题。

  但若追究其行为背后的逻辑,并与其他用户的反馈(“我上次买的号码没有直接显示出来?”“这里看不到开奖的号码啊?”)联系起来,可以判断用户的心理模型和产品的系统表象不一致。用户希望能同时对照着开奖号码和自己买的号码很方便地核对,而网站却割裂两部分放在不同的页面,因此需要将这2个用户碰到的问题当作真正的可用性问题来对待。

 六、研究方法:定性 VS 定量

  可用性测试,很多时候被认为是一种定性研究方法;但也有人说它是一种定量研究方法。究竟是怎么回事呢?

  个人认为,可用性测试实质上结合了定性和定量两种方法的特点,到底哪种成分更多,要看你的使用目的以及细节上如何操作。

  定量研究的思路是基于对一定数量样本的测量,以将研究所得的结论推广至总体。除了强调样本的代表性,还对样本的数量有具体的要求,同时会考虑抽样误差、置信度、置信区间的度量。并且定量研究过程中非常注重对某些自变量操控、及无关变量的控制。

  而定性研究重视对主观意义的理解(如背后隐藏的原因),采用解释建构的方法,比如访谈法等。

  平时工作中以“形成式可用性”测试为主,即便它稍微偏向于定性研究,但在允许的范围内,我个人还是尽可能地遵循着定量研究的方法去实施。这样整个测试过程的严谨性能得到保证,结论的客观程度相对更高(近几个世纪来,量化研究一直是科学研究的主要范式,也正是这个原因)。具体做法如下:

  1、在任务的设置上:因为参与者可能存在差别较大的亚群体,不可能要求完成完全相同的任务。但必定会设置大部分基本的、都需要完成的公共任务,再针对不同亚群体设置少量的特殊任务。在后期统计分析的时候,基本的公共任务则可以进行数量化的统计,并横向比较。

  2、在测试过程中:关注参与者完成任务时的相关行为,用数字来记录(以0、0.5、1分别表示失败、帮助/提示下成功、成功)。主试尽量少地言语及体态姿势的干扰,只在必要时进行适当地言语交流。

  3、在报告呈现:对任务完成情况(效率、完成率)统计呈现,对不同任务的完成情况进行比较,对亚群体间的任务完成情况进行比较,对所有可用性问题按数量化指标进行排序等。或者比较迭代前后独特问题的频次是否减少,以及严重程度高的等级里面可用性问题数量的变化情况。

  4、测试过后,我们通常还会收集用户自我报告式的数据,作为“感知可用性”的一个总体反映。

  (1)推荐使用系统可用性量表(SUS),因为有研究表明SUS在少量样本时即可产生较为一致的评分结果。

  (2)为减少用户在填写这些量表时的反应心向,不要求填写任何个人信息,且主试最好暂时回避。

  (3)只统计分析所有参与者SUS量表总分的平均值,切勿再拆分比较亚群体之间的差异,因为即便信效度再高的量表,当样本量极小时都会变得很不靠谱!

  七、问题优先级:单指标 VS 多指标

  除了在可用性测试过程中,最终报告也必须体现出量化、客观地特点。例如,报告发现的可用性问题的列表,我也会以量化的方式排列出问题的优先级别。

  这样做的好处在于:首先,发现的可用性问题肯定有一些比另一些更严重;其次,考虑到产品和设计人员的精力和资源总是有限的,必须帮助他们梳理出最亟需整改的问题。站在别人的角度考虑问题,这样他们才能更“友好地”接受我们的报告。

  可用性问题列表的排序,涉及到采用单指标还是多指标、以及指标分为几级的问题。




先就量化的客观性而言,“出现频率”指标是最客观、最易量化的;而其它三个指标都需分析人员的主观判断。

  就指标的代表意义而言,“严重程度”、“出现频率”与用户体验最相关,与用研人员的职责也最相关。另两个指标可能更多地是产品人员的职责。

  就指标的价值而言,多个指标的综合显然比单一指标更有价值。

  基于上述考虑,实际工作中我会选择“严重程度”和“出现频率”两个指标的综合,作为可用性问题的优先级指标。“严重程度”分为3级,而不是5级(分析人员主观判断时,3级指标的误差率要低于5级指标);“出现频率”采用计算的具体数值,而非4级分类。这两个指标合并时,采用1:1的权重,具体公式为:

  问题优先级=严重程度的级别+出现频率的具体值×3

  八、报告呈现:优点 VS 问题 VS 建议

  当产品设计人员辛辛苦苦做出的产品却被你报告上罗列的各种问题批评得一无是处时,即便理智上认可你的成果,情感上也很难接受。因此报告中列出哪怕一条最重要的优点,也会让产品设计人员感到欣慰、感受到你中立的态度,增加对报告的接纳程度。列出优点的另一个好处是,在测试中被参与者多次自发提及的优点确实带给用户某种惊喜;当你在报告中再次强调时,可以避免在后期迭代开发中丢失掉原本的优点。

  问题的列举肯定是报告中非常重要的部分,但切勿罗列出清单就草草了事,因为:

  1、某个(些)问题和另一个(些)问题是有关联的,但是报告中的问题列表部分却割裂了这些联系。

  2、产品设计人员无法一直参与旁听/观察可用性测试的过程,导致对报告中文字描述的问题缺乏感性认识。

  3、只提问题却不提供解决方案,就不是“建设性地提问”!

  因此,我们需要在可用性测试报告的后半部分提出针对重要问题的解决方案。其目标并非是强迫产品设计人员一定要采纳我们提出方案,而是:(1)把一些相关问题联系起来看,(2)加深报告阅读者对于问题的感性认识和背后原因的理解,(3)使整个报告的思路更清晰、完整,(4)我们还可学到一些交互设计和产品的知识。

  总之,可用性测试施行起来既简单又复杂。简单是因为不管你如何施行,终究能发现一些问题;复杂则在于发现可用性问题的质量、重要性、对测试的利用效率、对产品设计人员的帮助程度可能相距甚远。一次成功的可用性测试体现在从前期策划、测试过程、后期报告等整个过程中是否遵循了这些原则,并在某些难以两全的原则面前做到合理的权衡取舍。

posted @ 2011-12-05 14:45 顺其自然EVO 阅读(206) | 评论 (0)编辑 收藏

使用单元测试的原因及使用前的准备

使用单元测试的原因及使用前的准备

  1、自傲的编码

  有一次——或许就是上个礼拜二——有两个开发者:Pat 和Dale。他们面临着不异的最后一日,而这一天也越来越近了。Pat 天天都在焦心地编写代码,写完一个类又写一个类,写完一个函数又接着写另一个函数,还经常不得不停下来做一些调整,使得代码能够经由过程编译。

  Pat 一向连结着这种工作体例,直到最后一日的前一天。而这时已经是演示所有代码的时候了。Pat 运行了最上层的轨范,可是一点输出也没有,什么都没有。这时只好用调试器来单步跟踪了。“Hmm,决不成能是这样的”,Pat 想,“此时这个变量绝对不是0 啊”。于是,Pat 只能回过头来看代码,考虑着跟踪一下这个难以琢磨的程序的挪用流程。

  时刻已经越来越晚了,Pat 找到且更正了这个bug;但在这个过程中,Pat 又找到了其他好几个bug;如斯几回事后,bug 仍是存在。而程序输出何处,仍然没有结果。这时,Pat 已经筋疲力尽了,完全搞不清为什么会这样,认为这种(没有输出的)行为是毫无事理的。

  而于此同时,Dale 并没像Pat 那么快地写代码。Dale 在写一个函数的时候,会附带写一个简短的测试程序来测试这个函数。这并没有什么非凡的处所,只是添加了一个简单的测试,来判定函数的功能是否和程序员期望的一致。显然,考虑如何写,然后把测试写出来,是需要占用一定时间的;可是Dale 在未对刚写的函数做出确认之前,是不会接着写新代码的。也就是说,只有等到已知函数都获得确认之后,Dale 才会继续编写下一个函数,然后挪用前面的函数等等。

  在整个过程中,Dale 几乎不使用调试器;而且对Pat 的模样也有些思疑不解:只见他头埋在两手之间,嘀咕着各类难听的话语,诅咒着计较机,充血的眼球同时盯着好几个底时景口。

  最后一日终于到了,Pat 未能完成使命。而Dale 的代码被集成到整个系统中,而且能够很好地运行。之后,在Dale 的模块中,呈现了一个小问题;可是Dale 很快就发现了问题地址,在几分钟之内就解决了问题。

  此刻,是该总结一下这个小故事的时候了:Dale 和Pat 的年数相当,编码能力相当,智力也差不多。唯一的区别就是Dale 很是相信单元测试;对于每个新写的函数,在其他代码使用这个函数并对它形成依靠之前,都要先做单元测试。

  而Pat 则没有这么做,他老是“知道”代码的行为应该和所期望的完全一样,而且等到所有代码都差不多写完的时候,才想起来运行一下代码。然而到了这个时辰,要想定位bug,或者,甚至是确定哪些代码的行为是正确的,哪些代码的行为是错误的,都为时已晚了。

  2、什么是单元测试

  单元测试是开发者编写的一小段代码,用于磨练被测代码的一个很小的、很明晰的功能是否正确。凡是而言,一个单元测试是用于判定某个特定前提(或者场景)下某个特定函数的行为。例如,你可能把一个很年夜的值放入一个有序list 中去,然后确认该值呈现在此刻list 的尾部。或者,你可能会年夜字符串中删除匹配某种模式的字符,然后确认字符串确实不再包含这些字符了。

  执行单元测试,是为了证实某段代码的行为确实和开发者所期望的一致。

  对于客户或最终使用者而言,这种测试需要吗,它与验收测试有关吗?这个问题仍然很难回覆。事实上,我们在此并不关心服个产物确认、验证和正确性等等;甚至此时,我们都不去关心性能方面的问题。我们所要做的一切就是要证实代码的行为和我们的期望一致。所以,我们所要测试的是规模很小的、很是独立的功能片段。经由过程对所有零丁部门的行为成立起抉择信念,确信它们都和我们的期望一致;然后,我们才能起头组装和测试整个系统。

  事实下场,若是我们对手上正在写的代码的行为是否和我们的期望一致都没把握,那么其他形式的测试也都只能是华侈时刻而已。在单元测试之后,你还需要其他形式的测试,有可能是更正规的测试,那一切就都要看情形的需要来抉择了。总之,做测试如同做善事,老是要巨匠(代码最根基的正确性)起头。

  3、为什么要使用单元测试

  单元测试不单会使你的工作完成得更轻松,而且会令你的设计变得更好,甚至削减你花在调试上的时间。

  在我们之前的小故事中,Pat 因为假设底层的代码是正确无误的而卷入麻烦之中,先是高层代码中使用了底层代码;然后这些高层代码又被更高层的代码所使用,如斯往来来往。在对这些代码的行为没有任何抉择信念的前提下,Pat 等于是在假设用竖立卡片堆砌了一间房子——只要将下面卡片轻轻移动,整间房子就会轰然倾塌。

  当根基的底层代码不再靠得住时,那么必需的改动就无法只局限在底层。虽然你可以批改底层的问题,可是这些对换层代码的改削必然会影响到高层代码,于是高层代码也连带地需要修改;以此递推,就很可能会动到更高层的代码。于是,一个对换层代码的批改,可能会导致对几乎所有代码的陆续串改动,如此而使改动越来越多,也越来越复杂。于是,整间由卡片堆成的房子就由此倾塌,从而使整个项目也以失踪失败了却。

  Pat 老是说:“这怎么可能呢?”或者“我其实想不明白为什么会这样”。你发现自己有时候也会有这种想法。那么凡是你对自己的代码还缺乏足够抉择信念的默示——你并不能确认哪些是工作正常的而哪些不是。

  为了获得Dale 所具有的那种对代码的抉择信念,你需要“询问”代码事实做了什么,并搜检所发生的结过是否确实和你所期望的一致。

  这个简单的设法描述了单元测试的焦点内在:这个简单的手艺就是为了令代码变得加倍完美。

 4、我需要做什么

  其实惹人的单元测试是很简单的,因为它自己就布满了乐趣。然而在项目交付的时候,我们给客户和最终用户的仍然是产物代码,而不包含单元测试的代码;所有,我们必需对单元测试的目的有个充实的熟悉。首先也是最主要的,使用单元测试是为了使你的工作——以及你队友的工作——完成得加倍轻松。

  ● 它的行为和我的期望一致吗?

  最根柢的,你需要回覆下面这个问题:“这段代码达到我的目的了吗?”也许代码所做的是错误的工作,但那是另外的问题了。你要的是代码向你证实它所做的就是你所期望的。

  ● 它的行为一向和我的期望一致吗?

  很多开发者说他们只编写一个测试。也就是让所有代码从头至尾跑一次,只测试代码的一条正确执行路径,只要这样走一遍下来没有问题,测试也就算是完成了。

  可是,现实当然不会这么事事顺心,工作也不老是那么顺利:代码会抛出异常,硬盘会没有残剩空间,收集会失踪线,缓冲区会溢出等——而我们写的代码也会呈现bug。这就是软件开发的“工程”部门。就“工程”而言,土木匠工程师在设计一座桥梁的时候,必需考虑桥梁的负载、强风的影响、地震、洪水等等。电子工程师要考虑频率漂移、电压尖峰、噪音,甚至这些同时呈现时所带来的问题。

  你不能这样来测试一座桥梁:在风和日丽的某一天,仅让一辆车顺遂地开过这座桥。显然,这种测试对于桥梁测试来说是远远不够的。相似地,在测试某段代码的行为是否和你的期望一致时,你需要确认:在任何情形下,这段代码是否都和你的期望一致;譬如在参数很可疑、硬盘没有残剩空间、收集失踪线等的时候。

  ● 我可以依靠单元测试吗?

  不能依靠的代码是没有多大用处的。但更糟糕的是,那些你自认为可以相信的代码(可是结果证实这些代码是有bug 的)有时候也会让你花很多时间在跟踪和调试上。显然,几乎没有项目可以许可你在这上面花费太多的时间,是以无论如何,你都要避免这种“前进一步,萎缩后退两步”的开发体例。也就是说,要闪开开发过程连结不变的轨范前进。

  没人能够写出十全十美的代码;可是这并没有关系——只要你知道问题的地址就足够了。很多类型软件项目的失败,诸如只能把坏了的太空船搁浅在遥远的行星,或者在翱翔的途中就爆炸了,都能经由过程确认的限制来避免。例如,Arianne 5 号火箭软件重用了来自于之前一个火箭项目的一个程序库,而这个程序库并不能措置新火箭的翱翔高度(比原本火箭要高),从而在起飞40 秒之后就发生了爆炸,导致5 亿美元的损失踪。

  显然,我们但愿能够依靠于所编写的代码,而且清楚地知道这些代码的功能和约束。

  例如,假设你写了一个反转数值序列的体例。在测试的过程中,你也许会传一个空序列给这个程序——但导致了程序解体。现实上,轨范并没有要求该轨范必需能够领受一个空序列,是以你可以只在体例的注释中声名这个约束:如不美观传递一个空序列给这个体例,那么这个体例将会抛出一个异常。此刻你马上就知道了该代码的约束,年夜而也就不需要用其他很麻烦的体例来解决这个问题(因为在某些地址要解决这个问题并未便利,好比在高空年夜气层中)。

  ● 单元测试声名我的意图了吗?

  对于单元测试而言,一个最让人欢快的意外收成就是它能够辅佐你充实理解代码的用法。简单而言,单元测试就像是能执行的文档,了然在你用各类前提挪用代码时,你所能期望这段代码完成的功能。

  项目成员能够经由过程查看单元测试来找到如何使用你所写代码的例子。如果他偶然发现了一个你没有考虑到的测试用例,那么他也可以很快地知道这个事实:你的代码可能并不支持这个用例。

  显然,在正确性方面,可执行的文档有它的优势。与通俗的文档分歧的是,单元测试不会呈现与代码纷歧导致的情形(当然,除非程序选择不运行这些测试)。

  5、如何进行单元测试

  单元测试原本就是一项简单易学的手艺;可是如果能够遵循一些指导性原则(guideline)和根基规范,那么进修将会变得加倍轻易和有用。

  首先要考虑的是在编写这些测试用例之前,如何测试那些可疑的用例。有了这样一个概略的想法之后,你将可以在编写实现代码的时候,或者之前,编写测试代码。

  下一步,你需要运行测试用例,或者同时运行系统的所有其他测试,甚至运行整个系统的测试,前提是这些测试运行起来相对斗劲快。在此,我们要确保所有的测试都能够经由过程,而不只是新写的测试能够经由过程;这一点长短常主要的。也就是说,在保证不惹人直接bug 的同时,你也要保证不会给其他的测试带来破损。

  在这个测试过程中,我们需要确认这个测试事实是经由过程了还是失败了——但这并不意味着你或者其他晦气的人需要查看每个输出,然后才抉择这些代码是正确的还是错误的。

  在此,你慢慢地就会养成一个习惯:只要进行一次单元测试查看一下测试结果,就可以马上知道所有代码是否都是正确的,或者哪些代码是有问题的。关于这个问题,我们将留在讨论如何使用单元测试框架时来具体讨论。

posted @ 2011-12-05 14:35 顺其自然EVO 阅读(168) | 评论 (0)编辑 收藏

重构——构筑测试体系

 构筑测试体系

  如果你想进行重构,首要前提就是要拥有一个可靠的测试环境。

  “编写优良的测试程序,可以极大的提高我的编程速度,即使不进行重构也是如此。”

  1、自我测试代码(Self-testing Code )的价值

  “Class 应该包含他们自己的测试代码。”

  “每个Class 都有一个测试函数,并用它测试自己这个 Class 。”

  确保所有的测试都完全自动化,让它们检查自己的测试结果。

  只要写好一点功能,就立即添加测试。

  一整组(a suite of )测试就是一个强大的“臭虫”侦测器,能够大大缩减查找“臭虫”所需要的时间。

  “实际上,编写测试代码的最有用时机是在开始编程之前。当你需要添加特性的时候,先写相应的测试代码。听起来离经叛道,其实不然。填写测试代码其实就是问自己:添加这个功能需要做什么。编写测试代码还能使你把注意力集中于接口而非实现上头(永远是件好事)。预先写好的测试代码也为你的工作按上一个明确的结束标志:一旦测试代码运行正常,工作就可以结束了。”

  构建自我测试的代码。

  2、JUnit测试框架( Testing Framew )

  频繁的运行测试,每次编译请把测试也考虑进去,每天至少执行每个测试一次。

  单元测试功能测试

  “每当你接获臭虫提报,请先撰写一个单元测试来揭发这只臭虫。”——如何揭发?这里需要根据报告准确定位。单元测试会对此有帮助吗?

  3、添加更多的测试

  “观察Class 该做的所有事情,然后针对任何一项功能的任何一种可能失败的情况,进行测试。”

  “测试应该是一种风险驱动(risk driven )行为,测试的目的是希望找出现在或未来的可能出现的错误。”

  “测试的诀窍是:测试你最担心的部分。”

  这点和我目前的想法不大相同。我目前的想法是,测试要对程序做100% 的保证,所以,要测试程序可能行为的每一种情况,保证其正确性。按照我的想法,值域的设置和访问函数也是要测试的。作者的意思是,测试代码要用最低的成本,获取最大的收益。这一点,要我在实际的环境中进行抉择。

  “编写不是十分完美的测试并实际运行,好过对完美测试的无尽等待。”——我持怀疑态度。

  运用测试用例前后执行的函数:tearDown 和 setUp,保证测试用例之间相互隔离,而非相互影响。

  做一个懒惰的程序员。

  考虑可能出错的边界条件,把测试火力集中在那儿。

  “测试(优先)可以调高编程速度”,这一点我要在实践中验证一下,如果真是这样,那我就要尝试在我们部门推行这种方法。

  “当测试达到一定的程度后,测试效益会呈现递减态势。”所以,你不要期望通过测试找出所有的bug ,而是要通过测试,找出绝大多数的 bug 。

  这个地方其实也符合“二八定律”:即20% 的测试可以找出 80% 的 bug,其余的 80% 的测试可以找出剩下的 20% 的 bug 。我们要做的,就是写这 20% 的测试,而非 100% 的测试。

posted @ 2011-12-05 14:24 顺其自然EVO 阅读(173) | 评论 (0)编辑 收藏

VS2010中的自动化测试——Web性能测试

 一、概述

  网站的性能由很多不同的因素决定,比如:网络速度、不同的浏览器或者在同一时刻的用户数量、硬件处理能力等因素,都会影响到网站的性能和响应时间。Web性能测试就是帮助开发者在开发工程中就能确认并尽力修复这些问题。

  下面讨论几种主要的性能测试

  ● Validation and verification test: 这个测试用来帮助我们检验输入值和是否能在期望的入口安全登录。比如:一个字段要求你输入一个Email地址,那么你必须正确输入才能提交页面。

  ● Web page usability test: 它相当于是在生产环境中,通过模拟用户行为来查看网站内容是否完整。比如:每个链接是否正确或者页面上的信息是否显示正确等。

  ● Security Testing: 它帮助我们检验不同权限的用户是否能得到相应的内容,还有对本地或者服务器上其它资源文件的访问权限。

  ● Performance Testing: 帮助我们验证在特地环境下页面响应的时间,它包括压力测试和负载测试。

  ● Testing web page compatibility: 这个就是验证网站在不同浏览器上的兼容性。

  ● Testing a web application using different networks: 这个测试取决于我们的最终用户是处在什么样的网络环境中。

  对于Web性能测试,还有很多其它相关的测试,比如不同的操作系统、不同的数据库的影响等等都与性能有一定的关系。

  上面我所说的性能测试,在VS2010中提供了相应的工具,为我们进行测试,下面我们就来创建一个简单的Web性能测试。

  二、创建Web性能测试

  在我们创建Web性能测试之前先创建一个简单的网站,包括一个添加用户数据和显示用户数据的网页,数据表设计如下:

  网站用户界面如下:

  这个Web应用程序可以部署在Web服务器上进行测试,也可以直接在ASP.NET Development Server上进行测试,当然,如果在开发环境上测试,需要保持Development Server运行着。

  现在开始来创建一个Web性能测试,可以直接点击VS工具栏上Test->New Test…,然后选择如图所示文件:

 

点击OK后,会提示你新建一个测试工程,并给它命名,然后点击Create。这时会弹出一个IE窗口如下所示:

  左侧是一个Web Test Recorder(有可能在你创建测试文件后,弹出IE时没有这个东西出现,你可以通过IE的工具->管理加载项选项中将Web Test Recorder启用),它主要用来记录浏览测试网页时所有的操作,它会将所有的request和response记录下来,它还可以帮我们在不同的情况下找出我们期望的结果。

  现在我们输入刚刚创建的那个网页的地址,然后我们输入一些信息进行提交:

  点击Insert之后,我们会看到Recorder帮我们捕捉到一些信息:



完成所有操作后,点击Recorder面板中的Stop按钮,我们就可以自动跳转回VS中,并显示出之前记录的所有请求信息。

  至此,一个简单的Web性能测试就建好了。可以点击工具栏左上角的运行测试一下。上图显示的是一个Web性能测试的编辑窗口,窗口中,树的每一个层级都有不同的属性可以进行设置。除此之外,编辑窗口还有一个工具栏,能为测试用例提供不同的功能以及数据源等。

  下面我来详细说一下性能测试编辑窗口中的各个功能及操作。

  上次说到我们编辑窗口中的树结构,每一层都会有不同的属性设置。

  ● Root Level:可以说是一条Web性能测试的入口点,比如:可以在此设置用户验证、代理或者为这条测试添加一些描述信息等;

  ● Request Level:在Web性能测试中记录下来的每一条单独的请求,可以在此设置用户思考时间(think time)、请求方式(GET或者POST)或者设置是否缓存等;

  ● Request Parameter Level: 这里是每次请求的参数设置,可以在此设置是否进行Url编码、值还有名称。

  这里所有的属性设置你都可以在属性视窗中看到说明,如果还有不懂的,可以查看MSDN进行帮助,所有的属性都在Microsoft.VisualStudio.TestTools.WebTesting这个命名空间下。

  三、提取规则(Extraction Rules)

  在VS中我们可以用提取规则的功能把网站中的一些有用的数据提取出来。

  通常情况下,几乎所有的网站,它们页面之间总会有一些依赖关系,比如说你的下一个请求依赖你上一次请求响应中得到的一些数据。所以提取规则这个功能就是可以让你从响应的数据中提取到你需要的数据,并保存下来,用于你下一次的请求或者你之后需要的时候。它保存下来的数据在一个上下文参数中,你可以在全局环境中使用它。

  在VS2010中已经为我们内建了几种提取规则,如图:

  关于内建提取规则说明,可参见这里。如果内建的这些提取规则还不能满足你的需要,也可以自定义自己的提取规则。



 这里我借百度(偷个懒^_^)做个Demo,看下怎么使用提取规则。

  根据上篇内容,首先利用Recorder来打开百度,然后随便搜索一个东西(我百度的James),最后点击Stop,会在VS中生成如下数据:

  现在我们在第一请求节点上右键添加一个提取规则,因为我是要提取第一次请求响应回来的中的值,如下所示:

  提取规则设置如下:



 通过上面的设置,我将百度页面中,搜索按钮的值(“百度一下”)进行了提取,那么baidu这个参数在之后的程序中将一直保存着这个值。它的访问方式类似于key-value这样的形式。我们运行一下这个测试,就可以在结果中看到我们提取的信息了。

  我们可以将保存出来的信息用于下一次请求或者之后的任何一次请求中,比如我们可以修改第二个请求中需要搜索的值:

  通过右键属性,然后在值属性中,将它重新绑定到baidu属性,我们还需要注意一下的是我们之前提取的值是中文,所以需要将Url编码设置为ture。最后我们重新运行一下测试看下结果:

  这里可以看到我们的第二次搜索不在是James,而是“百度一下”了。

  四、验证规则(Validation Rules)

  很多网站都有一些验证程序来验证输入或者输出是否正确,比如:用户名不能含有特殊的字符、密码不得少于6个字符或者正确的Email格式等等。

  验证规则这个功能就是验证响应的数据是否包含期望的信息,如果有,这条请求就可以pass,否则就会fail。

  我的VS2010也内建了几种验证规则:

  关于内建的验证规则说明,可参见这里。如果内建的这些验证规则还不能满足你的需要,也可以自定义自己的验证规则。

  验证规则的使用方法其实和提取规则差不多,但是它只是起验证的作用,而不会帮你保存数据。但是要注意的一点是,随着验证规则的增多,网站的性能测试和测试时间都将受到影响,尤其是在做压力测试的时候,更要决定好哪些数据非常重要的、需要验证的。当然,VS中也提供设置验证规则的级别来降低这些影响。

posted @ 2011-12-05 14:17 顺其自然EVO 阅读(1850) | 评论 (0)编辑 收藏

正视测试正视第三方测试机构

 如何面对软件产品大型化、复杂化、系统化带来的挑战,抓住云计算带来的发展新机遇,解决软件测试理论、工具与应用不相适应的矛盾?如何推动软件质量保证体系向纵深发展,结合超大规模复杂系统对可靠性的要求,将软件质量管理与开发过程紧密结合,帮助企业实现软件质量水平的持续提升?如何破解软件知识产权遭受侵犯的难题,将中国软件知识产权的保护与软件著作权的申请、使用、管理相结合,建立促进软件正版化与产业技术创新的长效机制?如何培养高端、复合型软件人才,突破软件产业遭遇的人才瓶颈,建立符合软件人才市场需要的培训体系,满足企业对专业领域软件人才的需求?如何应对货币政策逐渐收紧的趋势,开拓融资渠道,创新为软件园区和企业提供个性化的投融资服务?

  面对软件产业技术变革,创新商业模式成为应对变革的重要手段,本届年会以“前瞻科技创新 重构商业未来”为主题,成功举办了主论坛与软件知识产权、软件人才培养、软件投融资、软件测评技术和软件质量保证五个分论坛。来自工信部的领导、两院院士及典型企业总裁等与业界一起分享“软件产业商业模式面向服务的创新与变革”,促进新模式下认证测试、产品质量、知识产权、人才培养、投融资体系等软件产业生态重构,促使软件产业步入融合、转型和调整的新阶段,助推中国新一轮软件产业发展浪潮。大会期间,记者就中国软件评测中心周润松先生进行了采访。

  Q:在软件公司,开发人员和测试人员是否有一个合适的比例?比如在一家偏向研发的公司,研发人员相对占多数。而在一家做测试的公司,相对测试人员占多数,是否有这样的比例问题呢?

  A:与我国的国情有关。更与软件测试的受重视轻度有关。在国内,软件测试逐渐被重视。包括软件产品有登记测试,可以证明企业有能力生产这个软件,而这个测试只是政府的行为,作为简单的抽测。从软件工程师角度来说,从 2004年开始有测评师这样一个增项。很多研发型企业并没有专门的测试人员,软件的测试工作就由研发者自己来完成。有的企业也可能做交叉型的测试,比如两个工程师互测,但这样的情况并没有很好的开展。自己研发自己测试有个弊端,开发者会有固定的思维定式,很难解决软件自身的问题。企业保证研发就已经是很吃力的事情就不可能投一笔资金来维护一堆测试人员。相对国内,测试人员相对匮乏,我们也可以在一些报道上看到极度缺乏测试人员这样的广告。我们缺少的不是低端的测试人员我们缺少的是对测试有较高领悟的高端测试人才。

  Q:帮助理解“测试人员的成功不在于找出多少个Bug,而是说服开发人员修复多少个Bug”这句话。

  A:测试工程师的使命是发现程序中的缺陷,但在企业固有投入的状况下不可能完全修复所有的缺陷。企业也好,开发人员也好都有自己的权衡。往往在测试的时候有个过程,从理解软件开始到实施测试。测试之后才会发现软件的缺陷,此时我们才会和开发人员进行核对,如果不是对软件对业务流程理解问题那么此时才会进一步考虑,在现有投入状态下,这个版本是否需要修复这个缺陷或者直接将这个功能删掉,或者下个版本时将此功能修复好。软件的缺陷可分为三级,重要级别,一般级别以及建议级别。遇到严重级别的bug,必须要进行修复,否则将会导致软件崩溃。一般级别的bug,并不会影响系统的正常运行,依据情况进行修复。而建议性问题则在易用性以及美观度提出一些建议。通常情况下,测试并不是保证软件没有任何问题,而是更多的去发现问题,叫软件更健壮叫用户使用起来更放心。

  Q:在您的工作中是否遇到过这样的情况,肩负开发和测试双重工作的人员,是否会比较烦感测试,他们宁可去写代码也不喜欢进行测试?

  A:你提出这样的质疑可能是你会关注开发人员和测试人员薪酬的问题。在我国,开发人员的薪酬要远远高于测试人员,而在国外却恰恰相反。如果你是一名合格的测试工程师,你所处的位置应该是在开发人员之上的,并不是一个不懂开发的人。相对开发人员,测试人员的开发功底相对较低,在一些小企业中,他们的测试只是简单的功能验证,只是将正向的合理的流程顺利走完,他们并没有针对异常输入以及恶意行为进行测试。

  Q:我们的测试是否和“跑分”的测试一样呢?

  A:非也。你所说的跑分测试,其实是个基准测试,定义一个评分体系,而我们拿到产品便会对其原始需求进行分析,承诺的需求是什么样子,然后根据需求详细到测试点,再对其设计测试方法进行测试,如果满足我们的要求说明该测试点没有问题,如果没有通过则是一个缺陷。最终出一份报告,报告的内容是告诉系统目前有哪些地方没有达到标准,为何没有达到标准。

  Q: 目前我国有很多相关培训,如果说学员学满而归,所在企业购买一套测试系统,如果是这样,我们这样的第三方测试机构岂不是没有什么作用了?

  A: 这样的情况也有,不过有句话说的比较贴切,叫“王婆卖瓜”。有些时候测试的能力与我们相当,并能出一份类似的评测结果。而我们目前的角色是充当一个第三方的角色,我们更多的是去验证你的话是否如你所说。我们培训的学员虽然是参加了培训,但能否建立一个有效的测试体系和测试团队我们不敢打这样的保票。如果产品我们来测试可能我们出的测试报告有100页,而他们自己可能只有十几页,这充分说明了测试的细腻度不同。

  采访对象周润松简介:

  硕士,高级专业职称,核高基实施部、高级测试工程师。 2004 年 5 月加入中国软件评测中心至今,多次主持国家大型政府网站及办公应用系统的性能测试与调优工作,同时参与电子发展基金 IPv6 测试平台研究工作。在 J2EE 应用系统测试领域,多次作为项目负责人领导组织大型应用系统的性能测试与调优工作,具备相当丰富的大型应用系统现场性能测试及调优工作经验。先后参与了中石化人力资源管理系统、国家开发银行办公应用系统、北京市公安局 110 接处警系统、中国移动 12580 信息查询系统等性能测试工作。 2007 年底至 2008 年 6 月份,领导完成了第 29 届奥运会票务系统的功能以及性能测试工作,通过测试优化,有利的保证了票务系统的第三次实时售票工作,系统承受了页面峰值流量 2900 多万 / 小时。同时在城市智能交通领域,配合北京市交管局完成了美国 NTCIP 城市智能交通系统开放式通讯协议的引进工作,多次配合北京市交管局进行城市智能交通信号控制器的 NTCIP 通讯协议选型测试工作,发表期刊论文一篇,并成功组织了一次国内城市智能交通通讯协议研讨会,极大的推动了 NTCIP 协议在国内的推广。

posted @ 2011-12-05 14:01 顺其自然EVO 阅读(149) | 评论 (0)编辑 收藏

需求变更的烦恼

客户今天要求变更需求,加某某功能,“这个应该不难吧,某某公司的产品都有这个功能的。”客户的需求一直在变,烦恼。。。

  开始是需求不明确,客户都不知道要做成什么样,只有一个大概的粗略的描述。等到大楼盖好了,给客户,却发现大楼应该是这样那样的......客户方和开发方在一起( WorkShop) 还好,如果分开在两地就更糟糕......

  永远不变的就是变化,这个大家都知道,但关键是如何合理的控制需求变更

  我以前做的上百人一年多一个的大项目,完全按照CMMI Level3规范来控制需求变更的。起初有双方签字的经过评审的需求基线,以后需求变更的时候有需求变更委员会(CCB)或专门负责的角色(通常由客户方需求人员来收集和评估最初需求并提交给QA,QA牵头需求变更流程)来处理需求变更,具体做法是:

  1、先是客户或项目组成员提出的需求申请,填写《变更申请单》并提交给项目经理。

  2、项目经理组织项目相关人员对需求变更进行评估和调研,然后组织需求变更评审。

  3、如果同意变更则由CCB授权配置管理员检出配置项由项目组成员对相关的文档(用户需求说明书、需求规格说明书)进行修改,修改后评审(同时 填写《变更管理记录表》)通过后由高层经理审批,然后提交用户确认,最后纳入配置库,更新《需求追踪矩阵》,确保需求和工作产品的一致性;

  4、如果不同意变更,则项目经理、部门经理与客户共同协商,协商后同意变更,则对相关的文档进行修改。协商后依然不统一,则需求变更结束。

  5、所有的需求变更都需要总经理理进行审批。需求变更的影响:利用《需求跟踪矩阵》对变更影响进行评估;估计对项目参数的影响—规模、工作量、进度影响;超出阀值(整个项目进度的10%- 15%,里程碑30%)的,应提交高层评审/批准。

  6、妥善保存变更产生的相关文档。

  现在公司做的项目规范较小,完全按照CMMI的规范来有点多余,所以我们基本上类似于敏捷开发的模式。敏捷编程是拥抱变化,持续重构和改进,迭代开发,频繁交付。在需求变更管理上我们还没有一套完整的合适的流程,具体做法是:

  1、客户提出新需求;

  2、开发人员或项目经理评估后答应了;

  3、继续开发,时间表按照重新评估后的进行;

  4、基本上很少拒绝客户;一方面是为了维护客户关系,另一方面对自己team的开发能力很自信; 结果是上头答应了客户,下头的只能加班加点赶工。

  另外还有一些控制需求的做法:

  1、项目前期会首先快速开发一个产品原型(Prototype)给客户,有界面的先用visio画个界面,以验证业务规则、业务流程和大概GUI等。另外,产品原型也有助于进一步挖掘用户的需求。

  2、会粗略的列出大体的需求并签字

  3、频繁交付给客户,短周期的交付可工作的产品,以印证需求与实现是否一致,同时兼做客户教育工作。

  问题是如果需求变更无休止,则需求变更几乎就不可控,项目开发也无休止。所以我觉得我们公司在需求管理上还缺乏:

  1、需求基线管理,经过评审的双方确认签字的需求基线。以后如果要超出或修改需求基线,则必须有专门的人员对此提出异议,由CCB审核后方可修改;

  2、专门的需求控制负责人。现在基本上是技术人员或是项目经理收到客户需求变更,然后自己评估下就答应了。缺乏专门的需求控制负责人,因而没有需求评审,没有一套专门的严格可控的需求变更流程。

  3、需求功能点列表的书面确认。现在签的只是非常粗略的大体需求,定性而没有定量,以后扯皮发生的可能性非常大;

  4、适当时候应该拒绝客户的要求。虽然用户有众多的理由,比如他认为改动不大,竞争对手已经拥有该功能,或是新的业务需要,但如果评估后的结果是没有必要,或不合理,或优先级不高,或风险大于必要,则坚定的拒绝。另外一种变通的方法是,根据优先级重要性有条件的答应,比如放在下一次版本之后。

  5、需求Scope的管理,不仅要明确做什么,而且要明确不做什么。什么是我们负责的,什么不是我们应该负责和提供的。

  另外在需求变更管理中,和客户有效的沟通、协调和教育非常重要。说的好点,就是“要讲究沟通的艺术”,“多引导客户”;说得俗点,就是“摆平客户”。如果能够对客户进行很好的客户教育,很多时候客户是可以理解开发过程中的困难,从而达到妥协或折中。比如客户理解了项目后期进度紧张,技术架构难以大改,就会在资源、进度、功能上做一些折中的选择,比如把功能分主要功能先实现,次要功能后实现;核心业务保稳定,次要业务不能牺牲核心业务的稳定性等等。反之,如果没有和客户有效的沟通、协调和教育,则会双方各执一词,搞业务的只讲业务、流程和功能,不考虑技术可行性,不考虑资源和时间表;搞技术的只讲技术,没有倾听客户的正当的商业需求,不能满足客户利益的最大化,这样双方就很难达成双赢的结果。所以,有效的沟通是软件项目成功的关键。

posted @ 2011-12-05 13:57 顺其自然EVO 阅读(173) | 评论 (0)编辑 收藏

项目质量测试方面的心得

软件质量是实现客户满意度的关键,而质量管理主要靠测试。我在这方面的心得体会是:

  第一是建立一套高效完善的测试体系至关重要;

  第二是选择一套适当的测试工具来辅助整个测试体系的运作很有必要;

  第三是在选择测试工具后关键是灵活应用工具并不断改进流程以适合自身团队的实际情况。

  不能孤立地看待测试体系建设问题,必须将测试体系和测试工具有机地结合起来看。测试体系反映了对测试工作的基本认识和基本需求,但如何使它具备足够的可操作性而不是流于形式呢?我的看法是通过与工具的结合可以有效解决这一问题。

  这就引出第二个观点:选择一套适当的测试工具来辅助整个测试体系的运作很有必要。我们现在用了两类测试工具:测试管理工具和自动化测试工具。测试管理工具能够使我们的测试流程变得行之有效。我们现在这个项目中有近130人,包括一支超过20人的测试队伍,测试管理工具在其中发挥了很好的作用。自动化测试工具也是一个很好的主意,它能够比较有效减轻劳动强度,节省一定的手工时间。我们目前所设计的测试案例数已接近1万个,完全依靠手工是不可想象的。那么,如何选择适合我们需要的测试工具呢?我们的标准主要有两个:一是各类不同用途的测试工具能够有机地结合在一起,形成一个整体;二是界面要足够人性化,能够尽可能多地满足人的需要。

  最后,是在选择测试工具后关键是灵活应用工具并不断改进流程以适合自身团队的实际情况。可以寻求适当的测试咨询专家来就上述两方面提供测试咨询服务。上次我们在这方面请了两名专家,效果非常好。我们自己的测试队伍被培养出来,整个测试体系正在逐步有效地运作,各种测试工具逐步在有效运用,自动化测试程度也在不断提高,而这一切都发生在专家加入后的三个月时间内。

  总之,软件质量体系是人、流程、工具的有机结合。流程和制度制订的好,不如执行的好。

posted @ 2011-12-05 13:50 顺其自然EVO 阅读(170) | 评论 (0)编辑 收藏

Java代码规范那些事

Java开发中所要遵守的编码规范大体上有如下7点。命名规范、注释规范、缩进排版规范、文件名规范、声明规范、语句规范以及编程规范。

  1、命名规范

  (1)所有的标示符都只能用ASCⅡ字母(A-Z或a-z)、数字(0-9)和下划线“_”。

  (2)一个唯一包名的前缀总是全部小写的字母。例如:www.tonysun.cc

  (3)类名是一个名词,采用大小写混合的方式,每个单词的首字母大写。例如:Tony。

  (4)接口的大小写规则与类名相似:例如:Tony。

  (5)方法名是一个动词或动词词组,采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写。例如:setNeekeName(String neekeName)。

  (6)变量名第一个字母小写,任何中间单词的首字母大写。变量名应简短且可以顾名思义,易于记忆。例如:neekeName、neekeAddress。避免单个字符的变量名,除非是一次性的临时变量。

  (7)常量的声明应该全部大写,每个单词之间用“_”连接。例如:final String WWW_TONY_CN = “www.tonysun.cc”;

  2、注释规范

  (1)注释尽可能使用“//”;对于所有的javadoc的注释则使用“/** */”;而临时对代码块进行注释尽量使用“/* */”。

  (2)所有的源文件都应该在开头有一个注释,其中列出文件名、日期和类的功能概述。

  (3)每个方法必须添加文档注释(类的main()方法除外)。

  (4)每个属性必须添加注释。

  (5)代码中至少包含15%的注释。

  (6)注释使用中文。

  3、缩进排版规范

  (1)避免一行的长度超过60个字符。

  (2)使用Eclipse的源代码的格式化功能完成代码的缩进排版(Ctrl+Shift+F)。

  4、文件名规范

  (1)一个Java源文件只能存储一个Java类。

  (2)文件名与Java类名相同。

  (3)一个类文件的代码行不超过200行。

posted @ 2011-12-05 13:47 顺其自然EVO 阅读(124) | 评论 (0)编辑 收藏

保护你的Web服务器 iptables防火墙脚本全解读

本文假设你已经对iptables有基本的了解,否则请先阅读iptables入门。

  在我们的Web服务器上,系统的默认策略是INPUT为DROP,OUTPUT;FORWARD链为ACCEPT,DROP则设置得比较宽松,因为我们知道出去的数据包比较安全。

  准备工作

  为了验证脚本的通用性,我特地查看了服务器的内核及iptables版本:

# uname -a
Linux ud50041 2.6.9-34.ELsmp #1 SMP Fri Feb 24 16:54:53 EST 2006 i686 i686 i386 GNU/Linux
# iptables -V
iptables v1.2.11
# lsb_release -a
LSB Version: :core-3.0-ia32:core-3.0-noarch:graphics-3.0-ia32:graphics-3.0-noarch
Distributor ID: RedHatEnterpriseAS
Description: Red Hat Enterprise Linux AS release 4 (Nahant Update 3)
Release: 4
Codename: NahantUpdate3

  大家可以发现,这台服务器的系统、内核和iptables版本是比较老的。本文中介绍的脚本涉及到recent安全模块,这对系统内核有要求(recent模块在主机防护脚本中也经常用到)。因此,如果大家要采用iptables作为主机防火墙时,建议用CentOS 5.6 x86_64或更高级版本,不然系统会有如下提示错误信息:

iptables: Unknown error 18446744073709551615
iptables:Invalid argument

  在tail -f /var/log/messages时会有如下出错提示:

ip_tables: connlimit match: invalid size 32 != 16
ip_tables: connlimit match: invalid size 32 != 24

  另外,在生产环境下进行iptables脚本的调试之前,强烈建议编写crontab任务,每5分钟关闭一次iptables脚本,防止操作失误而将自己的SSH客户端锁在外面:

*/5 * * * * root /etc/init.d/iptables stop

  准备工作就是这些,下面是iptables脚本内容。

  脚本内容

#!/bin/bash
iptables -F
iptables -F -t nat
iptables -X

iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

#load connection-tracking modules
modprobe iptable_nat
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp

iptables -A INPUT -f -m limit --limit 100/sec --limit-burst 100 -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 10 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 20/sec --limit-burst 200 -j ACCEPT

iptables -A INPUT -s 122.70.x.x -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dport 80,22 -j ACCEPT

  保存脚本文件后用

# sh iptables.sh

  执行脚本。运行脚本之后最好检查一下:

# iptables -nv -L

  脚本说明

  由于此Web服务器是置于负载均衡器后面,所以我们要允许数据源地址为负载均衡器的数据包通过:

iptables -A INPUT -s 122.70.x.x -j ACCEPT

  如果配置了Nagios等监控系统的话在这里也要加上,如果监控和LB都没做的话,这行可以不用。

  另外,我的许多基于LNMP的小网站上面也部署了此脚本,由于Web服务和MySQL数据库同时安装在一台机器上,所以没有开放3306端口。

  在本脚本中,我们配置了一些安全措施,以防止外部的ping和SYN洪水攻击,并且考虑到外部的疯狂端口扫描软件可能会影响服务器的入口带宽,所以在这里也做了限制:

iptables -A INPUT -p tcp --syn -m limit --limit 100/s --limit-burst 100 -j  ACCEPT

  上面的命令每秒钟最多允许100个新连接。请注意这里的新连接指的是state为New的数据包,在后面我们也配置了允许状态为ESTABLISHED和RELATED的数据通过;另外,100这个阀值则要根据服务器的实际情况来调整,如果是并发量不大的服务器这个数值就要调小,如果是访问量非常大且并发数不小的服务器,这个值则还需要调大。

iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s –limit-burst 10 -j ACCEPT

  这是为了防止ping洪水攻击,限制每秒的ping包不超过10个。

iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 20/sec --limit-burst 200 -j ACCEPT

  上面的命令防止各种端口扫描,将SYN及ACK SYN限制为每秒钟不超过200个,免得把数务器带宽耗尽了。

  后续加固工作

  iptables防火墙运行后,运行nmap工具进行扫描:

# nmap -P0 -sS 211.143.6.x
Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2009-03-29 16:21 CST
Interesting ports on 211.143.6.X:
Not shown: 1668 closed ports
PORT     STATE SERVICE
22/tcp   open   ssh
25/tcp   open   smtp
80/tcp   open   http
110/tcp   open   pop3
111/tcp   open   rpcbind
143/tcp   open   imap
443/tcp   open   https
465/tcp   open   smtps
587/tcp   open   submission
993/tcp   open   imaps
995/tcp   open   pop3s
1014/tcp  open   unknown

  在这里,我们发现一个1014端被某个进程打开了,用lsof -i:1014查看发现是rpc.statd打开的,这服务每次用的端口都不一样啊!本来想置之不理的,但是如果rpc.statd不能正确处理SIGPID信号,远程攻击者可利用这个漏洞关闭进程,进行拒绝服务攻击,所以还是得想办法解决掉。我们发现rpc.statd是由服务nfslock开启的,进一步查询得知它是一个可选的进程,它允许NFS客户端在服务器上对文件加锁。这个进程对应于nfslock服务,于是我们关掉了此服务:

service nfslock stop
chkconfig nfslock off

  最后想说的是,如果没有硬件防火墙保护的话,请尽量在每一台有公网IP的机器上部署iptables防火墙吧!


posted @ 2011-12-05 13:41 顺其自然EVO 阅读(207) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 352 353 354 355 356 357 358 359 360 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜