Yogesh Deshpande和Steve Hansen在1998年就提出了Web工程的概念。Web工程作为一门新兴的学科,提倡使用一个过程和系统的方法来开发高质量的基于Web的系统。它" 使用合理的、科学的工程和管理原则,用严密的和系统的方法来开发、发布和维护基于 Web的系统"。目前,对于web工程的研究主要是在国外开展的,国内还刚刚起步。
在基于Web的系统开发中,如果缺乏严格的过程,我们在开发、发布、实施和维护 Web的过程中,可能就会碰到一些严重的问题,失败的可能性很大。而且,随着基于Web 的系统变得越来越复杂,一个项目的失败将可能导致很多问题。当这种情况发生时,我们对Web和Internet的信心可能会无法挽救地动摇,从而引起Web危机。并且,Web危机可能会比软件开发人员所面对的软件危机更加严重、更加广泛。
在Web工程过程中,基于Web系统的测试、确认和验收是一项重要而富有挑战性的工作。基于Web的系统测试与传统的软件测试不同,它不但需要检查和验证是否按照设计的要求运行,而且还要测试系统在不同用户的浏览器端的显示是否合适。重要的是,还要从最终用户的角度进行安全性和可用性测试。然而,Internet和Web媒体的不可预见性使测试基于Web的系统变得困难。因此,我们必须为测试和评估复杂的基于Web的系统研究新的方法和技术。
一般软件的发布周期以月或以年计算,而Web应用的发布周期以天计算甚至以小时计算。Web测试人员必须处理更短的发布周期,测试人员和测试管理人员面临着从测试传统的C/S结构和框架环境到测试快速改变的Web应用系统的转变。
一、功能测试
1、链接测试
链接是Web应用系统的一个主要特征,它是在页面之间切换和指导用户去一些不知道地址的页面的主要手段。链接测试可分为三个方面。首先,测试所有链接是否按指示的那样确实链接到了该链接的页面;其次,测试所链接的页面是否存在;最后,保证Web应用系统上没有孤立的页面,所谓孤立页面是指没有链接指向该页面,只有知道正确的URL地址才能访问。
链接测试可以自动进行,现在已经有许多工具可以采用。链接测试必须在集成测试阶段完成,也就是说,在整个Web应用系统的所有页面开发完成之后进行链接测试。
2、表单测试
当用户给Web应用系统管理员提交信息时,就需要使用表单操作,例如用户注册、登陆、信息提交等。在这种情况下,我们必须测试提交操作的完整性,以校验提交给服务器的信息的正确性。例如:用户填写的出生日期与职业是否恰当,填写的所属省份与所在城市是否匹配等。如果使用了默认值,还要检验默认值的正确性。如果表单只能接受指定的某些值,则也要进行测试。例如:只能接受某些字符,测试时可以跳过这些字符,看系统是否会报错。
?
3、Cookies测试
Cookies通常用来存储用户信息和用户在某应用系统的操作,当一个用户使用Cookies访问了某一个应用系统时,Web服务器将发送关于用户的信息,把该信息以Cookies的形式存储在客户端计算机上,这可用来创建动态和自定义页面或者存储登陆等信息。
如果Web应用系统使用了Cookies,就必须检查Cookies是否能正常工作。测试的内容可包括Cookies是否起作用,是否按预定的时间进行保存,刷新对Cookies有什么影响等。
4、设计语言测试
Web设计语言版本的差异可以引起客户端或服务器端严重的问题,例如使用哪种版本的HTML等。当在分布式环境中开发时,开发人员都不在一起,这个问题就显得尤为重要。除了HTML的版本问题外,不同的脚本语言,例如Java、JavaScript、 ActiveX、VBScript或Perl等也要进行验证。
5、数据库测试
在Web应用技术中,数据库起着重要的作用,数据库为Web应用系统的管理、运行、查询和实现用户对数据存储的请求等提供空间。在Web应用中,最常用的数据库类型是关系型数据库,可以使用SQL对信息进行处理。
在使用了数据库的Web应用系统中,一般情况下,可能发生两种错误,分别是数据一致性错误和输出错误。数据一致性错误主要是由于用户提交的表单信息不正确而造成的,而输出错误主要是由于网络速度或程序设计问题等引起的,针对这两种情况,可分别进行测试。
三、 经验与教训
从项目规模中可以看出,该项目的时间还是比较紧张的;另外一方面,项目交付是在合同规定日期之前完成,而且通过了所有的功能测试。从一定意义上的讲,项目的开发是取得了一定的成功的。
3.1 经验
在项目开发前,项目开发商已经通过其它项目,实施了以XP为代表的敏捷软件开发方法的部分最佳实践,并取得了很大的成功。因此,在该项目的执行过程中,项目开发商继续采用了XP的部分实践以及其它软件开发方法中的推荐做法[1][2]:
每日晨会:在项目实施过程中,每天早晨开发小组都要参加一个持续15分钟左右的会议,由项目经理主持,听取每个成员的进度,并根据进展情况,对于进度和资源进行调整。
由于会议是每天进行的,PM很容易从中获得真实的项目情况-"掀开地毯下面的东西"[4],从而对风险有了较好的控制。
交叉审核:项目组在最初的时候原本是想采取"成对编程"的实践,但是没有获得物理和管理上的支持,因此,只能采取交叉审核的方式进行。
需求获取:由PM和一名对于原有系统较熟悉的开发人员进行需求获取和SRS (Software Requirement Specification) 的撰写。技术经理和其它开发人员进行需求的审核。
分析与设计:由一名开发人员进行系统框架的设计,其它人员进行审核;在系统框架设计进行过程中,由于系统去除订单处理以外的其它部分比较独立,因此,将其它模块分配给开发人员,而将核心部分交与技术经理进行分析与设计。开发人员在每个迭代周期内,都会在分析与设计做完后,每2人一组进行审核。
编码:每天下班前,2人一组,对对方的代码进行Review,发现问题及时解决。代码Review的时候,语法与规则的检查,通过Check Style的工具进行;开发人员将审查的重点放在功能实现与性能优化等方面。
测试:在需求文档形成以后,2个测试人员分布编写分配模块的Test Case;而在具体测试的时候,两人交叉测试对方的模块和更新文档。
在系统开发Verification的各个阶段,都有Check List,详细的信息请查看参考文献[3]。
测试先行:测试在软件开发中的重要作用已经得到了越来越多的重视,但是,由于习惯势力的影响和对于"Test-Driven Development"的不熟悉,开发小组并没有实施完全意义上的测试先行。
对于系统框架的核心类设计过程中,项目小组采取了TDD的方式进行开发。在后续的系统开发中,每个开发人员在进行开发前,首先要完成一个功能测试 ( Function Test ) 列表,将要完成的Use Case中的主要业务逻辑以及关联逻辑都要罗列出来,在提交测试人员进行集成测试之前,开发人员需要保证完成Function List中的所有选项。
在每个开发人员的模块完成并通过个人的功能测试后,测试人员进行集成测试,同时编写测试脚本,并通过自动测试工具 (Rational Robot) 进行记录。每天下班之前,测试人员会启动测试工具,进行回归测试。在第二天向PM和技术经理提交测试报告并将Bug提交至Bug Trace系统(Rational Clear Quest),由PM进行Bug的分发。每个开发人员需要在下一个迭代周期完成前,修正前一个迭代内分配的Bug。
持续集成:在测试先行的基础上,开发一组平均每天都会进行已经完成模块与以后系统的集成。集成由专门的人员,在开发人员将已经通过功能测试的源码Check in到源码控制系统 (ClearCase) 中以后进行,在部署应用结束以后,通知测试人员进行集成测试。
小步发布:项目有专门的测试与发布服务器,每天都有集成的系统在运行和接受测试。由于没有现场客户,对于已经发布的系统,是由"客户领域专家"(这个项目是由Business Development人员来充当这个角色)来进行审查的。他对于系统的意见和发现的问题,在经过PM和技术经理审核后,进入ClearQuest,分配给开发人员进行修改。
由于项目一开始就注意组织内部以及与客户的沟通和交流,同时采用了很多敏捷软件开发过程的实践,项目如期交付使用。
3.2 教训
项目在交付以后,最初的两个订货季节没有出现功能与性能上的问题。但是,由于合同中有数据迁移的条款,在项目交付2月后,项目开发商将旧应用系统中的数据导入新系统以后,在下一个大的订货季节中,持续的出现性能上的问题。在代码修改和硬件环境提高以后,系统性能目前获得了一定的改善。
从项目验收日期的日益推迟中,我们可以看出,该项目还是有很多地方做的不够,例如:系统二次开发效应:"第二个系统效应"是Brooks在《人月神话》中提出的一个普遍的问题,一般而言,第二个系统会倾向于过分设计[4]。对于这个项目而言,没有犯这个错误,却发生了另外一种情况:旧系统中,对于订单信息以及产品信息的展示,不管是多是少(系统页面最多显示上千条记录),都是在一个页面中显示。这对于没有明显的层次结构,直接在Script中调用数据库记录的PHP来说,性能还是可以接受的。但是,新系统的设计中客户提出考虑系统用户习惯一致性的问题,就照搬了旧系统的页面设计;同时,在架构设计上,对于这种页面显示大量数据的情况,也没有给予充分的考虑,为后来的性能问题,埋下了伏笔。
教训一:没有考虑新平台的影响,照搬旧系统的功能以及页面设计。
非功能性需求:项目合同中主要描述的是系统功能性的需求,而没有非功能性需求的规定;同时,在需求获取解决,也没有明确的了解系统的性能指标等非功能性需求。主要原因在于项目开发商之前没有大规模业务系统开发的经验,对于非功能性需求没有足够的重视;同时,在测试阶段,也没有对于系统负载和性能做过测试。
因此,在项目交付以后,由于旧系统数据迁移后,数据量有了很大的增长,同时,在秋季的定购高峰中,有大量的并发用户访问,出现了下列问题:
数据库死锁;
大量数据计算与显示页面速度很慢,页面要经过5~10分钟才能够完全显示;上述两种情况在少量负载的单元测试和集成测试中是不可能出现的。
教训二:对于企业应用系统,尤其是业务系统,没有切实注意负载、性能等非功能性需求。
效率与设计:在J2EE中,已经成功的运用了很多设计模式的思想,为系统的开发提供了一个很好框架。但是,在项目的架构设计中,除了考虑可维护性、可复用性等问题以外,还要考虑代码执行效率的问题[5]。
随着计算机硬件技术的发展,"莫尔定律"被一再的验证,系统硬件的价格逐渐降低。对于很多使用J2EE架构或者JAVA技术的项目来说,解决性能与效率问题的解决方案就是增加硬件方面的投入。而实际上,软件开发过程中优劣算法之间的差是靠硬件的投入平衡不了的。
该项目在系统维护期间,对代码进行走查,修改了很多对于性能有影响的语句;同时,在框架设计中,尤其是数据库操作方法,利用Cache原理,从一定程度上解决了性能的问题。
教训三:系统框架设计只考虑面向对象和可维护性,没有在完美的设计与高效率的代码之间做出权衡。
数据库设计:JAVA是纯粹的面向对象语言,利用J2EE开发的项目,也强调首先进行OOAD的分析,首先有对象,然后再有数据库的设计。DBA在项目中的作用,已经远远没有传统的结构性编程中重要。而实际情况却是远非如此:大部分的业务系统,如果要对系统的性能做出优化,对数据库层或者SQL语句进行优化是关键的步骤之一。
对于这个PRM系统,在数据库的设计上并没有经过DBA的审查就开始进行开发;而在性能问题出现以后,客户增加了512M的内存,也没有请求DBA对Oracle的参数做相应的调整,造成了很大的资源浪费。
在项目维护过程中,依靠DBA的帮助,开发商对于数据库系统参数、索引、存储过程和SQL语句都做了一定的调整,这对于系统性能的提高起了很大的作用。
教训四:在面向对象的软件系统构建中,忽视数据库设计以及DBA的重要作用。
客户参与:在传统的软件开发过程中,一般情况下,客户在签订合同后,项目交付前是很少有机会看到系统的,这样就造成了系统交付后,客户抱怨很多的情况;而在以XP为代表的敏捷软件开发方法中,强化了客户在软件开发中的重要作用,XP更是提出了"现场客户"的实践,将客户作为项目小组的一员,客户对于项目的发布计划、内容和优先级等方面有绝对的控制权。
对于这个PRM项目,由于客户的原因,不可能采取"现场客户"的实践,但是,开发商的BD对于该客户十分熟悉,完全可以作为客户代表参与到项目中来,因此,开发商将客户经理作为项目组的一员。
实际情况是:开发过程中,客户经理由于业务拓展的原因,并没有在项目上分配多少时间进行审查;而客户在交付前也没有花费很多的时间研究系统,也没有提交很多的反馈报告。在系统交付出现性能等问题后,客户经理与开发人员一起对于系统需求进行审查,提出了很多有参考性的意见。如果从一开始,就强化"现场客户"的最佳实践,就可以很早发现问题。
教训五:客户或者客户经理对于项目的参与力度不够。
四、 结论
在基于J2EE的企业应用项目开发中,要注意以下问题:
权衡系统设计与性能指标,关注非功能性需求;
采取敏捷软件开发过程,关注人(客户和开发人员)在项目实施中的重要作用,如果可以的话,联合实施XP的所有实践; 。
怎样理解这种说法呢?
首先,测试并不仅仅是为了要找出错误。分析错误产生的原因和错误在开发的哪一个阶段产生,具有非常重要的意义。
通过分析错误的原因,我们可以立即在开发行动中对其进行改正。同时,这种分析也能帮助我们推理出 与所分析的错误有关联的潜在错误,从而有针对性地设计出检测的方法。
通过分析错误产生于哪一个开发阶段、而又在哪一个阶段被发现,我们可以判断从错误的产生到错误的发现,跨越了多少个开发阶段。软件开发的一条重要原则是尽早发现与修正错误。(当然,更高的一条原则是尽量预防错误的出现。)一个错误能够超越本开发阶段而不被发现,就指明了该开发阶段的检测手段有缺陷,从而也不难有针对性地制定出加强的措施与办法。这也就是软件过程改进的一项重要内容。如果能做到在同一开发阶段发现及修正错误,该开发机构就可以预期有一个高质量的产品及一个低成本、高效率的软件过程。
有些项目的主持人,认为以尽快的速度把测试之前的所有开发阶段完成(实际并没有完成),早日开始测试,以图达到快速和高质量(因为似乎有更长的时间可用于测试)。实际的效果将会是俗语所说的“欲速不达”。从常识就可以知道,花开发时间去继续扩大发展前面阶段引入的错误,得出的只能是更大量的需要耗时修正的错误。
因此,正确分析与利用测试的结果,我们可以非常有效地进行软件过程改进。
软件开发全过程检测,力争本阶段修正错误
从上面的讨论,我们很自然的就能领会到,软件错误的发现绝不能等到测试才开始(按常规,最早的测试就是编码后的单元测试)。因此,笔者提出一个软件工程的守则:软件开发全过程检测,力争本阶段修正错误。单元测试是在软件开发的“实现阶段” 才开始的,在此之前的“可行性研究与计划阶段”,“需求分析阶段”,“概要设计阶段”,和“详细设计阶段”,都必须有非常明确切实的手段与措施对开发结果进行检验,以保证阶段的正确完成。
怎样判断一个软件过程的优劣,怎样进行软件过程改进,都可以在这个守则的指导下进行。这个守则是简单明确的,但因企业背景、条件的不同,开发环境条件的不同,项目产品的不同,实际的软件过程的实现方法就会变化无穷。考虑实现这个原则的方法的时候,可以尽量多参考各种理论及经验,但在选择制定本企业开发实践中使用的软件过程时,就必须处处根据是否能给自身的项目带来好处,以及自身的条件进行考虑。千万不要仅仅为了满足某个“标准”的提法而做一些无实际意义的工作。要尽量避免烦琐,争取做到简单、有条理和有最大的效果。
软件测试的工作量很大(据统计,会用到40% 的开发时间;一些可靠性要求非常高的软件,测试时间甚至占到总开发时间的60% ),但测试却是在整个软件过程中极有可能应用计算机进行自动化的工作,原因是测试的许多操作是重复性的、非智力创造性的、需求细致注意力的工作。计算机就最适合于代替人类去完成这些任务。企业在这方面的投资,会对整个开发工作的质量、成本、和周期带来非常明显的效果。一些适于考虑进行自动化的测试操作为:
1.测试个案的生成(包括测试输入,标准输出,测试操作指令等)。
2.测试的执行写控制(包括单机与网络多机分布运行;夜间及假日运行。测试个案调用控制;测试对象、范围、版本控制等。)。
3.测试结果与标准输出的对比。
4.不吻合的测试结果的分析、记录、分类、和通报。
5.总测试状况的统计,报表的产生。
测试自动化与软件配置管理是密不可分的。与测试有关的资源都应在配置管理中进行统一的计划考虑。另外,测试工具的采用也是一个提高质量的关键,有些专用的测试 工具能帮助发现一些用任何测试个案都难以触及的错误。?
总的来说,基本的测试还是和神马那里的单元测试比较类似,问题在于web测试的页面输入问题不知道有没有什么好的测试工具能代替,也许基于structs的框架里有吧?