一个人不应该依附在其他人身上,一个人应该首先自力更生。你应该自己能够独立,能够安顿你自己,那你就不会害怕了。你爱你自己的话,别人不能不爱你吧。

发布新日志

  • RUP测试过程实践(转)

    2007-05-26 11:47:31

    RUP(Rational Unified Process,Ratinaol 统一过程) 是rational公司提出的一套软件开发过程,目前最新的版本是2003。RUP的最大特点就是它提供了一套完整的软件开发过程框架,任何人或组织都可以根据自己的需要来对这个过程进行裁剪,并根据自身需要进行调整后使其成为个性化的过程。读者可以参考网络上流传的《RUP2000中文版》。 ( Rational以及 Rational Unified Process 均系 Rational Software Corporation 在美国和其他国家的商标或注册商标。)

      有句老话说:万事开头难。说的是在做事情的时候,通常都是一开始觉得非常困难,但是只要上了道,入了门,就会越来越容易、越来越顺了。写文章也是如此。不过笔者这里说的开头难并不是不会写文章,而是专指不会写文章的开头部分。过去看到过的很多小说,无论是言情的或者武侠的,都会拿很长的篇幅出来作为“引子”,或者叫“楔子”,用来交待一些同小说相关的信息。而一部小说是否能够吸引读者,这部分内容也起了很大的作用。不过,笔者作为一个技术工作者,写的大多数都是技术文章,一般来说文章的内容、结构都是一早就想明白的,唯独这个开头,实在不知如何写起。不过想想也罢,既然不擅长这个,那就努力把内容写的详细、易懂一些,尽量让读者不会有上当的感觉吧。

      软件测试作为一个独立的职位或者说行业,并不是软件业的新生事物,但的确是随着最近两年一些新的思想注入国内软件行业(比如敏捷开发过程、测试驱动开发等),才得以红火起来的——这一点,从相关书籍的出版和销售就可以看得出来,从事软件测试工作的人也渐渐多了起来。但是也因为是刚刚起步,同时国内大多数软件公司都还处在中小型开发团队甚至作坊式开发的层次,不可能提供太多的测试职位,想找到一些高水平并且富有经验的测试人员更是难上加难。这最终也就导致了国内大多数测试从业者都处在“初级阶段”这样一个结果。

      笔者长期活跃在国内的几个比较知名的测试论坛,发现大家希望讨论的问题主要可以分为两种:一种是对于一些测试工作具体操作方法的提问,一种是对于测试工具使用的提问。总体看来,更多的问题集中在了后者。这似乎已经成为了国内软件业的通病,无论是开发还是测试,总希望可以通过某个工具或者语言来一劳永逸的实现某个理想。如果真的希望工具可以改变一切,那么这种愿望总是会落空的。而前者,大多是因为进入了一些刚刚开始重视软件测试的中小型软件公司,而公司的开发团队中负责软件测试的可能只有一两个对软件测试一知半解的新手,当公司需要开展某些方面的测试工作时,缺少这部分相关经验的朋友变选择了通过网络求助。

      测试工具的应用,的确可以提高工作效率,而对于测试工具方面的提问,本来也是无可厚非的,但是在笔者的实践中,如果希望提高一个团队的工作效率和改善工作效果,关注于过程和方法要远远好于关注工具。测试工具的学习、引入和使用,本身就是一个需要消耗大量资源的过程,而且对于工具的选择和引入工具时机的选择也是非常关键的,如果负责这项工作的并不是一位在软件行业沉浸多年,有着丰富测试经验并熟知开发过程的资深人士,那么开发团队将为此承担巨大的风险。即使成功的引入了测试工具,工具本身可以带来的效率的提高也不是在短期内可以体现的。在这里,笔者希望刚刚或者正在准备组建测试团队的软件公司在考虑测试流程的搭建和测试工具引入时,不要给刚刚进入测试行业的朋友太多压力,因为这两项工作都不仅仅同软件测试本身相关,同时也会涉及到项目管理、开发过程方面的内容。轻易的做出一个决定只会对将来在团队中测试工作的开展带来不利的影响。

      在这篇文章中,笔者不打算对测试工具方面的问题提出任何建议,而将对网络上大家关注的测试过程和测试方法方面给出一些具有实际参考价值的经验。

      测试工作应该什么时候开始? 测试用例是不是一定要写?如果写,应该详细到什么程度才会比较好用又容易维护? 什么样的测试用例才是好的测试用例?测试用例如何覆盖测试需求?测试需求和测试用例的关系是什么?怎么样保证测试需求的整理和测试用例的设计不会浪费太多的人力或其他资源?……

      这些问题可谓是老生常谈了,在论坛上、MSN上,或者邮件中,也经常会有朋友问到笔者一些这方面的问题。相信不管是测试新手,还是从事测试工作有一段时间的朋友,都会在工作中不得不经常的要考虑,这些问题到底有没有一个相对明确的答案呢?

      相信看到这里,已经有些朋友在想:这些问题也不是很难啊,在RUP对测试过程的描述中都已经说的很明白了啊。软件测试工作必须要通过计划测试、设计测试、实现测试、执行测试、评估测试几个阶段来完成。其中计划测试阶段需要制定测试计划、整理测试需求;设计测试阶段要设计测试用例和测试过程,要保证测试用例完全覆盖测试需求;实现测试阶段要根据测试用例实现具体的自动化脚本或者手工的操作步骤;执行测试阶段则通过自动化测试工具或人手工来执行那些自动化或手工脚本;最后的评估阶段则要对软件的质量和测试工作自身的质量做出一个客观的评价。RUP中还有详细的工作指南和文档模板呢!

      对,上面所说的这些都没有错,RUP中对于软件测试过程的描述要比笔者上面这段文字详细也生动得多。但是,我们同时也可以看到,RUP中描述到的,更多的是关注于过程的管理,或者更准确的说,RUP是在为我们提供一个大的方向,是一个稳定的、具有指导作用的框架,而不是一些具体的、涉及到操作细节的方法。这也是为什么很多朋友通读了RUP中关于软件测试的部分,但是一旦实际应用仍然找不准方向的原因。笔者今天希望同大家讨论的,则恰恰是这样一些在实践RUP测试过程时,从实际工作中总结出来的工作方法和经验。 对于测试过程方面的规范和一些基本概念, RUP中已经讲的很详细了,笔者在此也就不再赘述,有需要的读者请参照RUP中的相关部分。本文中所关注的内容包括:

      1.在计划测试时,如何确定测试工作的范围和如何整理测试需求;

      2.设计测试用例时,应该如何把握测试用例的粒度;

      3.如何平衡测试用例的可用性和可维护性;

      4.如何通过逆向的测试数据分析方法来保证测试用例的有效性和减少测试工作中资源的浪费;

      5.一个简单的但有实际意义的例子将展示如何将笔者的方法应用到测试过程中。

      这里要事先声明一下,笔者工作三年来,不管是开发还是测试,工作内容始终是围绕着信息管理系统相关业务展开的,而对于测试工作,也一直局限于在系统测试阶段通过手工方法和简单的利用一些测试工具特性进行黑盒测试。因此,在本文下面描述的内容中,难免受到客观环境和笔者个人经验的影响。也正因为如此, 笔者不保证本文中方法和观点适合于所有组织和个人的软件开发过程 。只是希望能够借此为大家提供一种思路,帮助更多人进行个性化的 RUP测试过程实践,共同提高软件测试行业的水平。 另外,本文中使用到的例子,均为笔者的一些假设,如果侵害到任何第三方组织或个人的利益,实属巧合,请通过 E-Mail通知笔者,笔者将在今后再次发布本文时做出相应的调整。

      如何确定测试工作的范围?

      对于一个存在生命周期的软件产品来说,它的开发和测试往往都不是一次性的,因为随着新的需求的出现,以及对原有版本的改进,新的版本会不断的发布(即使对于一些以客户定制方式运作的项目,在开发过程中以及发布后的维护期内,也会产生众多的内部版本)。随着版本的迭代,我们的测试工作也会一直继续下去。而在每一次迭代时,可能在整个工作阶段的开始就受到一些因素的影响,比如市场需求、既定的发布时间、并发的工作导致的资源紧张等等,使我们不得不考虑对软件质量要求的适度,最终使得我们在每个阶段的测试工作的要求或者说所涉及到的内容有可能是不同的。这种变化,最终将会影响到测试需求的确定。

      那么到底该如何确定每次迭代是测试工作的范围呢? 在笔者的实践中,通常把测试工作范围的确定,等价的认为是软件需求的确定。

      不过现在有一个很实际的问题是这样:软件需求在开发过程中不断发生变化,有时候到了后期还会有新的需求添加进来,还有些需求在交付内部测试版本之后又发现原来的需求本身就存在缺陷,之后再次返工,在软件最终发布之前,怎么可能确定的下来呢。啊,这些都是让我们的开发人员和测试人员极其头痛的事情。到底应该怎样在频繁变更的需求中确定哪些部分是我们在某个阶段要测试的内容呢?或者说通过什么样的方法可以改善我们上面提到的那些问题呢? 一个实际的做法就是实现软件需求的版本化控制 。既然说到了这里,就不免要说些题外话。笔者一直都认为软件需求是开发工作和测试工作在制定计划、开展工作时所共同参照的源头和依据,而我们只有在源头上控制好,才能保证下面工作的平稳开展。如果希望某个阶段工作的进度和内容可以明确的定义下来,就必须要考虑软件需求的版本化控制。这里所提到的“软件需求的版本化控制”,是指在一个软件产品的生命周期中,当要进行一个新版本的迭代时,要尽早的确定这个版本中将要实现的需求,并同上个版本做出比较,哪些内容是新增的,哪些内容是被调整过的。在该阶段工作开始之初的工作会议上,明确的向所有需要了解软件需求的涉众传达这部分信息。而如果在该版本的开发过程中不断的出现需求变更的情况,则应该根据市场策略、已公布的发布时间、客户需求、实现的代价、难易程度以及对现有工作的影响等方面,对需求进行适度划分,严格定义当前版本中需要实现的需求,而其他部分,则作为未来版本的软件需求进行考虑。如果有的朋友认为上面的内容还是太理论化,需要一个更实际的、可操作的方法。那么只能说,对于需求的变更,以及因为需求变更而引起的设计的变更,必须要早发现,早讨论,早决定,早调整。这可能更多的要依靠一个团队中相关负责人员的主动工作来保证,而不是依靠一个明确的方法。注意,这里的一个关键是,对于软件需求,同样需要严格按照版本进行管理,或者说使用“基线”进行管理。

      如何整理测试需求?

      一旦当前阶段测试工作的范围确定下来,我们就可以开始考虑测试需求的整理——也就是明确的定义现阶段要“测什么”。测试需求的确定将为我们制定进度时间表、分配资源以及如何确定某个阶段测试工作是否完成提供一个可供衡量的标准。当然,还有更重要的一点,已被确定的测试需求是我们进行测试用例设计和考虑测试覆盖的依据。整理测试需求的第一步,就是要“测试需求”。测试需求?对,不知道您是否想到,这里的“测试需求”中的“测试”是一个动词,指的是对软件需求本身的检查。

      啊?这不是已经超出了测试工作的范围了吗?测试人员不是应该只关心软件的实现同需求是否相符吗?这样对测试人员要求未免太高了。——这是笔者过去同一些朋友谈到测试人员必须对需求进行检查时听到的一些不同的声音。  在这里,首先要明确一个问题,就是软件测试的工作到底做什么?

      在《软件测试》( Ron Patton〔美〕,中文版由机械工业出版社出版,这本书是测试新手入门的经典教材)一书的第10页,有一个明确而简洁的定义:软件测试员的目标是找到软件缺陷,尽可能早一些,并确保其得以修复。

      瞧!这里说要“尽可能早”的“找到软件缺陷”。那这“尽可能早”要早到什么时候呢?

      不知道大家对《软件工程》这本书还有什么印象。至少在笔者看过的多个不同版本的软件工程方面的书中,对于软件缺陷都会有一段类似的描述:缺陷发现的越早,则修复这个缺陷的代价就越小,在需求、设计、编码、测试、发布等不同的阶段,发现缺陷后修复的代价都会比在前一个阶段修复的代价提高10倍(参见下图)。这样看来,上面问题的答案自然就变成了“秃子头上的虱子”:从需求阶段开始!从“测试需求”开始!

      注意,笔者这里的观点并不是说可以取消团队中的“需求评审会议”,这里并不存在冲突。笔者所希望讲述的,是测试人员应该如何看待软件需求,而并不是把“需求评审会议”所承担的责任揽到自己身上。 ?在论坛上也偶尔看到有的朋友问:如何测试需求呢?每次看到这样的提问,笔者内心就禁不住的一阵激动,因为一直以来,讨论这方面问题的朋友的确少之又少。在笔者的实际工作中,对软件需求的检查包括两个方面的内容。一是对软件需求正确性的检查,也就是要保证需求文档中所描述的内容是真实可靠的。在进行这部分工作时,不要迷信所谓的“都是用户提出的真实的需求”,因为我们必须考虑,提出这些需求的涉众,是否真的可以正确的描述自己的需求?我们的需求人员是否真的可以正确的理解用户的需求?有没有一些被用户认为在业务处理上是理所当然、极其平常的事情,而没有作为需求提出来?有没有一些被用户认为他们过去使用的软件已经提供了相应的功能,所以认为我们也应当提供,而没有提出来的?关于这个问题,也曾经有朋友提过不同的看法,认为这样对测试人员的要求太高了——既要熟悉需求人员的工作,又要熟悉软件所涉及的行业的业务。但笔者还是固执的认为,作为测试人员,还是需要对软件产品所涉及的行业的业务有一个全面的、深入的了解——当然,这不是对一个刚刚入门的测试者的要求,但是如果想称为一个优秀的测试者,是难免要付出这部分努力的。

      二是要保证软件需求的可测试性。对于“可测试性”,笔者的概念是:对于一条软件需求或者一个需要实现的特性,必须存在一个可以明确预知的结果,并且可以通过设计一个可以重复的过程来对这个明确的结果进行验证。说的具体一点,就是要保证所有的需要实现的需求都是可以用某种方法来明确的判断是否符合需求文档中的描述。如果对于某条需求或某个特性,无法通过一个明确的方法来进行验证,或者无法预知它的结果,那么就意味着这条需求的描述存在缺陷,应该请需求人员对需求文档进行修改或补充——我们有理由相信,如果作为测试人员对需求无法产生准确的理解,那么开发人员也同样无法对同一条需求产生准确的理解。对于一条确定的软件需求理解的二义性,是在不规范的开发过程中导致返工的一个主要原因。如果认为有必要,那应该在“需求评审会议”上确认所有涉众对需求的理解是一致的。 当然,对于如何提高软件需求的质量,在网络上或者已经出版的书刊中都已经有了很多更加具体、实用的方法,如果有兴趣,大家也可以找来参考。不过,如果您是一位测试者,那么上面这部分内容对您仍然是非常有用的。相信您只要在工作中进行尝试,慢慢的体会,一定会发现这种方法给您带来的好处。?现在当前的测试工作范围已经确定,相应版本的软件需求也通过了评审,我们就可以在这个已经确定的范围内进行测试需求的整理。我们手头上可以参考的东西,通常会有软件需求规约(以下简称 SRS)和用例(以下简称UC)——当然,也可能是一份包含UC的SRS。通过对SRS和UC的阅读,我们可以从文档对特性和业务流程的描述中获得对软件所涉及的业务的一个基本的认识。比如用户在处理实际业务时都要作些什么,多个业务之间的先后顺序是怎样的,用户在处理业务是对于哪些地方有特别的要求,等等。这部分规则,将成为我们的测试需求中最基本的一部分。

      至于测试需求的表现形式,笔者认为大家都可以根据自己的需要进行设计,而没有必要把思路限制在到底使用表格方式还是使用文本方式,只要把握一个原则就行了:在一条测试需求中,用容易理解的自然语言,明确的描述一项需要测试的内容。对于多项测试内容,应尽可能的剥离开来,保证一条测试需求只包含一项测试内容。

      另外,大家也可能注意到了,在软件开发过程的这个阶段,通常是没有用户界面(以下简称UI)可供参考的——虽然RUP中对于需求阶段的工作描述包括了UI设计的部分,但很多时候在这个阶段还是无法提供一个确定的UI的——也就是说我们这时获得的测试需求,将是完全基于业务的,而并不包括基于UI的那部分规则,是同软件的最终具体实现相独立的。

      随着开发工作的继续,开发部门的架构设计文档和详细设计文档也将陆续提交,这时候,我们可以根据设计文档来对已有的测试需求进行增补。注意,这里我们对于设计文档中提到的内容要有选择的采用,只有同SRS或UC中已经定义的部分相符的内容,才可以用来调整我们的测试需求。而同软件需求不相符的部分,则需要同设计人员和需求人员一起讨论,确定下以哪一方作为基准,决定是否需要调整软件需求,然后对测试需求进行相应的增补或者调整。比如对于一些算法,需要考虑设计文档中定义的,同系统实现相关的那些计算公式,是否同软件需求中描述的算法表达的是否是同一个意思?而对于一些约束或者业务规则,设计文档中描述的是否同需求中的相应部分一致? 呵呵,看完上面这部分内容,恐怕又有一部分朋友晕倒在地了,而没有晕倒的那部分朋友 也要提出异议:啊?!你这不是又包含了对开发人员所作的设计工作的检查吗?!刚刚让我们检查需求,现在又让我们检查设计,真的把我们当成全才了!没办法,为了让软件交到我们手上的时候只包含尽量少的缺陷,大家只能再辛苦一下了。我们的工作不应当仅仅限制在软件交付后尽力找到存在的缺陷,而更应该努力及早发现软件缺陷出现的苗头,尽量预防缺陷的出现。虽然并不是说在所有的团队中都应该由测试人员承担“测试需求”和“测试设计”的工作,但是测试人员对这些工作起到的作用,是其他团队中的其他角色所无法替代的。开发部门完成编码实现工作,提交供内部测试的应用程序时,测试人员手头上应该已经准备好了绝大部分测试用例和测试数据,测试部门将开始执行测试。通常在我们执行测试的过程中,即使我们已经从“通过测试”和“失败测试”两个不同的角度准备了非常充分的测试用例和测试数据,但总是有些缺陷的出现是出乎我们意料的,或者说是已有的测试需求和测试用例未能覆盖的。那么,对于这部分缺陷,也应当添加到测试需求中,并设计相应的测试用例,以便于下次版本迭代时进行参考。 OK,相信说到这里,各位看客也应该可以理解我的观点了:对于一个长期发展的团队或者持续开发的产品,它的所有东西都是要不断积累的、不断迭代的。无论对于软件需求还是测试需求,不仅仅是在一个版本的开发过程中,在不同的阶段进行迭代,在产品的整个生命周期中的不同版本间,也是不断迭代和积累的。

      关于测试用例

      什么时候开始设计测试用例?测试用例该怎么写?什么时候算是完成了测试用例的设计工作??上面几条可以算是网络上测试用例设计方面最热的问题,而且每隔一段时间就会被不同的人重新提起。提问的有刚刚进入测试行业的朋友,也有工作一段时间后重新陷入迷茫的“老手”。这几个问题看似简单,可是要想回答的让大家都感到满意,还真是不容易。这样的高难度,笔者也不敢有太多的奢望,还是把自己的经验写出来,希望对大家有些参考价值吧。 测试用例 是为特定目标开发的测试输入、执行条件和预期结果的集合。这些特定目标可以是:验证一个特定的程序路径或核实是否符合特定需求。——这是 RUP中关于测试用例的定义。而在实际工作中,对于测试用例的设计和选择,是考察一个测试人员工作能力和经验的最好方法。 如果您像笔者前面说的那样,已经在工作中开展了测试需求的整理工作,那么测试用例的设计工作就会变成一件自然而然的事情了。如果您在需求阶段就开始了对测试需求的整理,那么当这部分测试需求整理完后,就可以开始相应测试用例的设计了。而随着开发工作的继续,在测试需求被不断的增补、调整后,也应该添加或修改相应的测试用例,以保证测试用例的有效性。这里笔者要特别强调一点:测试用例的完成并非是一劳永逸的,因为测试用例是来源于测试需求,而测试需求的来源包括了软件需求、系统设计、详细设计,甚至包括了软件发布后,在软件产品生命周期结束前发现的所有软件缺陷。来源的多元化注定了测试需求是非常容易发生变化的。一旦测试需求发生变化,则测试用例必须重新维护。如果您对于软件开发的迭代方法比较熟悉,那么就可以对测试用例的设计采用同样的方法。而最终的结果,是您的团队将逐渐拥有越来越全面细致的测试需求和测试用例库,测试人员越来越多的精力,可以放到对测试过程的考虑和测试用例的选择方面。至少在笔者的实践中,这种方法虽然前期需要相对大量的投入,但随着时间的迁移,在没有使用自动化测试工具的情况下,同样大大提高了每个测试人员单位时间内测试工作的效率。关于设计测试用例的方法,无论是在已经出版的专业测试书籍还是网络上的专业测试论坛中,都已经有了很多非常好的文章来专门讲解,笔者也不打算占用太多篇幅重新引用,大家如果有这方面需要,通过网络都可以很容易的找到这些资料。在这里,笔者只是想简单的评论一下很多初学者对这些方法容易产生的误解。相信对于任何一个测试人员来说,等价类划分法和边界分析法都是最早接触,也是最基本、最容易使用的测试用例设计方法。很多朋友也都知道先使用等价类划分法划分出等价类,然后使用边界分析法确定测试需要的边界值。但是很多朋友也提到,在工作了一段时间后,发现这两中方法所能应用的地方越来越少,难道这两种方法真的只能应用在检查编辑框输入类型和输入长度的时候吗?当然不是。对于一些刚刚接触测试工作的朋友提出的这个问题,笔者认为现在市面上的很多测试书籍都要承担很大的责任。比如很多书中,在讲到测试用例设计时,都不约而同的使用同一个例子—— Windows计算器程序。通常是告诉你对于计算器有一个允许的输入范围(比如允许输入一个大于0小于等于100的整数),然后要求设计相应的包含合法数据和不合法数据的测试用例。当然,仅仅是这样一条简单的描述,我们已经可以设计出很多测试用例和测试数据了,比如对于输入范围的考虑,对于输入数据类型的考虑,对于输入长度的考虑等等。但是在我们的实际工作中,很多时候看到的并不是这样过于简单的软件需求描述,很多时候这些内容都是隐含在一些算法或业务规则中的。 我们现在举个例子来看一下: “双倍余额递减法是在不考虑固定资产残值的情况下,以平均年限法折旧率(不扣残值)的两倍作为折旧率,乘以每期期初固定资产折余价值求得每期折旧额的一种快速折旧的方法。
        年折旧率=2÷预计使用年限×100%
        月折旧率=年折旧率÷12
        月折旧额=期初固定资产账面净值×月折旧率
      为了保证固定资产使用年限终了时账面净值与预计净残值相等,在该固定资产折旧年限到期的前两年,将固定资产净值扣除预计净残值后的余额平均摊销。” 上面的内容是我国现行财务制度中关于固定资产折旧的一种方法——双倍余额递减法——的具体算法,大家可以在任何一本会计书中找到这部分内容以及一些相应的例子,不过我们这里并不关心固定资产的折旧到底是怎么一回事。笔者想知道的是大家在看完上面的描述后是否已经发现,我们在设计测试用例时,对于准备进行折旧的固定资产,至少应该包括预计折旧年限小于两年、等于两年和大于两年三种不同的类型。这也应该算是一个等价类划分法和边界分析法的应用吧。实际上,制约我们更好的使用这些测试方法来进行测试用例设计的,并不是方法的应用范围不够宽广,而是因为如果我们不能对这些同实际业务相关的具体算法或业务规则进行深入的分析,就不可能挖掘出深层的测试需求,那么这两种方法的应用也就很有限了。这也是笔者在前面一再强调加深对软件需求了解的原因。对于网络上也有讨论的另外两种方法——错误推测法和因果图法,则分别因为可靠性较差和操作相对复杂而并没有得到广泛的应用。

      如何划分测试用例的粒度?

      我们是不太可能在一个测试用例包含所有测试需求的,因为众多的功能以及不同的路径组合将使这样一个测试用例像巨无霸一般,完全不具有可操作性。——除非您的软件所包含的功能真的又少又简单,不过如果真的有这么一个软件,恐怕也没有测试和发布的必要了。

      当然,这也并不是要您走向另一个极端,为需求中定义的每个特性或功能都提供一个甚至多个测试用例。这里的关键,是要寻找一个合适的度。 笔者推荐的方法是:关注有效功能。

      有效功能:就是指在被测应用所涉及的实际业务中,当用户在手工状态下进行工作时,整个业务流程中对用户来说,具有实际意义那些功能。这个功能的特征是当我们把这个功能单独从计算机软件还原到用户的原始手工状态时,它的完成可以作为用户实际业务的一个阶段性结束的标志,而不是一旦从这个业务流程中独立出来就失去了意义。而该业务完成后,可以为其他用户或业务提供所需要的信息。

      这里区分“有效功能”的关键有如下两个:

      1. 这个功能是可以还原到用户原始的手工业务流程中去的。我们的计算机和软件,都是为了帮助用户解决手工业务中一些烦琐和低效的问题,而提出的一些忠实于原始工作方法或略有变通的解决方案,并不是要改变用户全部的业务流程。所以,应该从用户实际业务的角度来判断功能是否有效。

      2. 这个功能是否可以标志着用户实际业务的一个阶段性结束?并且这项业务完成之后,被完成的业务实体是否可以交付给其他用户或业务以供完成下面的工作? 为了方便理解,我们可以先看一下下面的例子。拿我们常见的财务软件来说,当添加一张会计凭证时,通常是需要填写会计科目,在使用计算机完成工作时,我们可以利用软件的功能,从很多备选科目中选择一个自己需要的科目,或者通过科目代码来输入科目。这项功能很有可能会作为一个特性要求出现在软件需求规格说明书中,那么这个科目的选择或输入是不是一个有效功能呢?让我们试着用上面规则来衡量一下。首先,这个功能在用户手工业务处理过程中是存在的,不同的是这项功能是在用户填写凭证时,在自己的大脑中完成的——用户会根据需要,在自己记忆的科目中选择合适的填写上去,这项功能节省了用户在记忆大量会计科目时付出的额外劳动。我们可以认为这个功能是为用户原来的工作提供了一种简便的、变通的方法。那么这项功能的完成对于用户来说意味着什么呢?我们从上面的描述中可以看到,用户希望软件提供的是可以添加一张完整的凭证这样的功能,而不仅仅是方便填写会计科目。填写会计科目只是用户在添加凭证时的一个步骤,单独把这个功能提取出来对用户来说没有任何实际意义。对于业务流程下游的用户,需要的也不仅仅只是一个会计科目的信息,而是一张包含了会计科目以及其他会计信息的完整的会计凭证,否则就无法进行下面的工作。这样看来,这个功能并不是一个有效的功能,我们可以把它最为需要测试的特性在测试需求中进行描述,却不应该作为一个单独的测试用例出现在我们的测试用例集中。而我们在测试用例中真正关注的,应该是添加会计凭证这个具有实际意义的功能。另外,我们还需要关注如何将多个相互之间存在依赖关系的功能区分为单个的有效功能。例如,现在有 A、B、C三个功能,其中B功能的开始必须依赖于A功能的完成,而且A功能如果出现不同的完成状态,B功能也会做出不同的反应;C功能对B功能的依赖也是如此。那么这时候,我们是否应当将三个相互依赖的功能包含在一个测试用例中呢?这样的做法也不是不可以,但是我们也可以先判断一下,这三个功能是否都是有效功能(您可以使用前面提到的方法来试着评判一下)?如果A、B、C都是独立的有效功能,那么我们可以从上面的描述中发现,它们之间存在的依赖性,可以理解为是一种状态或者说数据的依赖性。后一个功能关心的,是前一个功能最终提供给它的是什么样的“输入”,而不是前一个功能到底作了些什么。这样看来,我们完全可以将它们分别包含在几个独立的测试用例中,而在每个测试用例的开始,把不同的输入作为不同前置条件来描述。

      测试用例是否应该包含所有的细节?

      这是在网络上听到诉苦最多的又一个热点问题:公司要求按照一个严格的规范来开展测试工作,必须书写所有的测试用例文档,要求文档的书写一定要具体,并在执行测试时要参考测试用例文档来进行。如果测试用例文档写的过于简略,则会被领导斥为偷懒。但是,如果文档中的对操作步骤描述的过于具体,像下面这样:

      01.  在“用户名”项中输入“user”;

      02.  在“密码”项中输入“password”;

      03.  点击“确定”按钮。 这样的描述方式表面看起来可操作性似乎是增强了,任何人拿到这个文档都可以充当测试人员,检查一下这个功能是否存在缺陷。但是我们不要忘记,在开发过程中,变更的存在是必然的。一旦需求、设计或者应用程序中的某些细节发生了变化,比如“用户名”变成了“操作员”,“密码”变成了“口令”,“确定”变成了“登录”,或者输入项所接受的数据类型发生了变化,那么同这部分内容相关的所有的测试用例都需要修改。否则,我们凭什么可以保证这些描述不同的测试用例说的是同一样东西?如果我们只有这么一个测试用例,也许一切都不是问题,但是对于一个业务复杂、功能完整的系统,如果按照这样的方法描述测试用例,最终要么产生大量的测试用例文档,要么产生过长的单个文档。无论是那一种,如果发生了类似于上面说的变化,维护文档都将变成一次地狱式的体验。这也是为什么在网络上频频出现的这个问题,而且每次出现都会受到测试同行们的关注的原因。那么这个问题应该任何解决呢?测试用例是不是把所有的流程写出来就可以了呢?如何在减少测试用例文档中包含过多琐碎的细节的同时保证测试用例的可操作性呢?又有什么方法可以提高我们维护测试用例文档的效率呢?笔者的建议是:关注“测试思想”而不是关注操作步骤。要理解这个问题,首先要弄明白测试用例的作用。就像用例一样,测试用例并不是用来描述具体的实现的,而是着重描述处理问题的思路——对于一项明确的测试内容进行测试的思路。作为测试用例的设计人员,如何理解基本流和备选流?如何深入分析并找到所有需要覆盖的路径和需要检查的特性?我们在测试用例中应该用容易理解的自然语言清晰的来描述我们将要如何进行测试,而不是简单的把在应用程序上如何操作的烦琐的步骤记录下来。把测试用例设计当成填写具体操作步骤的表格是人们对测试用例最大的误解。传统的测试用例文档编写有两种方式。一种是填写操作步骤列表:将在软件上进行的操作步骤一步一步详细的记录下来,包括所有被操作的项目和相应的值。另一种是填写测试矩阵:将被操作项作为矩阵中的一个字段,而矩阵中的一条条记录,则是这些字段的值。网络上对于这两种方式孰优孰劣的争论,将大家错误的引导向了两个极端:要么采用 A,要么采用B。而大家却忽视了一点,对于工作方法的争论,本质上同工具的争论并不是一回事(例如曾经的VC、BCB之挣)。如果不同的方法各有优势,我们完全可以通过变通的方法,把优势的部分组合在一起来使用。 操作步骤列表的优势在于对基本流和备选流进行分析后,它可以清晰的描述您的测试思路。而测试矩阵则更适合于用来存放测试数据,特别是那些需要人工赋予一个确定的值的特性。下面,我们来看一个例子,当然,这个例子同样是杜撰的。?需求名称:用户登录安全验证需求描述:用户登录安全验证是为了保证所有登录到系统中的用户,都是由系统管理员预先在系统中设定的。使用系统中不存在的用户名,或者用户名输入正确,但密码输入错误情况,都无法登录到系统中。当用户使用了不存在的用户名或错误的密码时,系统应分别给出适当的提示。如果用户连续三次无法使用正确的用户名和密码登录到系统,则系统应给出适当的提示,并退出当前程序。如果用户使用正确的用户名和密码登录到系统,则退出界面,转到系统主界面。对于用户登录界面和程序主界面,请参考相应的 UI设计文档。

      测试需求:

      01. 检查能否使用正确的用户名和密码登录到系统;

      02. 检查能否使用错误的用户名或密码登录到系统;

      03. 检查使用错误的用户名和密码登录失败超过三次,是否会自动退出当前程序。

      测试用例:

    序号 操作过程描述
    1 输入用户名。
    2 输入密码。
    3 确认登录。

    序号 用户名 密码 预期结果
    1 正确的用户名 正确的密码 登录到系统并转到系统主界面
    2 正确的用户名 错误的密码 无法登录到系统并提示密码错误
    3 错误的用户名 正确的密码 无法登录到系统并提示用户名错误
    4 错误的用户名 错误的密码 无法登录到系统并退出当前程序
    5 空用户名 …… ……

      这个例子并不是按照 RUP提供的标准模板编写的,它的目的只是要为大家展示,用前面所讲的方法,整理出来的测试需求和设计完成的测试用例到底是个什么样子。所以省略了很多细节,不过大家在实际编写测试用例文档的时候,可以根据自己的需要把相应的内容添加上去。同时,也可以在用户名和密码两个字段中填写准备使用的具体数据。 相信大家已经看到,在我们的例子中,测试需求同测试用例之间并非是一一对应的关系因为一条测试需求未必是明确的对应到一个有效功能的(其实测试需求本身同软件需求和用例之间也未必是一一对应的)。而我们的测试用例所关注的,应该是一个有效功能。不过您不用担心,这种情况并不会增加您管理测试需求和测试用例的成本,现在市面上提供的测试工具中已经有些是专门用来维护软件需求、测试需求同测试用例之间的关系的,并且它们提供的强大的视图功能还可以让您很容易的查看到测试用例对测试需求的覆盖情况。对于例子中的测试用例文档,已经被分成了两个部分,一部分是描述了测试用例执行者所应遵循的操作过程,一部分则是在操作中需要使用到的测试数据。这样做的原因是在我们的实际工作中,尤其是在进行功能测试时,很多时候都是使用雷同的操作过程和不同的测试数据来进行的。而使用上面的方法,可以不用再对原本在多个用例中重复出现的操作过程再次描述,而可以把更多的精力放到测试数据的设计和准备上。这样作带来的副产品,就是提高了测试用例的可维护性。怎么?还有人对笔者的观点持怀疑态度?那好吧,那么我们来尝试着证明一下。我们的邮递员要在 5个城市内奔波,并且每个城市都有些邮件需要投递,他需要找到可以一次走遍5个城市的所有路线。这听起来似乎并不是太复杂,利用我们已有的数学知识,很容易就可以得到答案。但是对于我们要测试的内容,通常都会包含更多复杂的规则。 例如,我们有三个文本框,每个文本框每次都只能输入一个英文大写字母,允许输入的值只包括: A、B、C三个字母,当三个文本框输入不同的值的时候,我们不知道会发生什么,也不知道它们之间是否会互相影响,所以需要您来设计可以覆盖所有输入情况的测试用例来测试它。 瞧,这很简单不是吗?如果我们希望每个测试用例在执行时一旦出现缺陷都可以很快的找到导致缺陷的原因,那么最好的办法就是每个测试用例只包括一个同其他测试用例不同的输入值。那么可供我们输入的值都有哪些呢?嗯,对于每个文本框,都至少有 A、B、C三种已经声明的不同的值,另外,我们还要考虑当文本框为空、输入空格、输入非英文字符以及输入A、B、C之外的英文字符的情况。那么按照上面的方法,我们会有多少测试用例呢?答案是343个。这只是一个很简单的例子,我们工作中遇到的软件的业务规则和特性决不会比这少的,那会有多少个测试用例呢?God knows. 不过至少有一点可以肯定,我们无法在原有业务规则发生变化时高效的、无差错的维护完343个测试用例。 但是如果使用我们前面所描述的方法,对于操作过程的改变,您只需要重新维护一次,而对测试数据的维护,也同样是非常简单的,而且并不会因为连续大量修改时出现的错误导致测试用例本身出现歧意。?在将主要精力从“设计”操作步骤转移到设计测试数据之后,我们还将从这种方法中获得更大的益处——通过“逆向测试数据分析”来提高测试工作的整体效率。这种“逆向测试数据分析”的方法,是假设软件中存在多个互相依赖的功能,而且这些功能中包含在“依赖链”最末端,并且不再被其他功能依赖的功能。在我们准备测试数据时,首先从这个“依赖链”最末端的功能开始,分析这个功能会对不同的输入产生哪些不同的结果。然后将所有的输入进行整理,分清哪些输入是来源于其前一个功能的输出。之后,对该功能的上一个功能进行同样的分析,整理出所有的输入和输出,但是这个功能的输出至少应该包含“依赖链”最末端功能接收到的全部输入。继续按照这样的思路循环向上,直到到达“依赖链”开始端的功能。不知道您在工作中有没有遇到这样的情况:在对那些“依赖链”上的功能进行测试时,一开始并没有严格的规范测试数据的使用,结果前一个功能测试时产生的数据根本无法在下面的工作中被很好的利用起来,反而因为大量无效数据增加了后面功能的测试难度。最终不得不对每一个功能重新准备测试数据。大量的时间,浪费在了这些重复而低效的劳动上。?当然,如果希望可以进一步提高某个阶段测试工作的效率,还可以考虑应用“设计测试过程”的方法。这里所说的测试过程,指的是我们在执行测试时所设定的执行测试用例的先后顺序。之所以这样作,是因为可以充分的利用不同功能之间的耦合性,尽量通过一次操作来检查尽量多的内容,从而降低已完成工作的无效性或低效性,最终提高某个阶段的整体工作效率。不过,这项工作同样要求操作者必须对被测的系统所涉及的所有业务以及这些业务之间的关系都非常熟悉才行。?如果您正被测试工作的低效问题所困扰,那么建议您尝试一下上面的方法,希望会对您的工作有所帮助。

      如何评价测试用例的好坏?

      这部分内容的出现,完全是因为不久前同几个朋友的一次讨论。当时大家都认为对于一个测试用例好坏的评价,无外乎两个标准:是否可以发现尚未发现的软件缺陷?是否可以覆盖全部的测试需求?但是后来发现这两个标准对于一些问题是处理不了的。例如,对于一个质量非常好的软件产品,存在的软件缺陷异乎寻常的少,测试用例设计人员准备了大量的测试用例,已经完全覆盖了测试需求,但是只有很少一部分测试用例在执行时发现了缺陷,而其他用例都顺利通过了。那么是否就可以认为顺利通过的那部分测试用例不好呢?对于这个问题,笔者认为不管是测试用例是否可以发现尚未发现的缺陷,还是测试用例对测试需求的覆盖度,都是用来评估测试设计人员工作能力和经验的标准,而对于如何评价测试用例的优劣,应该还有其他标准。当然,在不同的团队中可能存在不同的标准,但下面两条应该是适合于任何团队的。 1.易用性。对于一个即熟悉测试工作,又熟悉被测应用的测试人员,应当可以花费 很少的时间就可以理解测试用例中表达的测试思路,并可以很快的执行完这个测试用例。 2.易维护性。当开发过程中的某些因素影响了测试需求,测试用例的作者或其他测试设 计人员,应该可以花费很少的时间就完成定位并维护所有相关测试用例的工作。

      一些题外话

      曾经有朋友问:如果测试用例同软件的具体实现互相独立,怎么保证测试用例的可操作性呢?怎么保证任何一个人都可以一拿到测试用例就可以直接上机执行测试呢?笔者的回答是:尽量不要让这种事情发生。首先,笔者一直不赞同那种让“任何人”都可以充当测试人员,按照手中测试用例执行测试的做法。因为对于被测应用的全面了解和熟悉,是作为一个测试人员最基本的要求——在前面的文字中对于软件需求的熟悉也多次被强调。我们无法预知让一个对软件以及软件所涉及的实际业务不够熟悉的人,依靠一份他同样不熟悉的操作步骤列表来执行测试会有什么样的结果。但是有一点可以明确,这就好像让一个没有医学背景的人,仅仅依靠一本七年制本硕连读的《内科学》教材来为患者检查是否患有心脏病,最终结果是患者承担了全部的风险。其次,测试用例的本来目的是为了描述我们的“测试思想”——也就是“怎样测”,而是否可以熟练的操作被测应用,并不是在测试用例这个“对象”中所要考虑和保证的,应当剥离出来,作为独立的部分进行处理。而问题的关键,在于如何保证拿到测试用例的人有足够的能力和经验来执行测试,这完全可以通过公司内部对软件及软件所涉及的实际业务的培训,或者软件的操作手册。总之,还是尽量不要随意的加入“任何人”到测试工作中吧。

    原文

     

  • 今天不舒服还要坚持上班

    2007-05-26 10:35:46

    胃不舒服,有点坠坠的。。。全身乏力。。。头轻飘飘的。。。拉肚子,把昨晚吃的都拉了。。。

    好想休息。。。

  • 狗原来是吃屎的

    2007-05-25 16:57:18

    是屎巴巴而且还是人屎。。。
  • 测试用例示例(转)

    2007-05-25 11:37:27

    测试用例示例(二)

    一个好的测试用例,应该包含以下信息:

    1 软件或项目的名称

    2 软件或项目的版本(内部版本号)

    3 功能模块名

    4 测试用例的简单描述,即该用例执行的目的或方法

    5 测试用例的参考信息(便于跟踪和参考)

    6 本测试用例与其他测试用例间的依赖关系

    7 本用例的前置条件,即执行本用例必须要满足的条件,如对数据库的访问权限

    8 用例的编号(ID),如可以是 软件名称简写-功能块简写-NO.

    9 步骤号、操作步骤描述、测试数据描述

    10)预期结果(这是最重要的)和实际结果(如果有BUG管理工具,这条可以省略)

    11)开发人员(必须有)和测试人员(可有可无)

    12)测试执行日期

    一个测试用例的范例

    项目/软件

    技术出口合同网络申领系统 (企业端)

    程序版本

    1.0.25

     

     

     

    功能模块名

    Login

    编制人  

    xxx

     

     

     

    用例编号-

    TC-TEP_Login_1

    编制时间  

    2002.10.12

     

     

     

    相关的用例

     

     

     

     

     

    功能特性

    用户身份验证

     

     

     

     

     

    测试目的

    验证是否输入合法的信息,允许合法登陆,阻止非法登陆

     

     

     

     

     

    预置条件

    特殊规程说明

    如数据库访问权限

     

     

     

    参考信息

    需求说明中关于登陆的说明

     

     

     

     

     

    测试数据

    用户名=yiyh 密码=1

    操作步骤

    操作描述

    期望结果

    实际结果

    实际结果

    测试状态

    1

    输入用户名称,按登陆按钮。

    用户名=yiyh,密码为空

    显示警告信息请输入用户名和密码!

     

     

     

    查看(1583) 评论(0) 收藏 分享 管理

  • :(

    2007-05-25 10:22:09

    见心情。。。

  • 故事

    2007-05-25 08:40:36

    有一间庙,上面有一尊花岗石雕成的佛,有很多人参拜。

    通往佛像,要经过很多石级,也是花岗石做成的。

    经过几十年,石级的花岗石深深不忿说:‘为什么我们要被人踩着去参拜你?’

    佛说:‘你不过被割四刀,而我经过千刀万剐,才成为佛的开关。

     

  • 疯狂喜欢Jolin ^o^

    2007-05-24 22:11:38

    没有表情一个人坐著等著一个安慰的理由但你没有

    她不是始作俑者缺席的你罪恶的问候
    用沉默代替解脱迷失在你的话语
    用微笑告别以后这一刻后彼此要擦身而过
    放下一切让你走就这样不再联络

    想起你电话来时的表情想起从前爱你的声音
    想起总是微微笑的你想起从前爱你的调皮

    想起如果没有遇见你想起从前爱你的甜言蜜语
    面对著自己背对离去的你我已失去

    她不是始作俑者缺席的你罪恶的问候
    用沉默代替解脱迷失在你的话语
    用微笑告别以后这一刻后彼此要擦身而过
    放下一切让你走就这样不再联络

    想起你电话来时的表情想起从前爱你的声音
    想起总是微微笑的你想起从前爱你的调皮
    想起如果没有遇见你想起从前爱你的甜言蜜语
    面对著自己背对离去的你我已失去

    多年后时间不再紧凑你我的以后也不再拼凑
    爱情始作俑者不是谁没有谁错又或谁对不再害怕面对
    想起你电话来时的表情想起从前爱你的声音
    想起总是微微笑的你想起从前爱你的调皮
    想起如果没有遇见你想起从前爱你的甜言蜜语
    面对著自己背对离去的你我已失去
    面对著自己背对离去的你选择放弃

     

  • Installing Bugzilla on Microsoft Windows

    2007-05-24 15:54:14

    Original author: Byron Jones

    Translation: es

    Bugzilla version 2.18 was the first release that runs unmodified on Windows. This document guides you step by step through the installation process.

    Note that there are a few things that don't work on Windows. The most important one of these would be the inbound email interface (contrib/README.Mailif).

    Bugzilla

    There's two main methods to getting the Bugzilla source - from CVS or in a tarball. The best method for fetching Bugzilla is to grab it directly from CVS, as this will allow for simple upgrades, even if you have customised Bugzilla.

    Read the Release Notes before you do anything.

    Installing Bugzilla From CVS

    Download the CVSNT client from http://www.cvsnt.org/ (2.15 Meg).

    Run the installation, you'll only need to install the Command line client and the Password Server (:pserver:) Protocol. Once the intsall has completed, log out and log in again to pick up the changes to the PATH.

    Note: this document assumes you want to install Bugzilla into C:\Bugzilla.

    Open the command line, and cd to the parent of the directory you want to install Bugzilla into. As we'll be installing Bugzilla into C:\Bugzilla, the current directory must be C:\.

    C:\>set CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
    
    C:\>cvs login
    
    Logging in to :pserver:anonymous@cvs-mirror.mozilla.org:2401:/cvsroot
    CVS password: anonymous
    
    C:\>cvs checkout -d Bugzilla -rBugzilla_Stable Bugzilla
    cvs checkout: cwd=C:\ ,current=C:\
    cvs checkout: Updating Bugzilla
    U Bugzilla/.cvsignore
    U Bugzilla/1x1.gif
    U Bugzilla/Bugzilla.pm
    U Bugzilla/CGI.pl
    ...
    U Bugzilla/template/en/default/whine/multipart-mime.txt.tmpl
    U Bugzilla/template/en/default/whine/schedule.html.tmpl
    cvs checkout: Updating Bugzilla/template/en/extension
    U Bugzilla/template/en/extension/filterexceptions.pl
    cvs checkout: Updating Bugzilla/template/en/extension/hook
    
    C:\>
    

    Upgrading From CVS

    If you've already installed an earlier version of Bugzilla from CVS or from a TarBall, updating is easy. Even if you've made customisations, CVS is smart enough to merge. If CVS needs help merging, it displays a C in the first column of its report. You need to resolve such conflicts manually.

    C:\Bugzilla>cvs update -R -d -rBugzilla_Stable
    cvs update: Updating .
    P editusers.cgi
    cvs update: Updating Bugzilla
    P Bugzilla/Bug.pm
    P Bugzilla/BugMail.pm
    P Bugzilla/Chart.pm
    P Bugzilla/Flag.pm
    P Bugzilla/User.pm
    P Bugzilla/Util.pm
    cvs update: Updating Bugzilla/Auth
    U Bugzilla/Auth/CGI.pm
    cvs update: Updating Bugzilla/Template
    cvs update: Updating Bugzilla/Template/Plugin
    ...
    cvs update: Updating template/en/default/search
    cvs update: Updating template/en/default/whine
    cvs update: Updating template/en/extension
    
    C:\Bugzilla>
    

    Installing Bugzilla From the TarBall

    Download the Bugzilla from:
    http://bugzilla.org/download.html (1.2 Meg).

    Bugzilla ships as a Tarball, which has the extension .tar.gz. Any decent Windows archive tool should be able to extract tarballs.

    Extract the archive to the directory of your choice. For the remainder of this document I will assume that you have extracted Bugzilla into C:\Bugzilla.

    Upgrading From TarBall

    If you installed Bugzilla from the TarBall, the simplest way to upgrade is to follow the CVS Upgrading instructions.

    MySQL

    Download MySQL

    Download the MySQL "Windows Essentials" installer from:
    http://dev.mysql.com/downloads/mysql/ (15.9 Meg).

    Install

    MySQL has a standard Windows installer. It's ok to select a Typical MySQL install (the default). For the remainder of this document I will assume you have installed MySQL into C:\mysql.

    Create Bugs Database and User

    Use the mysql command line utility to create the Bugzilla database and a MySQL account for Bugzilla.

    Note in the following example 'sockmonkey' is my password for the bugs account:

    C:\mysql\bin>mysql --user=root -p mysql
    Enter password: ********
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 15 to server version: 4.0.20a-debug
    
    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
    
    mysql> create database bugs;
    
    Query OK, 1 row affected (0.11 sec)
    
    mysql> grant all privileges on bugs.* to 'bugs'@'localhost' identified by 'sockmonkey';
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> flush privileges;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> quit
    
    Bye
    
    C:\mysql\bin>
    

    If you are running MySQL 4.1 or higher, you may encounter the Client does not support authentication protocol requested by server error message. To fix this, once the user has been created you will have to reset the password using OLD_PASSWORD:

    C:\mysql\bin>mysql --user=root -p mysql
    Enter password: ********
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 15 to server version: 4.1.11-nt
    
    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
    
    mysql> set password for 'bugs'@'localhost' = OLD_PASSWORD('sockmonkey');
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> quit
    
    Bye
    
    C:\mysql\bin>
    

    ActiveState Perl

    Download ActiveState Perl 5.8.1 or Higher

    Download the ActiveState Perl 5.8.1 or Higher MSI from:
    http://activestate.com/Products/Download/Download.plex?id=ActivePerl (12.5 Meg).

    Note that Bugzilla requires ActiveState Perl 5.8.1 as it needs CGI.pm version 2.93 or higher. 5.8.0 ships with CGI.pm version 2.81, 5.8.1 ships with CGI.pm version 3.00.

    There is a bug in Time::Local 1.10, which is shipped with ActiveState Perl 5.8.6, that will cause warnings to be generated at the top of every buglist. It's a good idea to avoid version 5.8.6 (version 5.8.4 works without issue).

    Install

    ActiveState Perl uses a standard Windows Installer. Install, sticking with the defaults, which will install Perl into C:\Perl.

    Note: Installing Perl into a directory that contains a space (eg "C:\Program Files") will break the Template-Toolkit installer.

    Once the intsall has completed, log out and log in again to pick up the changes to the PATH.

    Upgrading Existing Installs

    If you already have ActiveState Perl installed, now's a good time to ensure you're running the latest version of ActiveState Perl, along with the latest versions of the modules.

    To upgrade ActiveState Perl, follow the directions at:
    http://aspn.activestate.com/ASPN/docs/ActivePerl/install.html

    To upgrade your modules, simply run ppm upgrade

    Create Temp Directory

    On Windows, Perl has a hard time of locating the correct directory to write its temporary files (CGI.pm, File::Spec). Basically it has a list of paths hard coded to use, instead of querying Windows for the correct path.

    To avoid problems, create the C:\Temp directory (it has to be on drive C) and ensure SYSTEM has write and modify access.

    Install Modules

    Bugzilla requires a number of perl modules to be installed, all of which are available at http://landfill.bugzilla.org/ppm/.

    If you use a proxy server or a firewall you may have trouble running PPM. This is covered in the ActivePerl FAQ.

    The Net::LDAP module is only required if you want to use Active Directory for authentication.

    C:\>ppm
    
    PPM - Programmer's Package Manager version 3.1.
    Copyright (c) 2001 ActiveState Corp. All Rights Reserved.
    ActiveState is a devision of Sophos.
    
    Entering interactive shell. Using Term::ReadLine::Stub as readline library.
    
    Type 'help' to get started.
    
    ppm> rep add Bugzilla http://landfill.bugzilla.org/ppm
    Repositories:
    [1] ActiveState PPM2 Repository
    [2] ActiveState Package Repository
    [3] Bugzilla
    ppm> install AppConfig
    ====================
    Install 'AppConfig' version 1.52 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 50508 bytes.
    ...
    Successfully installed AppConfig version 1.52 in ActivePerl 5.8.7.813.
    ppm> install TimeDate
    ====================
    Install 'TimeDate' version 1.16 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 19235 bytes.
    ...
    Successfully installed TimeDate version 1.16 in ActivePerl 5.8.7.813.
    ppm> install DBI
    ====================
    Install 'DBI' version 1.43 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 508164 bytes.
    ...
    Successfully installed DBI version 1.43 in ActivePerl 5.8.7.813.
    ppm> install DBD-mysql
    
    ====================
    Install 'DBD-mysql' version 2.9002 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 178803 bytes.
    ...
    Successfully installed DBD-mysql version 2.9002 in ActivePerl 5.8.7.813.
    ppm> install Template-Toolkit
    ====================
    Install 'Template-Toolkit' version 2.13 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 530770 bytes.
    ...
    Successfully installed Template-Toolkit version 2.13 in ActivePerl 5.8.7.813.
    ppm> install MailTools
    ====================
    Install 'MailTools' version 1.67 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 46881 bytes.
    ...
    Successfully installed MailTools version 1.67 in ActivePerl 5.8.7.813.
    ppm> install GD
    ====================
    Install 'GD' version 2.07 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 363039 bytes.
    ...
    Successfully installed GD version 2.07 in ActivePerl 5.8.7.813.
    ppm> install Chart
    ====================
    Install 'Chart' version 2.3 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 58641 bytes.
    ...
    Successfully installed Chart version 2.3 in ActivePerl 5.8.7.813.
    ppm> install GDGraph
    ====================
    Install 'GDTextUtil' version 0.86 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 19178 bytes.
    ...
    Successfully installed GDTextUtil version 0.86 in ActivePerl 5.8.7.813.
    ====================
    Install 'GDGraph' version 1.43 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 71764 bytes.
    ...
    Successfully installed GDGraph version 1.43 in ActivePerl 5.8.7.813.
    ppm> install PatchReader
    
    ====================
    Install 'PatchReader' version 0.9.4 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 9558 bytes.
    ...
    Successfully installed PatchReader version 0.9.4 in ActivePerl 5.8.7.813.
    ppm> install Net::LDAP
    
    ====================
    Install 'Convert-ASN1' version 0.19 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 26326 bytes.
    ...
    Successfully installed Convert-ASN1 version 0.19 in ActivePerl 5.8.7.813.
    ====================
    Install 'perl-ldap' version 0.33 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 188548 bytes.
    ...
    Successfully installed perl-ldap version 0.33 in ActivePerl 5.8.7.813.
    ====================
    Install 'Net-LDAP-Express' version 0.11 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 7693 bytes.
    ...
    Successfully installed Net-LDAP-Express version 0.11 in ActivePerl 5.8.7.813.
    ppm>
    

    PatchReader 0.9.4

    Make sure the version of PatchReader that is installed is 0.9.4 or higher. If you end up with an older version, uninstall the ppm and install the ppm from http://landfill.bugzilla.org/ppm/PatchReader.ppd.

    ppm> uninstall PatchReader
    ====================
    Remove 'PatchReader' version 0.9.2 from ActivePerl 5.8.7.813.
    ====================
    ...
    Successfully removed PatchReader version 0.9.2 from ActivePerl 5.8.7.813.
    ppm> install http://landfill.bugzilla.org/ppm/PatchReader.ppd
    ====================
    Install 'PatchReader' version 0.9.4 in ActivePerl 5.8.7.813.
    ====================
    Downloaded 9558 bytes.
    ...
    Successfully installed PatchReader version 0.9.4 in ActivePerl 5.8.7.813.
    ppm>
    

    Apache

    It is recommended that you run Bugzilla with the Apache web server. If you want to use IIS to run Bugzilla, there are configuration instructions in the Bugzilla documentation.

    Download Apache 2.x

    Download the Apache HTTP Server version 2.x or high from:
    http://httpd.apache.org/download.cgi (5.8 Meg).

    Install

    Yet another standard Windows Installer. Just follow the prompts, making sure you Install for All Users. Be aware the Apache will always install itself into an Apache2 directory under what ever path you specify. The default install path will be displayed as C:\Program Files\Apache Group which will result in Apache being installed to C:\Program Files\Apache Group\Apache2. This gets me every time.

    For the remainder of this document I will assume you installed Apache into the default location, C:\Program Files\Apache Group\Apache2.

    If you are already running IIS, you must configure apache to run on a port other than 80, however you aren't asked the port to listen on at install time. Choose All Users (which says port 80), and we'll change the port later.

    By default Apache installs itself to run as the SYSTEM account. For security reasons it's better the reconfigure the service to run as an Apache user. Create a user that is a member of no groups, and reconfigure the Apache2 service to run as that account.

    Grant write access for Apache account

    By default Apache will run as the SYSTEM account. This account needs write and modify access to the following directorys, and all their subdirectories. Depending on your version of Windows, this access may already be granted.

    • C:\Bugzilla\data
    • C:\Program Files\Apache Group\Apache2\logs
    • C:\Temp

    Note that C:\Bugzilla\data is created the first time you run checksetup.pl.

    Configure Port and DocumentRoot

    Edit C:\Program Files\Apache Group\Apache2\conf\httpd.conf with your favourite text editor.

    To change the port that Apache runs on (listens on, or binds to), edit the Listen option.

    #
    # Listen: Allows you to bind Apache to specific IP addresses and/or
    # ports, instead of the default. See also the <VirtualHost>
    # directive.
    #
    # Change this to Listen on specific IP addresses as shown below to 
    # prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
    #
    #Listen 12.34.56.78:80
    Listen 80
    
    

    Change the DocumentRoot setting to point to C:\Bugzilla. Note there are two locations in httpd.conf that need to be updated. Note you need to use / instead of \ as a path separator.

    #
    # DocumentRoot: The directory out of which you will serve your
    # documents. By default, all requests are taken from this directory, but
    # symbolic links and aliases may be used to point to other locations.
    #
    DocumentRoot "C:/Bugzilla"
    
    #
    # Each directory to which Apache has access can be configured with respect
    # to which services and features are allowed and/or disabled in that
    # directory (and its subdirectories). 
    #
    # First, we configure the "default" to be a very restrictive set of 
    # features.  
    #
    <Directory />
        Options FollowSymLinks
        AllowOverride None
    </Directory>
    
    #
    # Note that from this point forward you must specifically allow
    # particular features to be enabled - so if something's not working as
    # you might expect, make sure that you have specifically enabled it
    # below.
    #
    
    #
    # This should be changed to whatever you set DocumentRoot to.
    #
    <Directory "C:/Bugzilla">
    

    Configure CGI

    To enable CGI support in Apache, you need to enable the CGI handler, by uncommenting the AddHandler cgi-scrīpt .cgi line.

    #
    # AddHandler allows you to map certain file extensions to "handlers":
    # actions unrelated to filetype. These can be either built into the server
    # or added with the Action directive (see below)
    #
    # To use CGI scrīpts outside of scrīptAliased directories:
    # (You will also need to add "ExecCGI" to the "Options" directive.)
    #
    AddHandler cgi-scrīpt .cgi
    

    And allow .cgi scrīpts in the Bugzilla directory by adding the ExecCGI option. We also need to allow Bugzilla's .htaccess file to restrict access to sensitive documents by allowing it to override the defaults. This involves changing AllowOverride None to AllowOverride All.

    Apache also needs to know to use Perl to execute .cgi files, via the scrīptInterpreterSource directive.

    #
    # This should be changed to whatever you set DocumentRoot to.
    #
    <Directory "C:/Bugzilla">
    
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs-2.0/mod/core.html#options
    # for more information.
    #
        Options Indexes FollowSymLinks ExecCGI
    
    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
        AllowOverride All
    
    #
    # Controls who can get stuff from this server.
    #
        Order allow,deny
        Allow from all
    
    #
    # Tell Apache to use Perl to execute .cgi
    #
        scrīptInterpreterSource Registry-Strict
    
    </Directory>
    

    You also should add index.cgi to the DirectoryIndex list.

    #
    # DirectoryIndex: sets the file that Apache will serve if a directory
    # is requested.
    #
    # The index.html.var file (a type-map) is used to deliver content-
    # negotiated documents.  The MultiViews Option can be used for the 
    # same purpose, but it is much slower.
    #
    DirectoryIndex index.html index.html.var index.cgi
    

    In order for scrīptInterpreterSource Registry-Strict to work, you also need to add an entry to the Registry so Apache will use Perl to execute .cgi files.

    Create a key HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI\Command with the default value of the full path of perl.exe with a -T parameter. For example C:\Perl\bin\perl.exe -T

    regedit screenshot

    Disable Logging

    Unless you want to keep statistics on how many hits your Bugzilla install is getting, it's a good idea to disable logging by commenting out the CustomLog directive.

    #
    # The location and format of the access logfile (Common Logfile Format).
    # If you do not define any access logfiles within a <VirtualHost>
    # container, they will be logged here.  Contrariwise, if you *do*
    # define per-<VirtualHost> access logfiles, transactions will be
    # logged therein and *not* in this file.
    #
    #CustomLog logs/access.log common
    

    Restart Apache

    Finally, restart Apache to get it pick up the changes.

    C:\>net stop apache2
    The Apache2 service is stopping..
    The Apache2 service was stopped successfully.
    
    C:\>net start apache2
    The Apache2 service is starting.
    The Apache2 service was started successfully.
    
    C:\>
    

    Extras

    While Bugzilla has built in support for SMTP servers, it doesn't (yet) support SMTP authentication or debugging of SMTP errors.

    If you require SMTP authentiation (including POP before SMTP), you can use Glob's sendmail wrapper. Download and install as per the instructions on that site.

    If you enable logging in Sendmail, you need to ensure that your Apache account has write access to C:\usr\lib.

    Configure Bugzilla

    checksetup.pl

    Run checksetup.pl. This will check your Perl modules and create localconfig.

    C:\>cd bugzilla
    
    C:\bugzilla>perl checksetup.pl
    
    Checking perl modules ...
    Checking for       AppConfig (v1.52)   ok: found v1.55
    Checking for             CGI (v2.93)   ok: found v3.10
    Checking for    Data::Dumper (any)     ok: found v2.121_04
    Checking for    Date::Format (v2.21)   ok: found v2.22
    Checking for             DBI (v1.38)   ok: found v1.48
    Checking for      File::Spec (v0.84)   ok: found v3.05
    Checking for      File::Temp (any)     ok: found v0.16
    Checking for        Template (v2.08)   ok: found v2.13
    Checking for      Text::Wrap (v2001.0131) ok: found v2001.09293
    Checking for    Mail::Mailer (v1.65)   ok: found v1.67
    Checking for        Storable (any)     ok: found v2.13
    
    The following Perl modules are optional:
    Checking for              GD (v1.20)   ok: found v2.16
    Checking for     Chart::Base (v1.0)    ok: found v2.3
    Checking for     XML::Parser (any)     ok: found v2.34
    Checking for       GD::Graph (any)     ok: found v1.43
    Checking for GD::Text::Align (any)     ok: found v1.18
    Checking for     PatchReader (v0.9.4)  ok: found v0.9.5
    
    Most ActivePerl modules are available at Apache's ppm repository.
    A list of mirrors is available at
        http://www.apache.org/dyn/closer.cgi/perl/win32-bin/ppms/
    You can add the repository with the following command:
        ppm rep add apache http://www.apache.org/dist/perl/win32-bin/ppms/
    
    Checking user setup ...
    
    This version of Bugzilla contains some variables that you may want
    to change and adapt to your local settings. Please edit the file
    './localconfig' and rerun checksetup.pl
    
    The following variables are new to localconfig since you last ran
    checksetup.pl:   index_html cvsbin interdiffbin diffpath create_htaccess
    webservergroup db_driver db_host db_pass db_sock db_check
    
    C:\bugzilla>
    

    Edit localconfig

    Open C:\Bugzilla\localconfig in your favourite text editor to configure Bugzilla.

    You have to tell Bugzilla how to access your database. If you used bugs/bugs, you'll only have to set db_pass.

    #
    # How to access the SQL database:
    #
    $db_host = "localhost";         # where is the database?
    $db_port = 3306;                # which port to use
    $db_name = "bugs";              # name of the MySQL database
    $db_user = "bugs";              # user to attach to the MySQL database
    
    #
    # Enter your database password here. It's normally advisable to specify
    # a password for your bugzilla database user.
    # If you use apostrophe (') or a backslash (\) in your password, you'll
    # need to escape it by preceding it with a \ character. (\') or (\\)
    #
    $db_pass = 'sockmonkey';
    

    checksetup.pl

    Run checksetup.pl again. This time it will build your database tables and initialise Bugzilla.

    C:\bugzilla>perl checksetup.pl
    
    Checking perl modules ...
    Checking for       AppConfig (v1.52)   ok: found v1.55
    Checking for             CGI (v2.93)   ok: found v3.10
    Checking for    Data::Dumper (any)     ok: found v2.121_04
    Checking for    Date::Format (v2.21)   ok: found v2.22
    Checking for             DBI (v1.38)   ok: found v1.48
    Checking for      File::Spec (v0.84)   ok: found v3.05
    Checking for      File::Temp (any)     ok: found v0.16
    Checking for        Template (v2.08)   ok: found v2.13
    Checking for      Text::Wrap (v2001.0131) ok: found v2001.09293
    Checking for    Mail::Mailer (v1.65)   ok: found v1.67
    Checking for        Storable (any)     ok: found v2.13
    
    The following Perl modules are optional:
    Checking for              GD (v1.20)   ok: found v2.16
    Checking for     Chart::Base (v1.0)    ok: found v2.3
    Checking for     XML::Parser (any)     ok: found v2.34
    Checking for       GD::Graph (any)     ok: found v1.43
    Checking for GD::Text::Align (any)     ok: found v1.18
    Checking for     PatchReader (v0.9.4)  ok: found v0.9.5
    
    Most ActivePerl modules are available at Apache's ppm repository.
    A list of mirrors is available at
        http://www.apache.org/dyn/closer.cgi/perl/win32-bin/ppms/
    You can add the repository with the following command:
        ppm rep add apache http://www.apache.org/dist/perl/win32-bin/ppms/
    
    Checking user setup ...
    Creating data directory (./data) ...
    Creating graphs directory...
    Creating .htaccess...
    Creating Bugzilla/.htaccess...
    Creating ./data/.htaccess...
    Creating ./template/.htaccess...
    Creating ./data/webdot/.htaccess...
    Precompiling templates ...
    Checking for    MySQL Server (v3.23.41) ok: found v4.0.20a-debug
    
    Creating table user_group_map ...
    Creating table series_data ...
    Creating table longdescs ...
    Creating table dependencies ...
    Creating table components ...
    Creating table keywords ...
    Creating table cc ...
    Creating table duplicates ...
    Creating table groups ...
    Creating table flagtypes ...
    Creating table profiles ...
    Creating table products ...
    Creating table bugs_activity ...
    Creating table series_categories ...
    Creating table keyworddefs ...
    Creating table fielddefs ...
    Creating table group_control_map ...
    Creating table profiles_activity ...
    Creating table group_group_map ...
    Creating table user_series_map ...
    Creating table bugs ...
    Creating table series ...
    Creating table versions ...
    Creating table flagexclusions ...
    Creating table logincookies ...
    Creating table watch ...
    Creating table bug_group_map ...
    Creating table votes ...
    Creating table attachments ...
    Creating table flags ...
    Creating table milestones ...
    Creating table tokens ...
    Creating table flaginclusions ...
    Creating table quips ...
    Creating table namedqueries ...
    Creating initial dummy product 'TestProduct' ...
    Populating duplicates table...
    Creating duplicates directory...
    Migrating old chart data into database ...
    Adding group tweakparams ...
    Adding group editusers ...
    Adding group creategroups ...
    Adding group editcomponents ...
    Adding group editkeywords ...
    Adding group admin ...
    Adding group editbugs ...
    Adding group canconfirm ...
    
    Looks like we don't have an administrator set up yet.  Either this is your
    first time using Bugzilla, or your administrator's privileges might have
    accidently been deleted.
    Enter the e-mail address of the administrator: byron@example.com
    You entered 'byron@example.com'.  Is this correct? [Y/n] y
    Enter the real name of the administrator: Byron Jones
    
    Enter a password for the administrator account: beef
    
    Please retype the password to verify: beef
    
    'byron@example.com' is now set up as an administrator account.
    
    C:\bugzilla>
    

    Parameters

    You should now be able to log into to Bugzilla using the account checksetup.pl just created. Point your web browser to http://localhost/, choose Log in to an existing account, and login.

    In the page footer, choose Parameters.

    Put in your email address as the maintainer.

    maintainer:
    The email address of the person who maintains this installation of Bugzilla.
    byron@example.com

    Put in the URL to Bugzilla in the urlbase field. This URL will be used in emails, so don't use localhost.

    urlbase:
    The URL that is the common initial leading part of all Bugzilla URLs.
    http://bugzilla.example.com/

    Download and install WebDot from http://www.graphviz.org/Download_windows.php. Put the complete path to dot.exe in webdotbase.

    webdotbase:
    It is possible to show graphs of dependent bugs. You may set this parameter to any of the following:

      * A complete file path to 'dot' (part of GraphViz) will generate the graphs locally.
      * A URL prefix pointing to an installation of the webdot package will generate the graphs remotely.
      * A blank value will disable dependency graphing.

    The default value is a publically-accessible webdot server. If you change this value, make certain that the webdot server can read files from your webdot directory. On Apache you do this by editing the .htaccess file, for other systems the needed measures may vary. You can run checksetup.pl to recreate the .htaccess file if it has been lost.
    C:/Program Files/ATT/Graphviz/bin/dot.exe

    Scheduled Tasks

    collectstats.pl

    Add a Scheduled Task to run collectstats.pl nightly.

    Step-by-step for Windows XP:

    1. Control Panel --> Scheduled Tasks --> Add Scheduled Task
    2. Next
    3. Browse
    4. Find perl.exe (normally C:\Perl\bin\perl.exe)
    5. Give it a name, such as "Bugzilla Collect Stats"
    6. Perfom the task daily at your desired time
    7. If you're running Apache as a user, not as SYSTEM, enter that user here. Otherwise you're best off creating an account that has write access to the Bugzilla directory and using that
    8. Tick "Open Advanced Properties.." and click Finish
    9. Append the scrīpt name to the end of the "Run" field. eg C:\Perl\bin\perl.exe C:\Bugzilla\collectstats.pl
    10. Change "start in" to the Bugzilla directory

    whineatnews.pl

    Add a Scheduled Task to run whineatnews.pl nightly.

    The steps for setting up whineatnews.pl are as per collectstats.pl

    whine.pl

    Add a Scheduled Task to run whine.pl nightly.

    The steps for setting up whine.pl are as per collectstats.pl, except whine.pl needs to run in Perl's Taint mode. The command line needs to include the -T option: C:\Perl\bin\perl.exe -T C:\Bugzilla\whine.pl

    Backing up Bugzilla

    You may want to backup the entire Bugzilla directory. It's small and you'll get all your settings and customisations on your backup media.

    The most important component of Bugzilla to backup is the Bugzilla Database. It contains all your Bugs, Users, Attachments, pretty well everything. Like most databases, backups with MySql are performed by generating a dump of the database and backing up the dump.

    Schedule the mysqldump utility to create the dump, and add the resulting file to your backup media. You'll find MySql's mysqldump documentation at http://dev.mysql.com/doc/mysql/en/mysqldump.html.

    Congratulations, the Bugzilla installation process is complete!

    爱生活爱爸爸爱妈妈爱自己爱龟龟爱家家爱本本爱澡澡爱作作爱飞飞爱吃吃爱觉觉爱觅觅爱蜜蜜爱爬爬爱孜孜爱娜娜

    我要宣布我最爱银子,哈哈。。。

    不过这篇文章更好,吼吼~~~大声吼三下~ ^o^,^o^,^o^

     

     

  • 想妈妈想爸爸

    2007-05-24 08:48:52

    如题
  • 胃痛胃胀想吐

    2007-05-23 10:32:33

    难受,如题。
  • Bugfree安装备忘录(转)

    2007-05-22 17:32:26

    1.安装Mysql(5.0.37)
       安装完毕后有时要打开防火墙打开3306端口
    2.安装Apache2.2.4到C:\apache
       安装完毕提示133行错误,打开\conf中,修改httpd文件,在133行前加#
    3.目录增加读写权限
    4.解压缩PHP5.2.1到C:\PHP
       修改php.ini-dist,改名去掉-dist后复制到c:\windows
       复制php5ts.dll和libmysql.dll到system32
    5.修改c:\apache\conf\httpd.conf
       在#LoadModule ssl_module modules/mod_ssl.so的下面添加
        LoadModule PHP5_module c:/PHP/PHP5apache2_2.dll
       在AddType application/x-gzip .gz .tgz的下面添加
        AddType application/x-httpd-PHP .PHP
    6.解压缩Greenamp050123到c:\Greenamp
    7.解压缩Bugfree到Greenamp下的www文件夹中
    8.运行phpmyadmin,创建数据库Bugfree
    9.选择Bugfree库,选择SQL,选择greenamp\bugfree\document下的bugfree.sql,选择执行
    10.运行install.php配置bugfree
    11.打开配置文件,修改邮件区代码那个false为true
    12.修改配置文件中1024*100改为1024*1000
    13.服务器可以不装IIS,装了IIS要修改端口号,把80改为别的端口号
    14.PHPmyadmin的登陆密码不要修改,默认是root,密码空,改了密码后,可以用phpmyadmin,密码空登陆,再改密码就只有百度"phpmyadmin 修改密码"找解决办法了

     

    相关软件下载页面

    图解

     

  • 测试用例模板和sample(转)

    2007-05-22 08:46:58

    测试用例模板(Test Case Template)

    ┏━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃用例编号  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃测试优先级 │                           ┃
    ┠──────┼───────────────────────────┨
    ┃用例摘要  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃测试类型  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃用例类型  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃用例设计者 │                           ┃
    ┠──────┼───────────────────────────┨
    ┃设计日期  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃对应需求编号│                           ┃
    ┠──────┼───────────────────────────┨
    ┃对应UI   │                           ┃
    ┠──────┼───────────────────────────┨
    ┃对应UC   │                           ┃
    ┠──────┼───────────────────────────┨
    ┃版本号   │                           ┃
    ┠──────┼───────────────────────────┨
    ┃对应开发人员│                           ┃
    ┠──────┼───────────────────────────┨
    ┃前置条件  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃测试方法  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃输入数据  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃执行步骤  │                           ┃
    ┃      │                           ┃
    ┃      │                           ┃
    ┃      │                           ┃
    ┃      │                           ┃
    ┃      │                           ┃
    ┃      │                           ┃
    ┃      │                           ┃
    ┃      │                           ┃
    ┃      │                           ┃
    ┃      │                           ┃
    ┠──────┼───────────────────────────┨
    ┃预期输出  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃实际结果  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃测试日期  │                           ┃
    ┠──────┼───────────────────────────┨
    ┃结论    │                           ┃
    ┗━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
     
    sample

    ┏━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃用例编号  │BOSS_ FS_ MARKETING_NEW_01P              ┃
    ┠──────┼───────────────────────────┨
    ┃测试优先级 │高(还有“较高、中、较低、低”几个等级)       ┃
    ┠──────┼───────────────────────────┨
    ┃用例摘要  │新增营销记录                     ┃
    ┠──────┼───────────────────────────┨
    ┃测试类型  │功能性测试(对应还有“安全性测试”等)        ┃
    ┠──────┼───────────────────────────┨
    ┃用例类型  │基本事件(对应还有“备选事件”、“异常事件”)    ┃
    ┠──────┼───────────────────────────┨
    ┃用例设计者 │songfun                        ┃
    ┠──────┼───────────────────────────┨
    ┃设计日期  │2005-04-25                      ┃
    ┠──────┼───────────────────────────┨
    ┃对应需求编号│REQ_ MARKETING_NEW_01                 ┃
    ┠──────┼───────────────────────────┨
    ┃对应UI   │Marketing.htm                     ┃
    ┠──────┼───────────────────────────┨
    ┃对应UC   │UC_ MARKETING_NEW_01                 ┃
    ┠──────┼───────────────────────────┨
    ┃版本号   │Build v0.1                      ┃
    ┠──────┼───────────────────────────┨
    ┃对应开发人员│Frank                         ┃
    ┠──────┼───────────────────────────┨
    ┃前置条件  │操作员登录营销管理系统                ┃
    ┠──────┼───────────────────────────┨
    ┃测试方法  │等价类划分(对应还有“错误猜测法”、“边界值分析”等)┃
    ┠──────┼───────────────────────────┨
    ┃输入数据  │用户名:51testing 性别:男 金额:10元 描述:aaaaaaa  ┃
    ┠──────┼───────────────────────────┨
    ┃执行步骤  │①.进入【营销下发】页面;               ┃
    ┃      │②.点击『增加』按钮;                 ┃
    ┃      │③.输入相应数据;                   ┃
    ┃      │④.点击『确定』按钮;                 ┃
    ┃      │⑤.在后台数据库(test/test@testDB)输入查询语句验证:  ┃
    ┃      │  select * from MarketingTab where ID='1001'    ┃
    ┃      │                           ┃
    ┠──────┼───────────────────────────┨
    ┃预期输出  │㈠.执行步骤④后,页面弹出添加成功提示信息框;     ┃
    ┃      │㈡.执行步骤⑤后查询数据库,记录确实添加成功且数据无误 ┃
    ┃      │                           ┃
    ┠──────┼───────────────────────────┨
    ┃实际结果  │符合预期                       ┃
    ┠──────┼───────────────────────────┨
    ┃测试日期  │2005-05-01                      ┃
    ┠──────┼───────────────────────────┨
    ┃结论    │                           ┃
    ┗━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
     
  • 被保护的世界还是被羞辱的世界

    2007-05-21 08:36:56

    买了早点,却没有一点点胃口,不想吃。。。

    我不想呆在这里不想呆在只有我的世界里不想呆在成天成为某人笑柄的世界里,让我很受挫,让我想逃,让我不知所措,让我很自卑,让我自保不了。。。可是某人却不认为,我觉得让我伤心难过心痛的事情他都会觉得很好笑,要么语气强硬或者无所谓或者觉得只要哄一下我就可以了,可是你错了,那样只会适得其反,因为他自始至终都觉得我是无理取闹,我真的是无理取闹吗?你考虑过你说什么话别人的感受吗?你知道当你大笑的时候严重伤害到我的自尊了吗?你知道当我和你一次次提出,你一次次答应不再说却一次次口无遮拦吗,你每次都说是开玩笑的,你说你也知道我知道你是开玩笑的,可是我说过,开玩笑是有分寸的,我始终强颜欢笑,却反让你让我觉得我在你的世界里永远都是被你戏弄的笑料,因为你没有用心去感受我的世界。

    你根本无法体会做为你的妻子现在的感受,你让我觉得生活无趣,让我觉得被羞辱,让我觉得想死。。。

     

     

  • 呜呜,没有眼镜的日子

    2007-05-18 11:41:51

    眼镜架的眼镜腿彻底的结束了它爆贵的两年生命。。。

    中午去亚洲寻觅新欢。。。

     

     

    已经配镜完毕,本打算只换个镜架,可。。。店员说适合我的镜片的就几副,可是我看了都不好看

    某人在旁边说不如重新配吧,俺就彻底的被瓦解了。。。

    结果光是验光就花了不知道多久的时间。。。然后选镜片。。。再选镜架。。。再选颜色。。。再买单。。。再。。。

    吖。。。一中午的时间就没有了,下午我等眼镜店的电话,让店长帮忙给我加快了,唉。。。一只腿的眼镜戴着真难受。。。就差上厕所没掉进wc了。。。

    怀念完整的眼镜。。。。一只腿的眼镜架在鼻梁上,晃来晃去的,看得我眼睛直花。。。

     

     

     

  • Fighting~

    2007-05-18 10:47:32

    我要奋力的向前冲吖冲吖冲吖~

     

     

     

    不过不是为了吃饭冲,借用一下图图~

     

     

  • 软件测试工程师薪资调查(转)

    2007-05-16 14:11:15

    因修正错误而存在——软件测试工程师

      
    所属门派:IT业
      “假如存在没有任何错误的程序,那么世界也会不复存在。”
       因错误而存在,因修正错误而存在,这就是软件测试工程师的存在之道。虽然测试不是解决错误的根本举措,但却是必须的手段。
            软件测试工程师(Software
    Testing Engineer)的主要工作职责是,理解产品的功能要求,并对其进行测试,检查软件有没有错误(Bug),决定软件是否具有稳定性(Robustness),写出相应的测试规范和测试案例。
            简而言之,软件测试工程师在一家软件企业中担当的是“质量管理”角色,及时纠错及时更正,确保产品的正常运作。据有关调查数据表明,目前国内许多软件企业内部的测试人员和开发人员之比在1:5,与国外软件业1:1的比例还相去甚远。


      门派技能:
      软件测试工程师主要职责为:
      1、负责项目/产品的测试工作,分析产品需求,建立测试环境和计划,保证产品质量以及测试工作的顺利进行;
      2、按照软件工程规范和项目管理流程,实施、管理和知道软件开发不同阶段的各种测试,并提交测试报告。测试的计划安排包括人员安排、进度、使用的软硬件环境、测试的流程等;
      3、提交测试报告,并撰写用户说明书;
      4、参与软件
    测试技术和规范的改进和制定。


      入门资质:
      一般需要至少专科学历,一到两年测试工作经验。要熟悉软件的测试技术、方法、流程、测试文档,若想进一步提升,还要熟悉
    自动化测试的流程、管理及深层开发(包括测试框架等);了解若干主流测试工具,如功能测试工具winrunner、quicktestpro,性能测试工具LoadRunner,配置管理工具TestDirecter, Visiual Source Safe等;熟悉一些主流的软件工程方法论和思想,如RUP、CMM、CMMI、XP、PSP、TSP;了解软件工程,软件生命周期模型基础,了解软件配置管理;能够根据不同企业的产品特点,要求了解相应的开发测试方法。对于资深的软件测试人员,有些企业还要求其本身有自主开发测试工具的能力。
      由于需要与开发人员及时沟通,因此作为一个出色的软件测试工程师,还需要有良好的沟通技巧以及优秀的言语表达能力,具备良好的团队合作精神。


      入门经:
      缜密的逻辑思维能力为了应对软件使用者千差万别的使用习惯和软件在使用过程中出现的各种现象,软件测试工程师应该具有逆向思维能力,能够以用户的角度出发,捕获一切可能性,对细节有不同寻常的关注能力。此外,软件测试工程师还要有穷追到底的精神,并且要善于沟通和撰写各类专业报告。
      出色的沟通能力要成为优秀的软件测试工程师,要具备出色的沟通能力和表达能力,既能够和技术开发人员沟通无碍,又能用简洁明了的话语向客户、管理者等这些非技术人员阐述系统在哪些方面还有缺失有待改进。在同开发人员的沟通过程中,要注意沟通技巧,提高沟通效率,和开发人员保持良好的人际关系。当测试人员发现软件有问题时,不仅需要跟开发人员沟通,找到问题出在哪儿,阐述自己挑错的理由,有时候甚至要提出解决方案,直接参与前期需求和代码的修改。一个优秀的软件测试工程师能够适时地站在各自的立场上考虑、解释并解决问题,从而尽量避免冲突和对抗。
      全面的技术能力作为软件测试工程师,虽然无须精通各种语言各类技术,但必须全面理解被测软件系统,明白该使用何种工具进行测试。要做到这一点一般需要有一定的编程经验,这些经验可以加深对软件开发过程的理解。
      耐得住性子 软件测试工作是枯燥的,甚至重复性的,有时需要花费惊人的时间去分离、识别和分派一个错误,因此需要测试人员能静得下心耐得住性子。这个工作不容许有丝毫的心浮气躁。同时,逻辑严密但不乏重复成分的测试工作也容易使人倦怠,因此需要一定的自我督促能力。
      规范测试流程公司不正规的测试流程,不标准的测试方法,将使软件测试人员终日陷入碌碌无为的点击按钮的不良状态中。


      晋阶易筋经:
      初级测试工程师
      入门级,具有一些手工测试经验,开发测试脚本并开始熟悉测试生存周期和测试技术;
      测试工程师
      能够独立编写自动测试脚本程序并担任测试编程初期的领导工作,进一步拓展编程语言、
    操作系统、网络与数据库方面的技能;
      高级测试工程师
      帮助开发或维护测试或编程标准与过程,负责同级的评审,并能够指导初级的测试工程师;
      Team Leader
      一般具有5年左右工作经验,负责管理一个小团队。负责进度安排、工作规模/成本估算、按进度表和预算目标交付产品,负责开发项目的技术方法,能够为用户提供支持与演示;
      测试经理
      能够担当测试领域内的整个开发生存周期业务,能够为用户提供交互和大量演示,负责项目成本、进度安排、计划和人员分工;
      计划经理
      具有多年纯熟的开发与支持(测试/质量保证)活动方面的经验,管理从事若干项目的人员以及整个开发生存周期,负责把握项目方向与盈亏责任。


      秘传“薪”经:
      薪资黄金点
      软件测试工程师在IT行业中越来越受到重视,其薪资也节节高升。
            测试工程师的起薪从2000~5000元/月不等,若有四年工作经验的话,薪资在8000元/月左右,具体视不同地域、不同性质企业、测试工程师的不同能力而定。一般工作5~8年的软件测试工程师的薪资是刚出道时的新手的一倍,而10年以上工作经验的软件测试工程师薪资却走了下坡路,和5~8年的从业者持平甚至有些企业开出了略低的薪资,看来这行的折旧率较高。
      软件测试行业的从业者7成左右都拥有本科学历,本科学历的从业者的薪资约为大专学历从业者的1.33倍左右,而硕士学历的从业者薪资起点明显高于本科学历从业者,约为后者的1.49倍。一般外语能力精通者的薪资为平均薪资的1.29倍左右,熟练者为平均薪资的1.09倍,值得注意的是,深圳、杭州和大连的外语能力精通者的薪资均超出平均薪资不少,其中杭州的外语能力精通者的薪资是平均薪资的1.79倍。
      以3.5年左右从业工作经验的软件测试工程师的各地薪资情况来看:
      深圳地区的平均年薪是全国各城市最高的,超出7万元,其中外商独资欧美企业的年薪为7.8万元,国营企业的年薪紧随其后,超过了7.3万元,合资/合作非欧美企业的年薪较低,约为6万。
      北京地区该职位的平均年薪逾5.8万元;其中外商独资企业的年薪为全国之最,将近8.5万元,而其余各类型企业的年薪都在5~6万元左右。
      广州地区该职位的平均年薪约为4.5万元;其中外商独资欧美企业的年薪最高,达到了7万元;合资/合作欧美企业也能拿到6.2万元的平均年薪,合资/合作非欧美企业就较逊色,年薪不到4万元。
      上海地区软件测试工程师的平均年薪为6.3万元,欧美独资和欧美合资的薪资不相上下,分别为7.9万和7.7万元。国营企业略高于平均线,达到6.5万元,其余各类企业则都表现平平。
      杭州地区该职位的平均年薪达到了5.5万元;其中外商独资欧美企业和合资/合资欧美企业的年薪相当,均为6.9万元,国营企业的薪资也颇吸引人,超过了5.9万元,民营/私企和合资/合作非欧美企业的年薪均不到5万元。
      大连地区该职位的平均年薪为3.8万元;其中外商独资企业和合资/合作欧美企业的年薪均超过了4.7万元;国营企业的软件测试工程师的年薪也近4万元左右,而民营/私企和合资/合作非欧美企业的年薪则相对较低。


      福利
      上海地区的软件测试工程师享有的带薪年假是全国各地最多的,一年中平均有10天,北京、广州、大连均为8天,杭州和深圳相对较少,为6天。
      以上这些地区在软件测试的培训方面都做得不错,基本上均有6成以上的从业者可享受到公司提供的培训计划,但上海的软件工程师的培训比例不到5成。杭州和深圳两地的培训是全国各地区最出色的,逼近8成。
      深圳、上海均有2成的从业者可享受房贴或者补充住房公积金,大连和北京则有3成以上的从业者可享受公司的房贴或者补充住房公积金,广州更是达到了4成以上,而杭州此项福利的比例较低,仅为1成。

  • 哼哼

    2007-05-16 11:34:10

    说话跟蚊子而且还是小蚊子似的,只能听见哼哼哼哼的声音,让我真想掐死它...
  • 九种打领带的方法(图解)

    2007-05-14 12:32:47

    按此在新窗口浏览图片
    1、平结
         平结为最多男士选用的领结打法之一,几乎适用于各种材质的领带。
    要诀:领结下方所形成的凹洞需让两边均匀且对衬。



    按此在新窗口浏览图片
    2、交叉结
         这是对于单色素雅质料且较薄领带适合选用的领结,对于喜欢展现流行感的男士不妨多加使用“交叉结”。


    按此在新窗口浏览图片

    3、双环结
         一条质地细致的领带再搭配上双环结颇能营造时尚感,适合年轻的上班族选用。该领结完成的特色就是第一圈会稍露出于第二圈之外,可别刻意给盖住了。


    按此在新窗口浏览图片

    4、 温莎结
      温莎结适合用于宽领型的衬衫,该领结应多往横向发展。应避免材质过厚的领带,领结也勿打得过大。


    按此在新窗口浏览图片

    5、双交叉结
      这样的领结很容易让人有种高雅且隆重的感觉,适合正式之活动场合选用。该领结应多运用在素色且丝质领带上,若搭配大翻领的衬衫不但适合且有种尊贵感。


    按此在新窗口浏览图片
    6、四手结(单结)
      是所有领结中最容易上手的,适用於各种款式的浪漫系列衬衫及领带


    按此在新窗口浏览图片

    7、浪漫结
      浪漫是一种完美的结型
      故适合用於各种浪漫系列的领口及衬衫
      完成後将领结下方之宽边压以绉摺可缩小其结型
      窄边亦可将它往左右移动使其小部份出现於宽边领带旁


    按此在新窗口浏览图片

    8、简式结(马车夫结)
      适用於质料较厚的领带
      最适合打在标准式及扣式领口之衬衫
      将其宽边以180度由上往下翻转
      并将折叠处隐藏於後方
      待完成後可再调整其领带长度
      是最常见的一种结形


    按此在新窗口浏览图片

    9、十字结(半温莎结)
      此款结型十分优雅及罕见
      其打法亦较复杂
      使用细款领带较容易上手
      最适合搭配在浪漫的尖领及标准式领口系列衬衫
  • BB

    2007-05-14 09:32:19

    点击查看原图

     

     

    这是我大学同学的BB,-_-#!!!都这么大乐...不过也是,人家已经开了家公司自己当老板乐。。。

    看墙上的那个奖状...,BB都肯定上小学乐,难怪以前听别人说***孩子都可以打酱油乐。。。

    据说是双胞胎呢,以后吖,我要生个龙凤胎

     

     

  • VuGen脚本开发(持续更新)

    2007-05-11 09:18:56

    OSI七层模型详解下载视听

    Ø         VuGen脚本开发

    ü         选择协议(录制脚本之前

    LR是通过监控网络客户端和服务器端之间的数据通信关系来录制脚本的。

    (即:只要客户端和服务器端之间交互并得到一个响应就可进行脚本录制)

    !       网络协议的分析

    ©        协议层次

    OSI 参 考 模 型

    Open System Interconnection

     

     

     

    物理层(Physical Layer) :传递物理属性(即提供机械、电气、功能和过程特性)。如规定使用电缆和接头的类型,传送信号的电压等。在这一层,数据还没有被组织,仅作为原始的位流或电气电压处理。比特

    数据链路层(Data Link Layer) :链接两个相邻点之间的线路,实现数据的无差错传送。它接收物理层的原始数据位流以组成帧(位组),并在网络设备之间传输。帧含有源站点和目的站点的物理地址

    网络层(Network Layer):处理网络间路由,确保数据及时传送。将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息 — — 源站点和目的站点地址的网络地址

    传输层(Transport Layer):提供建立、维护和取消传输连接功能,负责可靠地传输数据。报文

    会话层(Session Layer) :提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制。如服务器验证用户登录便是由会话层完成的。报文

    表示层(Presentation Layer):提供格式化的表示和转换数据服务(解决用户语法表示问题)。如语音数据的压缩和解压缩,加密和解密等工作都由表示层负责。

    应用层(Application Layer) :提供网络与用户应用软件之间的接口服务。

     

    ©        协议:一种通讯的规则。

       

     

     

    !       选择协议的方法

    ©        初步分析

    ©        分析架构

    ©        通用协议:一般是最底层的协议

    ©        特殊情况:一般没有协议的支持就自己二次开发应用。