初步关注点.docx
- 文档编号:15322564
- 上传时间:2023-07-03
- 格式:DOCX
- 页数:19
- 大小:48.26KB
初步关注点.docx
《初步关注点.docx》由会员分享,可在线阅读,更多相关《初步关注点.docx(19页珍藏版)》请在冰点文库上搜索。
初步关注点
10
第章
初步关注点
“软件错误(softwarebug)”是一个常见术语,甚至计算机初级用户都知道是一种软件应用程序的缺陷(defect)或瑕疵。
软件用户已开始习惯于寻找软件中的问题。
有些问题有相应的解决办法而且并不严重,然而其他可能相当麻烦,并且在某些情况下代价很高。
令人遗憾的是,作为用户,我们已能够预计软件中的这些问题。
然而,近年来由于在将软件发布给用户之前,软件团队耗费了无数的时间查明并消除这些问题,因而软件质量普遍有所提高。
查明这些错误的过程则称为测试。
当前有许多用于Web应用程序的不同测试方法,其中包括应用程序功能、安全性、负载/压力、一致性和可访问性测试。
如果您初次涉足测试领域,不用担心:
本书将解释基本概念,并针对测试学科的每种类型引导您了解应当采取的正确行动。
如果您已拥有测试应用程序的经验,那么本书将指明ASP.NET系列的重要领域,并将其与正确的方法和可用的工具配对,以便能成功地测试Web应用程序。
本书并非针对任何特定测试类型的权威指导,而是针对Web测试学科的各种类型给出一个全面的概述。
它旨在让您使用最佳实践及测试工具,并为您提供用于掌握特定测试学科所需的资源。
作为作者,我们的目的是帮助读者,引导他们定位到本书的具体章节,学习在开发基于Web的应用程序的任何时间点应当进行什么测试以及如何进行测试。
尽管现有的书籍深入涵盖了不同的测试学科,然而本书却是独一无二的,因为它将当前最好的测试方法应用到了ASP.NET系列中,其中包括WebForm、ASP.NETMVCFramework、Web服务、Ajax、Sliverlight,以及ADO.NETDataServices,从而确保了读者能够测试当今有关的重要技术。
1.1测试工具的历史
当开发人员开始编写代码时,测试工具就开始出现了。
但是,在软件开发的最初几年,测试与调试之间并没有明确的界限。
在当时,这种模式是有效的。
有些人认为,之所以这种模式是有效的,是因为系统本身是封闭的;大部分需要软件的公司都拥有用于创建和维护系统的开发人员。
当时计算机系统并不十分普遍,开发人员与客户密切合作,以提供他们需要的确切功能。
而在之后的1970~1995年间,计算机系统才开始变得流行起来,然而开发人员和客户却开始疏远,通常在他们之间安插了几个管理层次。
您也许会问,调试和测试有什么不同?
测试是寻找软件缺陷的过程。
缺陷可能是一项缺失的功能,或者一项并没有充分执行的功能,或者一项受到破坏的功能。
调试是跟踪软件中的错误,而后修复该错误的过程。
大部分开发人员早期用于测试的工具都是针对特定项目开发的内部工具,通常无法重用。
之后,开发人员开始意识到有必要创建包含了他们很早就学到的多种模式的可重用工具。
出于这一认识,测试方法学逐渐演变,测试工具开始趋于标准化。
近年来,测试方法学已成为独立的、非常严格的计算机科学学科。
在过去的12年中,已开发出许多工具,它们使测试变得更加容易。
然而,在深入学习当前工具集之前,了解过去并学习之前的工具是非常必要的。
值得注意的一点是,工具是随着过程的演变而逐渐演变的。
海军上将GraceMurrayHopper使“调试”一词得以流行,1945年8月,当时她正在哈佛大学的MarkII型计算机上工作。
当她的同事们发现了一只飞蛾困在继电器中,并意识到这正造成系统问题,Grace对外界表示她们当时正在“调试系统”。
sUnit测试架构
通常说模仿是最真诚的奉承方式;也就是,最现代的单元测试架构就来源于最初由KentBeck于1998年开发的sUnit测试架构所阐述的主体结构。
以下只是一小部分以Beck最初的概念为基础所构建的架构。
●sUnit——KentBeck为SmallTalk所创建的sUnit已被称为“测试架构之母”。
许多主流单元测试架构(如jUnit和nUnit)都是sUnit的端口。
sUnit测试架构中的重要概念起初发表于KentBeck’sGuidetoBetterSmalltalk(剑桥大学出版社,1998)一书的第30章中。
●jUnit——1998年年底KentBeck和ErichGamma为Java创建的sUnit端口。
jUnit促使自动单元测试成为主流趋势。
●nUnit——在2000年年底,所有有关jUnit的重要事物均被移植到.NET中,从而允许C#开发人员针对C#代码编写jUnit风格的单元测试。
●qUnit——这是针对jQuery架构的单元测试。
2008年5月,qUnit上升为jQuery项目中的顶级应用程序。
它允许Web开发人员在JavaScript上运行单元测试。
●WCAT——Web容量分析工具(WebCapacityAnalysisTool,WCAT),它于1998年最先收录到IIS4资源工具包中,并且是一个免费发布的命令行工具。
它允许服务器配置代理,从而在网站上执行负载/压力测试。
●Web应用程序压力工具(WebApplicationStressTool)——微软于1999年发布了一个免费工具,用于创建用户图形界面浏览器的压力测试。
这一工具记录一次浏览器会话并将行为编写为可修改的VisualBasic6脚本文件。
由于该工具能生成可修改的脚本文件,很多Web开发人员不仅使用此工具进行压力测试,还利用其修改脚本用于用户界面的功能测试。
●微软应用程序中心测试(MicrosoftApplicationCenterTest)——VisualStudio2001企业版中包含的微软ACT改进了Web应用程序压力工具。
它提供了一个架构(schema),测试可以按这种架构分布于各个代理之间以便进行大规模负载测试。
●集成测试架构(FrameworkforIntegratedTest,FIT)——由WardCunninham于2002年创建的FIT是一个自动化客户测试工具。
由客户提供软件如何执行的示例,并由开发人员创建了自动化测试装置。
FIT旨在促成开发人员、客户、测试和分析员的工作整合。
●Fitnesse——于2006年被DavidChelimsky和MikeStockdale移植到.NET平台上的Fitnesse将一台Web服务器、Wiki以及FIT软件验收测试架构结合在一起。
由此提供了一种验收测试架构,它允许用户定义输入,并且该输入可以由允许非技术用户编写测试的测试装置进行解析。
●Watir——2002年5月,发布了应用于RubyWatir(发音同“Water”)的Web应用程序测试。
这是用Ruby语言编写的一个自动化浏览器验收测试库。
●Selenium——Selenium提供了一套用于Web应用程序自动化用户界面测试的工具。
2004年,Thoughtworks软件技术咨询公司的JasonHuggins为自动化测试的时间和资费系统创建了核心“JavaScript测试运行器”模式。
●WatiN——2006年5月,Watir这一主流浏览器验收测试架构作为WatiN(发音同“Wattin”)项目被移植到.NET平台上。
●VisualStudio2005测试版(VisualStudio2005TestEdition)——2005年,微软发布了一款VisualStudio版本,其中包括了一个由微软称之为MS测试(MSTest)所开发的新的单元测试架构。
除了这一新单元测试架构以外,之前被称之为微软应用程序中心测试(MicrosoftApplicationCenterTest,微软ACT)的工具作为Web单元测试和Web负载测试也被集成到这一VisualStudio版本中。
●VisualStudio2008专业版——2008年,VisualStudio2008的专业版收录到MS测试中。
1.2测试术语
如同编程领域的许多不同方面一样,测试学科拥有自身特有的词汇。
然而,由于术语的数量很多,入门门槛较高可能令新开发人员望而生畏。
本节旨在让读者快速学到一些将会在本书其余章节中使用的常用术语。
以下给出的术语仅提供一个简短说明。
后续章节将对其进行充分讨论。
●测试(Test)——测试是一个用于确保应用程序的某个具体单元正常运作的系统程序。
●成功(Pass)——成功表明一切正常运作。
如果在报告或用户界面(UI)中,它表示为绿色。
●失败(Fail)——在失败的情况下,被测试的功能已被更改,因此不再按预期运作。
如果在报告中,它就为红色。
●xUnit——xUnit是指最初从sUnit移植而来的各种测试架构。
例如,jUnit、qUnit以及nUnit等工具都被归入xUnit系列。
●测试装置(TestFixture)——测试装置是指在测试能够运行之前,测试必须处于的状态。
在运行测试前,测试装置需准备好该测试所需要的所有对象。
装置确保了测试在一个已知的、可重复的状态下运行。
●测试驱动开发(TestDrivenDevelopment,TDD)——测试驱动开发是一个敏捷软件开发过程。
在这个过程中,在编写代码之前就创建某个过程的测试。
●行为驱动开发(BehaviorDrivenDevelopment,BDD)——基于TDD基本原理所构建的BDD旨在利用TDD在设计和文档方面的更多优势,为客户和业务提供更多的价值。
●测试替身(TestDouble)——当在单元测试中无法使用或选择不使用实际组件的情况下,用于替代实际组件的对象被称为测试替身。
●存根(Stub)——测试存根是一种具体类型的测试替身。
在需要复制对象和控制输出的时候,就可以使用存根,然而它并不对任何与存根对象进行的交互行为实施正确性验证。
当前存在许多种类型的存根,如响应、破坏、临时、过程和实体链等类型的正确性,这些将在第2章中深入探讨。
●模拟(Mock)——模拟对象也是一种测试替身的形式,与存根对象运作方式类似。
它常用于模拟一个复杂对象的行为。
而与存根对象不同的是,每个与模拟对象进行的交互行为都需要经过正确性验证。
第2章将会深入探讨模拟对象。
●伪造(Fake)——伪造对象仍然也是一种测试替身类型。
它类似于测试存根,但自身实现并替代了部分功能,从而使得方法的测试变得更加容易。
●虚拟对象(DummyObjects)——当方法需要对象作为其方法或构造函数的时候,即可以使用虚拟对象。
然而,在这种情况下,该对象从未被测试代码使用。
因此,虚拟对象通常是空的。
●单元测试(UnitTest)——单元测试是用于测试小单元源代码正常运行的方法。
单元测试应当独立于外部资源,如数据库和文件等。
一个单元通常被认为是一个方法。
●开发测试(DeveloperTest)——这是单元测试的另一种说法。
●集成测试(IntegrationTest)——它类似于单元测试。
然而,它不是一个孤立单元,而是进行跨应用程序界限和系统界限的测试。
●功能测试(FunctionalTest)——功能测试将工作单元组合到一起,共同测试一个外部需求。
像图形用户界面测试和性能测试这些测试学科均被视为功能测试。
●图形用户界面测试(GUITest)——GUI测试是图形用户界面的测试。
这一测试也被认为是功能测试。
应用程序用来模拟用户与系统的交互行为,如向文本框输入文本或者单击一个按钮。
而后,根据用户界面或系统的响应进行验证。
●客户测试(CustomerTest)——这是验收测试的另一种说法。
●系统测试(SystemTest)——系统测试一词是一个用于表示系统的“端到端”测试的术语。
系统测试包含单元测试、安全测试、图形用户界面测试、功能测试、验收测试和可访问性测试。
●负载测试(LoadTest)——将大量链接连接到该网站,用以判断它是否能够正确扩展。
此类测试是用于确保网站在生产使用中能够处理预期的负载高峰,而不出现任何错误或失败。
●压力测试(StressTest)——这是负载测试的另一个名称。
●性能测试(PerformanceTest)——性能测试用于测试正常运作,处于负载以内的系统响应。
一种常用的Web应用程序性能衡量标准是首字节平均响应时间(TimeToFirstByte,TTFB)和每秒处理请求数(RequestsPerSecond,RPS)。
●验收测试(AcceptanceTest)——这是用于表明软件项目的某项功能是否符合客户期望规格的正规测试。
●黑盒测试(BlackBoxTest)——黑盒测试是在不了解正在测试的功能的内部工作原理的情况下而创建的测试。
该测试需要依据的唯一信息就是需求。
●白盒测试(WhiteBoxTest)——白盒测试是在已经了解测试的代码的内部工作原理的情况下创建的测试。
利用对系统内部的认识,可以调整输入,以确保较高的测试覆盖率和系统正确性。
●回归测试(RegressionTest)——回归测试用于确保现有的功能之前正常工作,并当前仍然正常工作。
1.3测试误区
一些开发人员经常需要向其经理解释创建软件所采用的每一步开发实践和每一种工具,而后由这位经理判断是否慎重使用了这些实践做法或工具。
这些经理往往是已被提拔的开发人员,而他们的重点已不再是软件开发而是管理。
以往的开发人员并不是总能成为最佳经理。
很多情况下,他们没有提升自身的开发技巧,而且有时仅仅因为不是他们的做事方式而否决新技术和新工具的使用。
这些情况确实没有意义,而且开发人员常常很难处理,尤其对于非常渴望学习最新、最好技术的初级开发人员。
虽然单元测试架构已引领主流近10年时间,但仍然有许多经理与要求实施单元测试架构的开发人员发生争论。
本节围绕测试探讨了一些较为常见的误区,并尝试向那些在其机构中实施大量测试的过程中遇到问题的开发人员提供建议。
1.3.1测试是昂贵的
FrederickBrooks在其文集《人月神话》中提到:
“要解决实际使用中发现的错误的成本,很可能比解决开发过程中所发现错误的成本高出1000倍。
”
“测试是昂贵的”——如果这是您的经理所使用的一个理由,那么请创建一个测试来验证含有错误的方法的功能,并在错误再次发生时使用这一测试——并记录您的时间。
然后由您自己写好如何修正这一错误,并再次记录您的时间。
在大多数情况下,您会发现编写某项功能的测试只需要几分钟时间,那么现在,您对经理的辩驳可以是:
“假使允许我花费长度为X的测试时间去创建测试,那么客户就不会遇到这样的错误了。
”如果您做这些事的原因拥有数据支撑,那么大多数经理将会对这一请求更加关注。
如果一直为系统编写测试,那么随着时间的推移,就会形成一套完整的测试案例集合。
而后,这些测试案例可以在系统开发过程中予以执行,并使得在这一过程中能够更早地发现回归错误。
利用测试捕获这些错误,将在重复测试应用程序和生产中维护系统方面节省时间和金钱。
1.3.2只有初级开发人员应该创建测试
这一说法完全不符合事实。
编写测试对初级开发人员与高级开发人员都十分重要。
这一说法往往是经理用来让一个初级开发人员在项目中仅仅从事于创建一堆测试计划的借口。
然而,由于缺乏培训和指导,初级开发人员所创建的测试计划和自动化测试往往是没有用的。
因此,高级开发人员应当与初级开发人员紧密合作,并指导他们如何创建好的测试,这一过程十分重要。
测试很容易,而好的测试却是困难的。
很难仅仅从书本中学到如何编写好的测试,如何创建测试计划。
书本仅仅是用来帮助学习概念,但完全无法同经验丰富的开发人员坐在一起结对编程一整天的成效相媲美。
如果您是高级开发人员并且意识到了这一点,那么请根据自身情况帮助培养那些初级开发人员。
向经理提出请求,是否让您负责一部分测试,并针对这一过程帮助培养初级开发人员。
从长远来看,这将使您的工作更加简单,因为这样在团队中就能够拥有多个人员,以便很好地执行任务。
如果您是一名初级开发人员,您的工作最终就是您的责任。
您应当向经理提出请求,要求一名高级开发人员与您一起合作完成部分测试。
如果经理不同意,那么请根据自身情况,针对执行任务所需的技能进行培训。
从阅读尽可能多的测试开始,而后尝试参加一个本地用户群组。
这种本地用户群组往往会举行“黑客之夜”。
在这一天,他们会聚在一起编写代码,能够让您与同伴一同学习。
1.3.3不能为遗留代码创建测试
虽然测试遗留代码往往比较困难,但也不是不可能的。
通常,遗留代码并没按照能够创建单元测试的方式进行体系结构设计。
但在大多数场景下,可以为它们创建功能测试或验收测试。
在过去几年中,出现了许多令测试遗留代码变得容易得多的模式。
在测试领域中,不包含任何测试的代码库通常被认为是遗留代码。
这意味着,如果您编写代码时没有写测试,那么您正在做的所有事从一开始只不过是创建遗留代码。
这个误区一般只是那些没有学过测试模式的经理的另一个借口。
为遗留代码编写测试是一个很好的想法。
通常情况是,原本编写代码的开发人员已经离开,无法再继续维护这一应用程序,那么为这一应用程序创建一套测试套件将有助于新的开发人员了解这一应用程序,并为其他开发人员提供一个安全网(如果他们在将来需要修改这一应用程序)。
1.3.4测试仅仅用于敏捷软件开发
单元测试和测试驱动开发是XP和许多其他敏捷软件开发方法论的基本过程。
仅仅因为一个过程使用了很好的工具,并不能意味着它就不适合对应过程。
如果您的经理不喜欢敏捷这个词,那么不要将创建单元测试的做法称作为敏捷过程,仅仅称之为单元测试。
作为一个Web开发人员,您可能会熟悉LorenIpsum。
LoremIpsum被用作文本占位符。
它来自于西塞罗的拉丁著作DeFinibusBonorumetMalorum。
其本身是没有任何意义的,因为客户关注的往往是文本内容,而不是文本的布局。
向您的经理使用这一手法。
由于缺乏认识或误解敏捷过程如何运作,因此一些经理并不熟悉敏捷过程。
1.3.5必须在编写代码之前创建测试
第3章将概述测试驱动开发(TestDrivenDevelopment,TDD)这一过程。
到目前为止,关于它您所需要了解的是,这是一个在编写某项功能的代码之前就已为其创建单元测试的过程。
对于纯粹的测试驱动开发人员,这并不是一个误区,必须在代码创建之前就创建测试。
对于那些初涉测试的人,测试驱动开发可能比较难。
在开发人员考虑步入测试驱动开发之前,他们应当先学习如何创建一个好的单元测试。
第4章将探讨如何创建一个好的测试,并分析单元测试和测试驱动开发。
●维护测试很难。
从开始为代码创建测试起,测试套件往往就会变得相当庞大,难以控制。
如果您的测试编写得比较蹩脚,那么它们将同其他代码那样难以维护。
通过本书中描述的正确体系结构以及正确考虑因素,就会发现测试和整个系统更加易于维护。
拥有一个能够全面测试应用程序的大型测试套件是一项投资。
说服您的经理拥有一套能够全面测试应用程序的测试套件非常重要。
这是一名开发人员应做的工作。
●无法自动化用户界面代码。
在过去,编写代码来自动生成用户界面代码一直非常困难。
然而(如MS测试的Web测试和WatiN等工具)却使得自动化用户界面测试成为可能。
假如一位经理说自动化用户界面测试是不可能的,那么只要向他们指出这些工具。
尽管需要注意这些自动化用户界面测试往往比较脆弱,需要耗费比单元测试更多的时间用于维护。
第5章将进一步探索自动化用户界面测试。
具备了正确的知识而且恰当的时间,自动化用户界面测试就能够实现。
●单元测试消除了手动测试的需要。
尽管单元测试将成为系统的宝贵资源,但它们本身并不能取代系统还需要手动测试的需要。
单元测试验证孤立的程序块,但还必须确保系统作为一个整体是有效的。
手动测试包含了确保在一切都正确部署的情况下,系统按照预期运行。
在手动测试系统时,不但可以确保界面渲染是正确的,而且能够验证应用程序和用户界面均实际可用。
尽管您能自动化应用程序的不同部分,但还不可能自动地使得最终用户理解,并且易于使用应用程序。
而这是一个非常重要的阶段,必须手动执行。
假如没有这一阶段,即使您能够创建一个完美运作的应用程序,但是,最终用户可能永远都无法使用它,因为他们根本不明白其布局和进程。
●单元测试是最新的发展潮流。
在过去两年中,测试已成为一个十分热门的主题,每过几天都有新的博客标榜着“专家”来鼓吹,如果您不编写测试,您编写的就是伪劣代码。
随着知名度迅速提升,也可以理解为什么有人会认为这种开发实践是一种潮流。
然而这完全不符合事实,因为当今推广的许多概念都来源于许多年前。
像“测试是昂贵的”这一误区一样,大多数经理会听从事实。
收集事实并给出测试之所以重要的充分理由。
在大多数情况下,如果有人正告诉您由于您没有进行一定的测试开发实践,因此您所编写的代码是拙劣的,那么您不应当盲目地相信这个人。
真正的专家明白为什么测试如此重要,他们不会强行向您推销测试。
他们明白为什么编写的有些代码没有测试,而且如果您愿意,他们将引导您向正确的方向前进。
●开发人员只需要编写单元测试。
使用单元测试相当有用,因为它们有助于您设计可测试的代码,并且在进行结构变化时,这些测试能起到安全网的作用。
但是,不应当认为它们能够替代集成测试、功能测试和验收测试。
当一名测试人员/开发人员了解到每种测试类型的目的之后,就不会认为只需要单元测试了。
如果有人这么说,那么可以认为他们并没有充分理解单元测试、功能测试和验收测试之间的不同点。
请向他们解释这些不同点,各种类型的测试是什么,以及它们各自的应用领域。
●测试很容易。
虽然创建测试非常容易,但创建有意义的测试却是另外一件事。
就像在您职业生涯中所学的许多其他科目那样,构建良好测试的能力会随着时间和经验的推移而累积。
学习如何创建好测试的最佳方法之一是与拥有创建测试经验的开发人员结对编程。
对于结对编程有许多种流派:
它是什么,以及如何最好地执行这一软件开发的方法。
我发现的自认为最好的方法是,与另一名软件开发人员使用两台显示器、两个键盘和两只相连鼠标在同一工作站上共同工作。
一名开发人员编写测试,而另一名开发人员实现能够使测试成功的代码。
如果一名开发人员不同意另一名开发人员正试图完成的工作,那么他们都能够控制工作站,并说明其各自的理由。
面对面工作时,沟通效果最好。
对于创建测试是一个很好的做法这一点,如果您已经说服了您的经理,那么让您说服他们,您需要学习如何创建良好的测试应该不是非常困难。
2.5.11节介绍如何构建良好的测试。
此外,还有许多由一流培训师开办的培训课程能够在这一领域给予您指导。
1.4迭代过程
您是否在只对员工进行年度绩效评定的公司工作过?
我相信,大多数开发人员都有过如此经历。
另外,在年度评定中您是否遇到过一个经理对您说,“在2008年6月13日,您忘了关闭Kanooter值,而且此后的每个星期五您都没有关掉它!
”或者类似的话?
作者相信许多开发人员都遇到过这种情形。
如果经理曾经指出您做错了什么,您可能会及时采取措施来纠正这一问题。
软件开发也发生着与此相同的范例。
项目经理花费了大量时间与客户合作,为的是准确定义应当完成什么样的一套软件。
然而,通常发现,当项目经理完成应用程序的需求收集之后,客户直到开发“完成”,才会再次看到这一应用程序。
这也就是为什么许多软件项目失败的原因。
在过去的几年中,敏捷软件开发过程深受开发人员的青睐。
那是因为,敏捷软件过程的关键原则之一就是迭代开发。
迭代开发将新功能的开发分类组合起来,并每次向客户提供项目的一小块,而并不是等待很长时间后提供一个非常庞大的整体系统。
敏捷团队试图保持较短的迭代周期,也许两个星期到一个月。
而且在每个迭代期结束时,他们总有能够展示的成果。
有些人把敏捷开发的成果归结于较短的迭代周期,以及与客户之间的不断沟通。
敏捷开发人员和经理经常会谈到降低变更的成本。
关于变更的成本,简单来说是这样的:
找出缺陷的时间越长
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 初步 关注点