2005年11月07日
软件测试实践
之测试环境的规划与管理
只有稳定,才能有发展。
——邓小平:《振兴中华民族》(1990年1月7日)《邓小平文选》第三卷第357页
中国要实现自己的发展目标,必不可少的条件是安定的国内环境与和平的国际环境。
——邓小平:《中国永远不允许别国干涉内政》〈1990年7月11日〉,《邓小平文选》第三卷第360-361页
 
测试环境 是指为了完成软件测试工作所必需的计算机硬件、软件、网络设备、历史数据的总称。毫无疑问,稳定和可控的测试环境,可以使测试人员花费较少的时间就完成测试用例的执行,也无需为测试用例、测试过程的维护花费额外的时间,并且可以保证每一个被提交的缺陷都可以在任何时候被准确的重现。
简单的说,经过良好规划和管理的测试环境,可以尽可能的减少环境的变动对测试工作的不利影响,并可以对测试工作的效率和质量的提高产生积极的作用。
 
一、规划测试环境——让环境为你服务
 
对于“金山词霸”这样的软件,大多数测试工作都可以在一台单独的电脑上完成,而对于一套电信系统,为了执行测试用例,你可能会需要搭建一个由多台计算机以及其他网络设备组成,采用集群和负载均衡技术,并且接驳到Internet的计算机网络。
不同的行业应用,不同的质量目标,都可能会影响到测试环境的规划。但从测试工作自身的要求来看,一条应当遵守的原则就是“尽可能的还原软件在用户那里最终实际运行的环境”——虽然在很多时候这是不现实的。^_^
通常来说,我们所需要搭建的环境,主要是用于被测应用的系统测试——单元测试和集成测试由开发人员在开发环境中进行,而验收测试则在用户的最终应用环境中进行,因此都可以暂不考虑。
为了确定测试环境的组成,我们需要明确以下问题:
1.         所需要的计算机的数量,以及对每台计算机的硬件配置要求,包括CPU的速度、内存和硬盘的容量、网卡所支持的速度、打印机的型号等;
2.         部署被测应用的服务器所必需的操作系统、数据库管理系统、中间件、WEB服务器以及其他必需组件的名称、版本,以及所要用到的相关补丁的版本;
3.         用来保存各种测试工作中生成的文档和数据的服务器所必需的操作系统、数据库管理系统、中间件、WEB服务器以及其他必需组件的名称、版本,以及所要用到的相关补丁的版本;
4.         用来执行测试工作的计算机所必需的操作系统、数据库管理系统、中间件、WEB服务器以及其他必需组件的名称、版本,以及所要用到的相关补丁的版本;
5.         是否需要专门的计算机用于被测应用的服务器环境和测试管理服务器的环境的备份;
6.         测试中所需要使用的网络环境。例如,如果测试结果同接入Internet的线路的稳定性有关,那么应该考虑为测试环境租用单独的线路;如果测试结果与局域网内的网络速度有关,那么应该保证计算机的网卡、网线以及用到的集线器、交换机都不会成为瓶颈;
7.         执行测试工作所需要使用的文档编写工具、测试管理系统、性能测试工具、缺陷跟踪管理系统等软件的名称、版本、License数量,以及所要用到的相关补丁的版本。对于性能测试工具,则还应当特别关注所选择的工具是否支持被测应用所使用的协议;
8.         为了执行测试用例,所需要初始化的各项数据,例如登陆被测应用所需的用户名和访问权限,或其他基础资料、业务资料;对于性能测试,还应当特别考虑执行测试场景前应当满足的历史数据量。当然,还有另外一个非常关键的问题:在测试过程中受到影响的数据如何恢复?
    明确了上面的问题后,明确哪些条件是可以满足的,哪些是需要其他部门协助调配、采购或者支援的。建议在搭建测试环境之前,把上面的问题做成一张CheckList,并为每一项指定一个责任人,完成一项就填写一项,最终形成的文档则作为测试环境的配置说明文档使用。当然,如果时间或其他条件允许,应当做好应急预案,尽量保证在环境失效时不会对正常工作产生太大的影响。
 
二、管理测试环境——把变化掌握在手中
 
    测试环境搭建好以后不太可能永远不发生变化,至少被测应用的每次版本发布都会对测试环境产生或多或少的影响。而应对变化之道,不是禁止变化,而是“把变化掌握在手中”。下面的这些建议可以帮助你尽可能摆脱环境变化所带来的不利影响。
1.         设置专门的测试环境管理员角色
每个测试项目或测试小组都应当配备一名专门的测试环境管理员,其职责包括:
ü         测试环境的搭建。包括操作系统、数据库、中间件、WEB服务器等必须软件的安装,配置,并做好各项安装、配置手册的编写;
ü         记录组成测试环境的各台机器的硬件配置、IP地址、端口配置、机器的具体用途,以及当前网络环境的情况;
ü         完成被测应用的部署,并做好发布文档的编写;
ü         测试环境各项变更的执行及记录;
ü         测试环境的备份及恢复;
ü         操作系统、数据库、中间件、WEB服务器以及被测应用中所需的各用户名、密码以及权限的管理;
ü         当测试组内多名成员需要占用服务器并且相互之间存在冲突时(例如在执行性能测试时,在同一时刻应当只有一个场景在运行),负责对服务器时间进行分配和管理。
2.         明确测试环境管理所需的各种文档
一般来说,下面的几个文档是必需的,当然你也可以根据需要增加新的文档。
ü         组成测试环境的各台计算机上各项软件的安装配置手册,记录各项软件的名称、版本、安装过程、相关参数的配置方法等,并记录好历次软件环境的变更情况;
ü         组成测试环境的各台机器的硬件环境文档,记录各台机器的硬件配置(CPU/内存/硬盘/网卡)、IP地址、具体用途以及历次的变更情况;
ü         被测应用的发布手册,记录被测应用的发布/安装方法,包括数据库表的创建、数据的导入、应用层的安装等。另外,还需要记录历次被测应用的发布情况,对版本差异进行描述;
ü         测试环境的备份和恢复方法手册,并记录每次备份的时间、备份人、备份原因(与上次备份相比发生的变化)以及所形成的备份文件的文件名和获取方式;
ü         用户权限管理文档,记录访问操作系统、数据库、中间件、WEB服务器以及被测应用时所需的各种用户名、密码以及各用户的权限,并对每次变更进行记录。
3.         测试环境访问权限的管理
    应当为每个访问测试环境的测试人员和开发人员设置单独的用户名,并根据不同的工作需要设置不同的访问权限,以避免误操作对测试环境产生不利的影响。下面的要求可以作为建立“测试环境访问权限管理规范”的基础。
ü         访问操作系统、数据库、中间件、WEB服务器以及被测应用等所需的各种用户名、密码、权限,由测试环境管理员统一管理;
ü         测试环境管理员拥有全部的权限;
ü         除对被测应用的访问权限外,一般不授予开发人员对测试环境其他部分的访问权限。如的确有必要(例如查看系统日志),则只授予只读权限;
ü         除测试环境管理员外,其他测试组成员不授予删除权限;
ü         用户及权限的各项维护、变更,需要记录到相应的“用户权限管理文档”中。
4.         测试环境的变更管理
    对测试环境的变更应当形成一个标准的流程,并保证每次变更都是可追溯的和可控的。下面的几项要点并不是一个完整的流程,但是可以帮助你实现这个目标。
ü         测试环境的变更申请由开发人员或测试人员提出书面申请,由测试环境管理员负责执行。测试环境管理员不应接受非正式的变更申请(例如口头申请);
ü         对测试环境的任何变更均应记入相应的文档;
ü         同每次变更相关的变更申请文档、软件、脚本等均应保留原始备份,作为配置项进行管理;
ü         对于被测应用的发布,开发人员应将整个系统(包括数据库、应用层、客户端等)打包为可直接发布的格式,由测试环境管理员负责实施。测试环境管理员不接受不完整的版本发布申请;
ü         对测试环境做出的变更,应该可以通过一个明确的方法返回到之前的状态。
5.         测试环境的备份和恢复
对于测试人员来说,测试环境必须是可恢复的,否则将导致原有的测试用例无法执行,或者发现的缺陷无法重现,最终使测试人员已经完成的工作失去价值。因此,应当在测试环境(特别是软件环境)发生重大变动(例如安装操作系统、中间件或数据库,为操作系统、中间件或数据库打补丁等对系统产生重大影响并难以通过卸载恢复)时进行完整的备份,例如使用Ghost对硬盘或某个分区进行镜像备份。并由测试环境管理员在相应的“备份记录”文档中记录每次备份的时间、备份人以及备份原因(与上次备份相比发生的变化),以便于在需要时将系统重新恢复到安全可用的状态。
另外,每次发布新的被测应用版本时,应当做好当前版本的数据库备份。而在执行测试用例或性能测试场景之前,也应当做好数据备份或准备数据恢复方案,例如通过运行SQL脚本来将数据恢复到测试执行之前的状态,以便于重复的使用原有的数据,减少因数据准备和维护而占用的工作量,并保证测试用例的有效性和缺陷记录的可重现。
解雇之前的五分钟
原著Danny R. FaughtFive Minutes Ahead of the Boot
—Kiki翻译于2005/7/15
 
        “这个错误和我上个星期发现的类型相同。他们什么时候才可以认识到这种问题?什么时候我可以将精力放在预防bug上呢?那是一个更高尚的职业吗?”一个感到不满的测试员说道。你也许认为质量保证是你测试职业的下一个合理的台阶,但是我曾经走过了那条道路并且不赞成这个观点。在这篇文章中,我们可以发现作者并不是唯一一个有那样的感觉的人。
 
        Fiona Charles曾是个测试员。在她公司做了六年的测试以后,她走向了许多测试人员都渴望的道路-她毕业了,成为了一名质量保证人员。最后,她开始帮助预防bug而不仅仅是在错误产生以后指出它们。顺便说一下,我在这里提到的“QA”,是指评估流程并且影响人们改进他们的流程,而不是比较常见的用法,单单只是“测试”的同义词。
但是Fiona的故事并没有到此结束。在做了几年的QA工作后,支持她工作的高级经理离开了公司,新的经理并没有给QA分享他们的感激。进度表的压力导致了以前所有人都同意的流程被扔出到窗外。人们说QA正在妨碍着他们 。Fiona说她可能会在公司解雇她之前的5分钟离开公司。现在她尽可能地避免QA这一角色,这是一个非常痛苦的经历。
        当Fiona给我讲述她的故事时,我感到奇怪,因为它和我自己的QA故事是如此得相似。当我做测试员的时候,我印象中测试人员在测试方面做得非常好之后应该自然而然的转到QA的角色。因此当我在发现bug的过程中受挫时,我就变得相信预防bug是一个更高的职业,我坚持要创建一个QA的团队。我绘制了一些流程图并且开始执行一个正式的检查流程。我攻读质量保证运动的硕士。但是在一年以后不知什么原因一切都塌陷在我身上。我真的不知道为什么我开始收到来自管理层关于我没有做好工作的投诉,但是我有一种和Fiona 相同的怀疑,我可能会在公司解雇我之前的5分钟离开公司。

测试和QA之间的相似点
        让我们来探究一下QA对于测试人员而言是不是一个更高的职业。首先查找两种角色的相似点。有一点是相当明显的-测试和QA人员都需要有对质量的热情。两者必须有锻炼附带一份实用性的热情的能力。当你不能直接控制产品的时候,软技巧(Soft skills)对于影响人们是很重要的。并且由于测试人员经常做一些QA相关的工作,他们可能已经有些部分工作的经验。 
每个测试人员好像在职业生涯中遇到了一些问题是最大的挫折。他们不能忍受相同的错误一再的发生,是因为他们知道有更好的构建产品的方法。 因此QA小组好象是达到那个目标的最合适的地方。
 
但是它们之间的区别是什么呢? 
        如何区分测试和QA呢?测试集中在产品的质量,QA趋向于从产品上移开,集中在流程的质量,尽管QA也要查看产品相关的度量指标。QA需要更多的关于整个开发生命周期的知识。QA人员必须得到来自经理,需求人员,设计人员,程序开发人员,配置管理人员,当然还有测试人员的尊重。多年测试员的经验给予了一些帮助,但是不可能让测试员成为在所有这些方面的专家。QA甚至需要比测试更多的软技巧,因为他们需要获得组织中人们的信任并且使人们信服地更改他们工作中一些核心的方法。
测试人员有切实具体的交付物,例如测试用例,bug报告等。QA工作就比较无形,例如观察,提倡,推动和影响。当QA分析人员感到比起做测试人员时,甚至更远地远离了构建一个高品质产品的切实的方面,它就可能感到灰心了。
 
怎样会误入岐途? 
        以下是一些作为一个QA可能会遇到的问题。
  • 为一个不是很成熟的组织做流程工作,可能不会理解工作的价值。最需要QA的组织是最不可能接受它的。因此你必须查找一个经历了一番磨难后才获得足够改进的组织以认识到可能有更好的方法。不同的人在对他们正在工作的公司的成熟度和程序有不同的偏好。
  • 为最佳实践本身,作为一个最佳实践的倡导者,而不是帮助人们从他们的角度解决问题。你不可能强推一个流程到一些人的喉咙里并且期望它一直呆在那里。接近改变的最好方法是帮助他人发现他们相信存在的问题的解决办法。那也意味着你可能甚至不能够获得对于你工作的信任。
  • QA会碍事。这是真的-在短期内。从长远的观点看,较好的流程将给予回报,但是只有当你通过了由于推行一个新的流程而延迟了一些人喜爱的项目所引起的对你的怨恨。
  • 成功地制造大块地流程变更是格外困难的。最可靠的方法是随着时间做许多小的改进,这样获得了许多的耐心。如果你真的试图快速的改变世界,要先准备面临彻底的失败。
  • 当时间被缩短时,或是高层管理层的态度改变时,QA通常是第一个被放在砧板上的。不要自寻烦恼地在你的办公室里挂很多的图片。
把你从QA退伍中吓跑了吗?
        我相信除了QA还有很多好的测试人员可以从事的职业道路。如下:
  • 管理层。获得一些作为测试领导的实践,试着做测试经理,并且寻找侧向的或向上的管理职位。
  • 工具专家(Toolsmith)。如果你想保持技术并且仍然想留在测试领域,就成为一个测试工具的专家吧。
  • 顾问。比较陌生,但是这是真的,在这个行业里许多非常有经验的测试人员都是顾问。
  • 其他很多的事情。一些你在做测试员时也用到的技术-想编程,技术文档的编写,技术支持,市场等等。
        QA工作可能适合你。我曾经听说过一些真的非常擅长QA工作的人。如果你选择了这条道路,希望你从现在开始就好好的准备,否则,我希望你有一个关于从事QA工作的全新的评价。
原文地址:http://taker2001.cnblogs.com/archive/2005/07/13/191882.html
在LR的参考资料中也可以看到,建议将登录系统这类的脚本放在Init部分,而将业务相关的脚本放到Action部分,退出系统的脚本放到End部分。这样做除了使脚本结构更加清晰以外,还可以保证在多次迭代时,不用反复的重复登录和退出操作。
今天看到论坛上有朋友问是否一定要每次录制完以后把脚本从Aciton部分分别剪切、粘贴到Init和End部分?其实可以在录制脚本的时候就分段录制的。如下图所示

图1
这是在Start Recording的时候弹出的对话框,在“Record into Action”项中有三个选项,默认是选中“Action”项。可以在开始录制的时候,选中“vuser_init”项,等系统完成登录进入主界面后,再切换到“Action”项,最后退出的时候选择“vuser_init”。
另外,界面上还可以看到“Record the application startup”项,默认上选中的,意思是在程序启动时就开始录制脚本,灵活运用吧 ^_^

图1
将LR返回结果保存为Session的好处之一,是可以添加注释,将你在分析图表过程中的思路记录下来,不至于下次看时毫无头绪,重新来过。
上面的注释和指示箭头,是使用“Add Comments”和“Draw arrow”实现的。这两个功能可以在LR Analysis工具栏中看到,如下图:

图2
在进行稳定性测试时,我们希望在可以充分利用时间和测试资源,让两个场景分别在前半夜和后半夜运行。为此需要准备两台Controller机,分别打开不同的场景,并对两个场景持续运行的时间进行设置——例如都运行6个小时。然后通过Scenario Start Time来分别设置两个脚本开始运行的时间——例如第一个脚本设置为从当天下午6点钟开始运行,第二个脚本从第二天凌晨1点钟开始运行。如下图

图1
共有三个选项,分别为不使用延迟、延迟N长时间后开始或者延迟到指定的时间开始。设置完成后,点击Start Scenario按钮,可以看到下面的样子

图2

图3

图1
上面这个图是对Google的搜索功能的一次测试后,使用“Merge Graphs…”功能将Hits per Second、Throughput、Average Transaction Response Time三个图组合在一起生成的图表,我们希望从中可以看出在场景执行过程中,随着Hits per Second的增加,Throughput的变化情况,以及对Average Transaction Response Time的影响。
但是因为三个原图中的性能计数器的数值和单位都不同,当Analysis使用同样的比例进行显示时,根本无法体现出三者的关系——图中高高在上的绿色线是Throughput,而几乎平伏在接近0水平的是Hits per Second和Average Transaction Response Time。
这种情况下,除了手工调整各个性能计数器的显示比例外,一个更简单有效的方法是使用“View Measurement Trends”功能(如图1所示)。使用后的效果就像下面这样

图2
是不是清楚多了? ^_^

     我们需要对一个商业系统进行整体性能测试,按照对用户以往使用情况的分析,我们整理出了用户在多个业务上的分布情况,也在Controller中添加了这些业务所对应的脚本,设置了每个脚本对应的虚拟用户数。我们还希望可以模拟一开始就让所有用户同时在线的情况,但我们又不希望使用集合点在每次迭代时都对各个业务造成那么大的压力——因为对组合场景来说,这种压力似乎又不太合理。最后我们使用了Controller中的“Initialize all Vusers before Run”选项,控制所有的虚拟用户都完成初始化(执行完init部分的脚本)后,全部到达“Ready”状态时,同时开始执行Action部分的脚本(虚拟用户变为Run状态)。如下图

有些时候我们需要将多个返回结果放在一起进行对比,例如,一个场景在多个不同的发布版本上运行后,我们希望通过对测试结果的比较来判断不同版本的性能差别;或者对同一个压力点,我们设计了几个场景,在这几个场景都运行通过后,我们要比较一下不同的负载对系统的影响。当然,你也可以因为更多的原因产生这种需求。不过不管怎么说,如果为了实现这个愿望,而不得不同时打开几个Analysis,那恐怕的确是有些麻烦——况且在比较这些结果时还要不停的切换窗口。
LoadRunner提供的一个比较好的功能可以帮助我们更简单的完成这项工作——“Cross with Result”。如下图所示

图1

图2

图3

在一个使用LoadRunner进行的性能测试项目中,需要管理的东西通常有三种:

1.         通过VuGen生成的脚本;

2.         通过Controller生成的场景;

3.         执行场景生成的返回结果。

我通常习惯于用下面的目录结构来管理这些内容,如下图



1

当然,也还需要一些文档来描述这些目录之间的关系。例如

序号

场景名

场景用途

场景设置

1

1场景

检查1个虚拟用户时Google的搜索响应时间

虚拟用户:1

集合点:无

Think Time:忽略

迭代次数:1

init all user before runDisabled

Load Generator 1jackei1VU

……

2

2场景

检查10个虚拟用户时Google的搜索响应时间

虚拟用户:10

集合点110个用户并发提交搜索请求

Think Time:忽略

迭代次数:5

init all user before runDisabled

Load Generator 1jackei10VU

……

3

3场景

……

……

当然,上面的这个表格只是为了说明一个思路,你也完全可以使用一个EXCEL表格把同场景设置有关的每一项都作为单独的一列来管理,这样你就可以利用EXCEL的“筛选”功能方便的在多个场景中迅速的找到自己需要的那个。

另外,通常还需要一份文档用来管理每次场景执行的结果。例如

模块名

场景名

返回结果

详细描述

GOOGLE性能测试项目

1场景

1场景0

全部通过

1场景1

全部通过

1场景2

全部通过

GOOGLE性能测试项目

2场景

2场景0

1次请求失败

2场景1

全部通过

上面这个例子比较简单,但在实际工作中可以在“详细描述”中记录更多的内容,例如在一个进销存系统中,发现某个场景中全部的请求都已经通过,但是在系统中却发现实际提交成功的订单数量小于LRVU的请求数量。那么应该将这种情况记录下来,否则在同一场景多次运行后你就搞不清每次运行的区别在哪里了。

 

对于场景和返回结果之间的关系,可以通过设置Controller中的Result Directory,让LR在每次运行场景时自动保存返回结果。如下图


2


3

Directory中指定的是返回结果的保存路径,选中“Automatically create a results directory for each scenario execution”项后,再输入一个“Results Name”,LR就会负责在每次场景执行结束后自动保存返回结果到指定的目录中,并且将根据Results Name中的值,每次按照顺序生成新的返回结果目录。如上面的例子中,会将返回结果保存为

L:\GOOGLE性能测试项目\返回结果\1场景0

L:\GOOGLE性能测试项目\返回结果\1场景1

L:\GOOGLE性能测试项目\返回结果\1场景2

……

每次在Controller中运行一个场景时,LR都会把返回结果保存在你指定的目录下,场景运行结束后,你可以在该目录中找到一个扩展名为“lrr”的文件,双击这个文件就可以在Analysis中看到在本次场景运行过程中LR收集到的各种信息。但是每次在Analysis中打开返回结果时,LR都要去ACCESS数据文件中读取数据,然后初始化图表,耗时太长。所以我们可以将返回结果保存成Session——保存成Session可以将当前Analysis中的所有内容以文件的形式保存下来,下次打开Session(扩展名为“lra”的文件)时LR直接读取这些文件,并在Analysis中还原为最近一次保存的状态,比直接打开返回结果快多了。

另外,在Analysis中每次打开的返回结果都是重新从ACCESS数据文件中读取数据,然后初始化图表的,假如你好不容易通过几个图的组合、关联找到了一点思路,终于把性能瓶颈定位清楚了,却没有保存为Session,那么下次打开返回结果时就又要从头开始整理你的思路了。

将返回结果保存成Session是一件很容易的事情,你可以直接点击Analysis工具栏上的保存按钮,指定Session的保存路径和文件名。也可以通过设置,在每次打开返回结果时自动保存为Session。设置方法如下图所示:



1


2

选中“Automatically save the session as:”选项后,Analysis默认每次打开返回结果都自动保存成Session,保存的路径和Session名字可以在后面的编辑框中设定,默认为“%ResultDir%\An_Session1”。

另外,你也可以同时选中Controller中“Auto Load Analysis”项,在每次场景运行结束后自动打开Analysis,加载本次的返回结果。如下图:


3

 

注意事项:

因为选中“Automatically save the session as:”选项后,Analysis默认每次打开返回结果都自动保存成Session。所以除了第一次加载返回结果以外,每次查看返回结果时请到保存Session的目录下打开扩展名为“lra”的文件,以免误操作将以前的Session覆盖。