-
Loadrunner常见报错
xiaoneng 发布于 2014-09-22 15:43:29
用LoadRunner录制TFS登陆界面,回放时报了几个错,第一个就是:“Error -26547: Authentication required, please use web_set_user, e.g. web_set_user("domain\\user", "password", "host:port"); [MsgId: MERR-26547]”;例如:web_set_user("X\\Y", "Z", "A.com:80"),解释为:在域X上的用户名为Y的用户,使用密码Z来登录到A.com:80。web_set_user()函数带三个参数,分别是域用户名、口令和需要登录的服务器名称和端口,第一个参数需要注意的是一定要带上域名,其格式为domain\\user,而最容易混淆的莫过于第三个参数了。特别需要注意的是,第三个参数是“需要认证的服务器名:端口”,假设你要访问的web url 是 http://requireauth/login.asp,则第三个参数应该是“requireauth:80”,有些朋友错误的写成“http://requireauth:80”或是“requireauth/login.asp:80”,都是不正确的。在windows基本验证的时候这个脚本被默认录制下来,但如果web服务器需要更安全的NTLM或更深层次的验证,需要手动的添加这个函数到脚本中。对于NTML验证,用户名必须在域名之后,并且以\分割。使用\等符号,需要使用\\,前面的\用来做转义用,否则会出现警告提示。
最后,知其然,知其所以然。web_set_user函数的原理并不复杂,简单的说,就是通过NTLM协议发送了一些数据包给服务器而已。关于NTLM的更详细的内容,提供两份参考文献: -
jira搭建总结
mile597 发布于 2014-02-18 16:13:17
本文参考并细化:
http://blog.csdn.net/jefferxun1/article/details/7419189
安装介质清单:
atlassian-jira-5.0.2-x32.exe: jira5.0.2版本
atlassian-jira破解文件.rar: jira5破解文件,包括两个class文件
JIRA-5.0.1-language-pack-zh_CN.jar: jira5的汉化包
mysql-5.0.27-win32.zip:mysql安装程序
安装步骤:
1、安装mysql,2、创建空数据库,3、安装jira5.0.2,4、配置数据库链接为mysql,5、破解jira,6、汉化jira,7、导入原数据库,8、启用。
前4步不做描述,安装全缺省就可以了。
5、破解步骤:
这是最重要的步骤。
安装完成后,启动服务:
访问http://localhost:8080/
配置好mysql数据库链接:
先测试一下链接,通过后,点击next;
停止jira服务,不用关闭之前的IE窗口:
替换两个文件:
覆盖一:
\atlassian-jira\WEB-INF\classes\com\atlassian\jira\license\JiraLicenseStoreImpl.class
文件覆盖到 JIRA安装目录
\Atlassian\JIRA\atlassian-jira\WEB-INF\classes\com\atlassian\jira\license\JiraLicenseStoreImpl.class覆盖二:
用WinRar等压缩工具打开JIRA安装目录\Atlassian\JIRA\atlassian-jira\WEB-INF\lib\atlassian-extras-2.2.2.jar文件,并找到atlassian- extras-2.2.2.jar\com\atlassian\extras\decoder\v2目录,
(jar包,可以把后缀名改成rar,进行操作)然后把破解补丁中的
atlassian-jira\WEB-INF\classes\com\atlassian\extras\decoder\v2\Version2LicenseDecoder.class拖动到这个窗口,覆盖原来的rar压缩包中的同名文件。启动jira服务;
这时的license可以直接填写明文的license了。于是填写:
管理员登录成功后,点击右上角的“管理员页面”,后续就可以在插件页面进行安装了。
-
测试负责人培养方案
没翅膀的飞鱼 发布于 2014-03-08 22:33:09
-
PL/Sql连接oracle配置
shingo0109 发布于 2013-02-26 14:02:27
PL/SQL的配置
1.安装Oracle Client11g,这里的安装目录为: D:\app\oracle\product\11.2.0\client_1
2.在当前目录下到network\admin目录下,在sample目录下copy文件tnsnames.ora到admin目录,然后再手动配置tnsnames.ora
(SERVICE_NAME为数据库服务名或sid名)
tnsnames.ora文件内容(斜体表示需要替换的内容):
orcl=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.103)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)
3.配置环境变量
变量名: TNS_ADMIN
变量值: D:\app\oracle\product\11.2.0\client_1\network\admin
否则出现:ORA-12154: TNS:could not resolve the connect identifier specified错误
4.安装pl/sql软件
5.配置pl/sql的Oracle连接参数:
选择pl/sql的工具/首选项(too/ preference/)里的连接,在右面设置Oracle主目录名(即安装目录)和OCI库.
Oracle Home: OraClinet11g_home1
OCI libiary: D:\app\oracle\product\11.2.0\client_1\oci.dll
6.pl/sql测试登录:
输入数据库用户名和密码,从Database下拉列中选择orcl, Connect as选为Normal
-
【转】初级——程序如何打包成apk文件
yanfang_zheng 发布于 2013-03-15 17:38:48
文章来自 http://blog.csdn.net/yuanfenwuyue1989/article/details/7739951将Eclipse Android项目打包成APK文件是本文要介绍的内容,主要是来了解并学习Eclipse Android打包的内容,具体关于Eclipse Android内容的详解来看本文。
Eclipse Android项目开发完成以后就要将android项目文件打包成apk文件,并最终下载到真机上运行。下面是个人打包apk的过程,主要是以图文形式记录一下。
其实最懒的办法,就是直接到eclipse项目的bin目录找到文件,那是eclipse系统自动生成的apk文件。
1、生成keystore
按照下面的命令行在C:\ProgramFiles\Java\jdk1.6.0_10\bin>目录下,输入keytool-genkey-aliasandroid.keystore-keyalgRSA-validity100000-keystoreandroid.keystore
参数意义:-validity主要是证书的有效期,写100000天;空格,退格键都算密码。
命令执行后会在C:\ProgramFiles\Java\jdk1.6.0_10\bin>目录下生成android.keystore文件。如图-1
图-1命令行下生成android.keystore
2、Eclipse Android生成apk文件
选择要打包的项目,右键点击–>Androidtools–>ExportSignedApplicationPackage…如图-2
图-2 Eclipse Android打包工具
接下来的步骤就是不断的next。下面仅贴出图片,不解释。
step2:选择打包的项目
step3:选择生成的Eclipse Android.keystore文件并输入密码
step4:选择aliaskey并输入密码
step5:最后选择生成androidapk文件的目录及文件名
最终生成的apk文件。 -
JAVA与C#语法区别
545168150 发布于 2013-03-16 21:45:42
JAVA语法和C#语法类似,除了一些关键字上有些区别,两者几乎是相通的。只是一个是sun公司,一个是microsoft。主要区别如下:
1,运行环境:C#需要.net framework支持,C#必须要在.NET FrameWork下运行,一般基于windows平台,需要IIS。而java有虚拟机,可以跨windows\unix平台,扩展性比.net好。
2,属性: java中属性定义和访问均要用get和set方法,可以不成对出现。 c#中属性,定义时get和set必须同时出现, 访问时用.号即可,不用get,set。
3,C#中不用任何范围修饰符时,默认的是protect,因而不能在类外被访问。JAVA规定在一个文件中只能有一个public类,而且这个类的名称必须与文件名一模一样。,C#中的访问修饰符与Java中的基本对应,但多出了一个internal。即C#有5种类型的可访问性:public:成员可以从任何代码访问。
protected:成员只能从派生类访问。
internal:成员只能从同一程序集的内部访问。
protected internal:成员只能从同一程序集内的派生类访问。
private:成员只能在当前类的内部访问。4,在C#中,它是以Main方法来入口,如果一个程序中没有Main方法,就会出"找不到入口的错误",不要把Main写成main。c#是可以对Main进行重载(java中是main),允许有int返回值和空参数的Main。
5,C#预定义的简单数据类型比Java多。例如,C#有unit,即无符号整数。
6, Java中static final修饰符声明常量。C#中常量可以用const关键词声明。C#的设计者还增加了readonly关键词,readonly域只能通过初始化器或类的构造函数设置 。
7,在Java中,switch语句只能处理整数。但C#中switch语句还能够处理字符变量。8,C#没有>>>移位操作符。c#保留了指针。unsafe
9,goto关键词: Java不用goto关键词,你可以用带标签的语句加上break或continue取代C#中的goto。在C#中,goto允许你转到指定的标签。不过,C#以特别谨慎的态度对待goto,比如它不允许goto转入到语句块的内部。
10,int[] x = { 0, 1, 2, 3 }; Int x[] = { 0, 1, 2, 3 }; 在C#中,只有第一行代码合法,[]不能放到变量名字之后。
11,C#允许为名称空间或名称空间中的类指定别名: using TheConsole = System.Console。
12,在Java中,包的名字同时也是实际存在的实体,它决定了放置.java文件的目录结构。在C#中,物理的包和逻辑的名称之间是完全分离的。 .NET中包的实体称为程序集(Assembly)。每一个程序集包含一个manifest结构。manifest列举程序集所包含的文件,控制哪些类型和资源被显露到程序集之外,并把对这些类型和资源的引用映射到包含这些类型与资源的文件。程序集是自包含的,一个程序集可以放置到单一的文件之内,也可以分割成多个文件。.NET的这种封装机制解决了DLL文件所面临的问题,即臭名昭著的DLL Hell问题。
13,在Java中,java.lang包是默认的包,C#中不存在默认的包。
14,C#中不存在final关键词,如果想要某个类不再被派生,可用sealed关键词。
15,与Java不同,C#中的接口不能包含域(Field)。 注意,在C#中,接口内的所有方法默认都是公用方法。在Java中,方法声明可以带有public修饰符(即使这并非必要),但在C#中,显式为接口的方法指定public修饰符是非法的。
16,C#中的is操作符与Java中的instanceof操作符一样,两者都可以用来测试某个对象的实例是否属于特定的类型。在Java中没有与C#中的as操作符等价的操作符。as操作符与is操作符非常相似,但它更富有“进取心”:如果类型正确的话,as操作符会尝试把被测试的对象引用转换成目标类型;否则,它把变量引用设置成null。
17,C#仍旧保留了C++的内存手工管理方法,它适合在速度极端重要的场合使用,而在Java中这是不允许的。
17,在C#中,所有的异常都从一个名为Exception的类派生。
18,C#中枚举器即enum类型(java无),把它作为一个变量值的类型使用,从而把变量可能的取值范围限制为枚举器中出现的值。
19,传值方式: 在java中简单数据类型的值传参时,都以传值方式。在c#中如果加ref则会以引用的方式传值(方法内部改变该参数,则外部变量一起跟着变),加out与ref基本相同,但out不要求参数一定要初始化。
-
正则表达式(一)
lei___ 发布于 2013-03-18 21:02:58
http://download.csdn.net/detail/pxd41408/2136844 下载的CSDN路径http://blog.csdn.net/napianyangguangxia/article/details/8543104http://blog.csdn.net/napianyangguangxia/article/details/8543104 基础与入门字符集合
说明
.
小数点可以匹配除了换行符(\n)以外的任意一个字符
\w
可以匹配任何一个字母或者数字或者下划线
\W
W大写,可以匹配任何一个字母或者数字或者下划线以外的字符
\s
可以匹配空格、制表符、换页符等空白字符的其中任意一个
\S
S大写,可以匹配任何一个空白字符以外的字符
\d
可以匹配任何一个 0~9 数字字符
\D
D大写,可以匹配任何一个非数字字符
[:alpha:]
POSIX 格式,可以匹配任何一个字母
[:^alpha:]
POSIX 否定格式,可以匹配任何一个字母以外的字符
POSIX 字符集合
说明
[:alnum:]
任何一个字母或数字(A - Z, a - z, 0 - 9)
[:alpha:]
任何一个字母(A - Z, a - z)
[:ascii:]
任何一个 ASCII 范围内字符(\x00 – \x7F)
[:cntrl:]
任何一个控制字符(\x00 – \x1F, \x7F)
[:digit:]
任何一个数字(0 – 9)
[:print:]
任何一个可显示的 ASCII 字符(\x20 – \x7E)
[:space:]
任何一个空白字符(\x09 – \x0D, \x20)
[:graph:]
任何一个可显示的 ASCII 字符,不包含空格(\x21 – \x7E)
[:lower:]
任何一个小写字母(a – z)
[:punct:]
可显示字符 [:print:] 中除去字母数字 [:alnum:]
[:upper:]
任何一个大写字母(A – Z)
[:xdigit:]
任何一个十六进制数字(0 - 9, A - F, a - f)
[:blank:]
空格或者制表符(\x20, \x09)
所有的 POSIX 字符集合,与 [:^alpha:] 类似 ,当 [: 之后为 ^ 时,表示相应字符集合之外的字符。
-
【转】oracle入门心得----强烈推荐
楠族开心果 发布于 2013-03-20 10:02:25
oracle的体系太庞大了,对于初学者来说,难免会有些无从下手的感觉,什么都想学,结果什么都学不好,所以把学习经验共享一下,希望让刚刚入门的人对oracle有一个总体的认识,少走一些弯路。
一、定位
oracle分两大块,一块是开发,一块是管理。开发主要是写写存储过程、触发器什么的,还有就是用Oracle的Develop工具做form。有点类似于程序员,需要有较强的逻辑思维和创造能力,个人觉得会比较辛苦,是青春饭J;管理则需要对oracle数据库的原理有深刻的认识,有全局操纵的能力和紧密的思维,责任较大,因为一个小的失误就会down掉整个数据库,相对前者来说,后者更看重经验。
因为数据库管理的责任重大,很少公司愿意请一个刚刚接触oracle的人去管理数据库。对于刚刚毕业的年轻人来说,可以先选择做开发,有一定经验后转型,去做数据库的管理。当然,这个还是要看人个的实际情况来定。
二、学习方法
我的方法很简单,就是:看书、思考、写笔记、做实验、再思考、再写笔记
看完理论的东西,自己静下心来想想,多问自己几个为什么,然后把所学和所想的知识点做个笔记;在想不通或有疑问的时候,就做做实验,想想怎么会这样,同样的,把实验的结果记下来。思考和做实验是为了深入的了解这个知识点。而做笔记的过程,也是理清自己思路的过程。
学习的过程是使一个问题由模糊到清晰,再由清晰到模糊的过程。而每次的改变都代表着你又学到了一个新的知识点。
学习的过程也是从点到线,从线到网,从网到面的过程。当点变成线的时候,你会有总豁然开朗的感觉。当网到面的时候,你就是高手了
很多网友,特别是初学的人,一碰到问题就拿到论坛上来问,在问前,你有没有查过书,自己有没有研究过,有没有搜索一下论坛?这就叫思维惰性。由别人来回答你的问题,会让你在短时间内不费劲地弄懂这个知识点,然而通过自己的努力去研究它,不但会更深入的了解这个知识点,更重要的是在研究的过程会提高你解决问题和分析问题的能力。总的来说,没有钻研的学习态度,不管学什么东西,都不会成功的。
当然,初学的人很多时候是因为遇到问题时,无从下手,也不知道去哪里找资料,才会到论坛上提问题的。但我认为,在提问的时候,是不是可以问别人是如何分析这个问题?从哪里可以找到相关的资料?而不是这个问题的答案是什么?授人以鱼不如授人以渔。
下面我讲下我处理问题的过程
首先要知道oracle的官方网站:www.oracle.com 这里有oracle的各种版本的数据库、应用工具和权威的官方文档。其次,还要知道http://metalink.oracle.com/这里是买了oracle服务或是oracle的合作伙伴才可以进去的,里面有很多权威的解决方案和补丁。然后就是一些著名网站:asktom.oracle.com www.orafaq.net, www.dbazine.com。这里有很多经验之谈。
遇到问题了。如果是概念上的问题,第一时间可以找tahiti.oracle.com,这里会给你最详细的解释。如果在运行的过程中出了什么错误。可以去metalink看看。如果是想知道事务的处理的经验之谈。可以去asktom。当然。这里只是相对而言。
三、oracle的体系
oracle的体系很庞大,要学习它,首先要了解oracle的框架。在这里,简要的讲一下oracle的架构,让初学者对oracle有一个整体的认识。
1、物理结构(由控制文件、数据文件、重做日志文件、参数文件、归档文件、密码文件组成)
控制文件:包含维护和验证数据库完整性的必要信息、例如,控制文件用于识别数据文件和重做日志文件,一个数据库至少需要一个控制文件
数据文件:存储数据的文件
重做日志文件:含对数据库所做的更改记录,这样万一出现故障可以启用数据恢复。一个数据库至少需要两个重做日志文件
参数文件:定义Oracle 例程的特性,例如它包含调整SGA 中一些内存结构大小的参数
归档文件:是重做日志文件的脱机副本,这些副本可能对于从介质失败中进行恢复很必要。
密码文件:认证哪些用户有权限启动和关闭Oracle例程
2、逻辑结构(表空间、段、区、块)
表空间:是数据库中的基本逻辑结构,一系列数据文件的集合。
段:是对象在数据库中占用的空间
区:是为数据一次性预留的一个较大的存储空间
块:ORACLE最基本的存储单位,在建立数据库的时候指定
3、内存分配(SGA和PGA)
SGA:是用于存储数据库信息的内存区,该信息为数据库进程所共享。它包含Oracle 服务器的数据和控制信息, 它是在Oracle 服务器所驻留的计算机的实际内存中得以分配,如果实际内存不够再往虚拟内存中写。
PGA:包含单个服务器进程或单个后台进程的数据和控制信息,与几个进程共享的SGA 正相反PGA 是只被一个进程使用的区域,PGA 在创建进程时分配在终止进程时回收
4、后台进程(数据写进程、日志写进程、系统监控、进程监控、检查点进程、归档进程、服务进程、用户进程)
数据写进程:负责将更改的数据从数据库缓冲区高速缓存写入数据文件
日志写进程:将重做日志缓冲区中的更改写入在线重做日志文件
系统监控:检查数据库的一致性如有必要还会在数据库打开时启动数据库的恢复
进程监控:负责在一个Oracle 进程失败时清理资源
检查点进程:负责在每当缓冲区高速缓存中的更改永久地记录在数据库中时,更新控制文件和数据文件中的数据库状态信息。
归档进程:在每次日志切换时把已满的日志组进行备份或归档
服务进程:用户进程服务。
用户进程:在客户端,负责将用户的SQL 语句传递给服务进程,并从服务器段拿回查询数据。
5、oracle例程:Oracle 例程由SGA 内存结构和用于管理数据库的后台进程组成。例程一次只能打开和使用一个数据库。
6、SCN(System Change Number):系统改变号,一个由系统内部维护的序列号。当系统需要更新的时候自动增加,他是系统中维持数据的一致性和顺序恢复的重要标志。
四、深入学习
管理:可以考OCP证书,对oracle先有一个系统的学习,然后看Oracle Concepts、oracle online document,对oracle的原理会有更深入的了解,同时可以开始进行一些专题的研究如:RMAN、RAS、STATSPACT、DATAGUARD、TUNING、BACKUP&RECOVER等等。
开发:对于想做Oracle开发的,在了解完Oracle基本的体系结构之后,可以重点关注PL/SQL及Oracle的开发工具这一部分。 PL/SQL主要是包括怎么写SQL语句,怎么使用Oracle本身的函数,怎么写存储过程、存储函数、触发器等。 Oracle的开发工具主要就是Oracle自己的Developer Suite(Oracle Forms Developer and Reports Developer这些),学会如何熟练使用这些工具。
介绍几本oracle入门的好书
oracle官方文档:《concept》上面讲了oracle的体系和概念,很适合初学者看。
OCP的教学用书,也就是STUDY GUIDE(SG)。
Oracle8i 备份恢复手册
Oracle8高级管理与优化
Oracle8i PLSQL程序设计
Oracle8数据库管理员手册
以上书本都是机械工业出版社出版。
介绍几个网站
http://tahiti.oracle.com oracle的官方文档
现在http://www.oracle.com.cn/onlinedoc/index.htm也有官方文档,速度奇快
http://metalink.oracle.com/ oracle的技术支持网站。需要购买Oracle服务才能有一个帐号,才能登陆,有大量的Knowledge Base,大量问题解决经验。
http://www.oracle.com oracle的官方网站,可以在这里down oracle的软件、官方文档和获得最新的消息
http://www.dbazine.com/ Oracle的杂志
http://asktom.oracle.com
http://www.orafaq.net/
http://www.ixora.com.au/
http://www.oracle-base.com
http://www.dba-oracle.com/oracle_links.htm -
如何判断安装的java是32位还是64位
sherryvm 发布于 2013-03-20 14:23:52
public class JavaArch{
public static void main(String[] args){
String arch = System.getProperty("sun.arch.data.model");
System.out.println("arch:"+arch);
}
}
-
2012测试领域工作进步总结及自我成长心得
架构师Jack 发布于 2013-02-02 10:49:22
忙碌,压力和富有创新的2012,很快就过去了,2012年2月1日仿佛还是昨天的记忆。回顾这一年的忙碌,自己在测试领域又有了一些新进步,为了自己的记忆,整理下吧。功能测试领域 让探索测试方法更好地丰富了功能测试的行为模式;抽象总结了 测试数据7因子模型;用户场景测试模型的建立,这些都将减少功能内缺陷,功能间缺陷的遗漏; 基于相同资源共享的测试分析方法降低功能组合测试爆炸的问题。 在很好应用该领域方法的产品团队,测试时间减少了,测试质量提升了。这就是how to do的价值稳定性测试领域 将过去压力测试、长时间测试、故障注入测试的经验和方法,进行了更好的组合和梳理,形成了系统的测试方法模型,对稳定性影响的5个维度:来自人为操作的输入;来自网络的影响;来自操作系统或第三方软件的影响;长时间运行的影响;大数据量压力下的影响。应用这些测试方法的产品,挡住了多个发布前的严重问题,实现了0事故性能测试领域 终于找到了解决为什么实验室的性能测试数据 与 用户环境性能测试数据差距的本质技术原因,并提出了一套性能测试数据和场景分析与设计的方法,解决了如何在不同插件、不同第三方平台、不同操作下获得软件性能影响值并避免了组合用例爆炸,又能准确在实验室中反应出各种极端或特殊用户环境下的性能值。无线测试领域: 最大的收获在于解决了移动互联网时代最大也最应该解决的性能测试场景,低质量或不稳当网络下的准确性能表现,例如如何快速复现新浪微博APP可以刷新数据,自己的APP却不能刷新数据的性能场景。一个产品团队2年没解决困扰的不确定性技术问题域,1个月完全搞定,解决的方案既可以发现真实环境中的性能问题还能发现稳定性问题,cover到monkey测试不能发现的稳定性问题类型。数据效果测试领域 对我而言是第一次接触和涉及这种测试类型,例如传统模式下靠人工方式来判断”文不对图“的数据缺陷,今年通过创新的领域测试建模终于实现了自动化判断的方式来代替人工判断,并首次实现不依赖用户行为数据就可以自动判断的测试性能。总的来说对于个人测试专业成长而言,2012年是最近2年提升最多的一年。心得体会:只要你真心想去解决一线测试存在的技术问题,以pull的方式而不是push的思路来减少用户反馈问题数,减少测试成本,你总能找到自己新的成长点。 自我成长来自:自有经验的应用+他人知识与经验+自有创新实践+及时总结提炼 -
wrf格式转换成avi
moshuang 发布于 2013-02-28 15:31:29
用了一款国外的录像软件WEBEX recording Editor,用起来费劲,等保存格式后是wrf,还不能跟其他人共享,别人用不了。最后发现这个录像软件可以导出为wmv格式。这可是最大众的格式了,然后,再下个格式化工厂,想转什么转什么,一切万事大吉。
这也说明了统一管理和统一规则的重要性啊,否则浪费太多时间在没必要的问题上。
-
软件测试工程师面试后想说的
moshuang 发布于 2012-12-31 14:59:44
昨晚正式收到支付宝的Offer,提交完离职申请,我的求职过程也就告于段落了。写下这篇文章,希望我的这些经历可以对正在求职的你能有点启发。
首先,交代下我的背景,这样大家看的时候,就可以有个对比参照。我2010年7月份毕业于南京晓庄学院计算机专业,一所二本学校,经常用大学班主任的气话来调侃“我是一所三流学校里面的二流学生”。在大学期间,成绩一般,没拿过一等,唯一一次有机会拿二等,还因为一门公共课挂科而取消资格,但也扎扎实实学过一些专业课程,比如数据库、网络、C++编程。考研,挂了。大学毕业那会,因为一直在实习,就没正儿八经投过几份简历(现在再看我大学毕业时的简历,真是一塌糊涂),那时候面试过金蝶,失败,富士通的笔试都没过。所以可以讲,我毕业那会基本没有面试经验。后来,没办法就厚脸皮,外包进入实习的那家很牛逼的杀毒软件公司,入行软件测试。这一待就是二十九个月。
在这两年五个月的时间里,开始我对软件测试知之甚少(大学课程中,也就软件工程课中提到过软件测试),利用工作间隙一点点学习:测试理论、Java、Python、设计模式,甚至学习过servlet、JSP,Spring框架……,现在看学的好混乱啊。同时,项目中接触到了自动化测试,就给自己定位要学好自动化测试。学习过程就不细述了,最后经过不断学习,我敢贴在自己简历中的技术背景是这样的:
从八月底开始,到十二月初我差不多投递了80多封求职简历(还不算在51Job中申请的职位),80+的求职邮件,收到了差不多40封邮件反馈。九月中旬,陆陆续续进入面试高峰期,有时,一周面三家单位,投的都是外地公司,所以接到都是四十分钟以上的电话面试。在这三个半月的时间里,我经历着“希望-失望-又有希望-再一次失望”这样的煎熬,一次次失败,逼得我不断反思,我问自己问题出在哪?一遍遍修改求职简历,从措辞到排版,到最后甚至计较该用什么字体,字体大小设置多大看起来比较美观。一遍遍独白面试第一部分的“自我介绍”,该如何有条理的把自己这两年所学,所做的事情阐述出来。更为重要的事,我开始整理这两年所学,梳理那些测试理论,编程语言,项目经验。
在决定换工作的时候,自己首先需要弄明白为什么要换工作?真的到了非换不可的地步了吗?我不赞成轻率地、频繁地换工作,在我看来换一份工作成本还是蛮大的。但当我在这一个项目两年以上,当日常工作游刃有余,没有压力时,当我不是很清楚地知道我该学些什么的时候,我知道该make change了。上周周会,看到项目未来半年的WBS,看到那些摊派到我头上的任务,我知道我做了正确的决定。促成我换工作的另一个原因是,这两年多来,我一直待在同一个项目组,测试的是IBM的Domino邮件服务器相关,单一的项目经验,对我自身的发展有很大局限。况且在Domino日趋衰败大背景下,我想出去呼吸点互联网公司的气息。
在这里,顺便谈下我对外包的看法。这两年多来,我一直是外包到一家跨国的杀毒软件公司,从事测试。在这里我遇到了我工作中的两位Mentor(Rongting & Paul,当然他们是Regular),从他们那我学到了做事的方法,带着我学习提高,解答了我的很多问题,对我帮助很大。遇到了现在的Leader,他对我的信任、认可,让我能有机会做更多的事,像设计测试用例、自动化测试开发、性能测试等。整个Team氛围都很open, 能有机会参加基本所有的项目会议,参与讨论。一毕业就能有机会,在这样的大公司,在各种规范的流程指导下学习工作,我真的受益匪浅。我知道这是我的幸运,不同的项目对外包的工作,管理都是不太一样,和Leader有很大关系。另一个项目外包的同事,进组一年多了,都没机会设计测试用例。这里我想讲的是,虽然外包总给不了人一种归属感,但同时也让你有机会和一群比你厉害的人一起工作,要利用这样的工作机会向同事请教、学习,迅速提高自己。还有一点很重要,一定要自信,如果你觉得你能胜任,就可以争取点不同的任务。
当决定好要换工作后,下面就要开始准备你的简历了。简历是你的敲门砖,用人单位看完你简历后,觉得合适,通过简历筛选,才能够获得面试机会。简历首先要真实,真实反映你所干过的活,所承担的角色,你的贡献,真实反映你的技术背景。面试官一般会围绕你提供的简历,展开提问,你简历上所描述的,你一定要很有把握。第二点,简历拿出来要有亮点。一位测试前辈老师,看完我的简历给我建议是“如果你觉得自己是实力派的人,在简历中要突出你的能力,过去的业绩亮点。”最后一点,如果应聘的是外企,或则职位描述是用英文来写的,一定要附上中英文简历,要准备一份拿得出手的英文简历哦!锦上添花的是,如果你的简历排版简洁(中文简历一般不超过两页),美观,也会为你加分不少。
如何获取职位信息?当我发现我在大型招聘网站(如51job,智联招聘)申请那些我向往的职位都没消息后,我就放弃在这类网站上申请职位了,还发现在这些招聘网站上发布信息的就是那么几家公司,后来都懒得登入这些网站看了。那我的职位信息是从哪来的呢?答案是专业技术论坛,就测试而言,很多公司会在51testing中发布职位信息,我的简历很大一部分都是投给了这些职位。一般还都能收到反馈,即使简历不合要求。十月份的时候,我发现很多人会在weibo上发布职位信息,就开始关注weibo中发布的测试岗位了。后来,要我的那两家公司也都是我在weibo上看到的信息,投的简历。现在想想,在大型招聘网站发布信息的都是HR,他们要在海量候选人中选择,被刷的概率更高。而利用论坛,weibo这些媒介发布信息的都是项目组的leader,他们将身边的一些岗位需求发布出来,有合适的候选人就内推,将来如果你面试成功,他们也可以获得一笔奖金。还有一个好处是,面试结果后,你可以发邮件请帮你推荐的人,查询面试结果。
附上技术博客链接、Github账号,如果平日里你有写技术博客的习惯,或者参加过开源项目,有Github账号,都可以把链接帖在简历上。在面试的过程中,不只一次听面试官跟我讲,“我看过你写的文章,觉得写得挺不错”。这些都会为你的面试加分。
利用好面试提问环节,一般面试结束前,面试官都会问你,有没有神马问题问他的?可以好好利用这个环节,一个漂亮的提问会为你加分哦!
下面谈谈,我面试过一些的公司,以及这些公司对测试工程师的要求,可能具体的面试题记得不是很清了,就写个大概印象吧。● 目前所在的杀毒软件公司 —— 对我帮助很大的一场面试
这是上半年的一场面试,之所以放在这讲,因为这场面试让我认识到自身的一些不足。三月份的时候,在51job上看到南京焦点科技的专场招聘信息,周六下午没事就过去了,后来顺利通过笔试面试,拿到Offer。在我和Leader谈准备离开的时候,Leader又帮我争取到了面试我所外派的这家公司的机会。这算不上一次正式的面试,是周会结束后和QA Manager的一个小时左右的交流。一开始,是我讲进入项目组以来,我学到的知识,干的活,还有就是介绍自动化测试相关的。后来就是老板的提问,到现在我还记得这些问题:
1、作为一名QA,你是怎么理解“质量”这个概念的?
2、Java的垃圾回收机制、内类的几种方式、堆和栈区别
3、在写自动化代码中,用到了哪些设计模式?
4、最近读过的关于软件测试的书,文章?有哪些给你留下了比较深的印象?
5、职业发展规划
回答这些提问时,我发现自己对测试的理解还是不深,对Java中的很多概念还是比较模糊。我突然意识到自己是有多浮躁。面试结束后,老板给了我些建议,弄清基本概念,多读一些优秀的开源代码,不要贪多,一定要深入学习下去。那次面试后,我放弃了焦点科技的Offer,继续留在项目组,又系统学习了Java编程思想,学习Junit那些框架的源码,并开了这个技术博客,逼自己要定期写文章。
● 四战IBM —— 英语口语要求较高
从八月底到十二月初,这短短几个月里,我先后面试过IBM三个不同项目组,前后经历四波面试。七月初的时候,在Lotus中国社区看到Domino组在招测试工程师,就试着投了简历,后来也一直没消息。八月底的一个周二,刚下班接到了北京IBM的电话,约周四上午电话面试。因为现在测试的产品是Hook在Domino邮件服务器上的,在介绍所做的项目是,面试官问得很细致。接着细诉了,关键字实现、框架流程等。下面就是面试官提问:
1、一些STAF/STAX的服务命令。
2、自动化测试如何和CI系统集成。
3、Domino中邮件路由过程
4、算法题:一个字符串,如“This is a test !” ,输出“test a is This”,要考虑空间。
5、设计模式:对单例模式的理解,有几种实现方式。
6、Python:字符串查找
7、口语题:你安排了一次团队活动,现在去给老板汇报,讲清楚:时间、地点、交通、具体活动安排。第二轮的时候,面试官会问,如果有一名RD手头有活,不愿意参加,你怎么说服他参加。
这次面试,答得最差的题是口语题,基本是结巴着讲完的。准备面试的时候,没在网上搜过面经,根本没想过会有口语考核。血的教训啊,我后来面试外企的时候,都会提前问下有没有口语。这里顺便讲下有意思的事,面试完后,我在一个Lotus技术QQ群里问,有没有IBMer,问面试IBM多长时间有结果,没想到的是,居然有人小窗找我,是NW,NW是IBM Lotus Notes组的工程师,NW讲,看到群里的QQ名,猜出了我就是前两天面试的人。原来,我的简历就是他挑选出来的。这个世界真小。后来他帮我查了面试结果,“HELD – wait for manager interview if no better candidate”,评价是“Java基础扎实,有自动化开发经验,但口语有待提高”。后来也没有接到进一步的消息,哎,感叹当了次备胎,失败了。
九月份的时候,在人人网IBM公共主页看到宁波研发中心招聘测试工程师,投简历,电话面试,也没消息了。十月份在weibo中看到发布招聘测试工程师,要求懂Java,有自动化开发经验。投简历,一轮电话面试,居然是IBM System i 项目组,二轮电话面试,后来又没消息了。需要说的是,这两个组的面试也都有英文对话。
十一月底的时候,在weibo中看到老高发的招聘信息,要求“Java编程有所涉猎。软件测试流程和工具熟练掌握。对自动化测试,尤其是GUI程序的自动化测试有扎实经验”。后来知道老高是IBM Lotus Notes组的老板。老高将我的简历给了Domino组的老板沙。周一的时候,沙约我视频面试,当时在Office,没法进行,下午沙和另一位同事,电话面试了40分钟,视频面试推迟到晚上。视频最后,沙问了我期望薪水、到岗时间,最后沙讲,年底了headcount很紧,明年应该会有名额。第二天问NW,NW帮我查了面试结果,从面试记录上看,通过了。周三的时候,收到电话让我填写内部推荐的一个表格,就在我以为没问题的时候,接下来的周一,沙打电话给我,肯定了技术,但是因为年底没有名额了,来年再看。让keep in touch ,坑爹啊!● 百度 —— 技术要求很高
六月份的时候,Paul让我给他一份简历,项目组缺人,结果那次简历没通过筛选。十一月份中旬的时候,百度又在招人,Paul问我要了最新的简历,又帮我推荐了次。Paul还给我讲了可能会问到哪一类的题目,比如算法。当时项目比较忙,考虑到时间有限,我就没花心思去准备算法。这个决定让我很后悔。面试也是,首先自我介绍,介绍所做的项目,在项目中的角色,做了哪些事情。来看看Baidu一面的问题:
1、在自动化实施过程中成本最大的一部分是什么
2、在实现自动化过程遇到的最大困难,是如何解决的?
3、Java:HashMap与HashTable的区别
4、Java:对抽象类与接口的理解
5、设计模式:如何实现线程安全的单例模式
6、设计模式:监听者模式
7、算法题:判断一个链表是否有环
8、算法题:字符串左旋
9、算法题:二叉树中,两个节点间的最大路径。
面试到最后,想死的心都有,算法题懵了。后来在网上搜面经,发现这些都是常见的算法面试题,如果事先稍微准备下,就不会这么被动了。面试结束后,Paul帮我查了下面试结果,Pending。Paul让我准备第二轮面试,接下来的一周,我都在复习算法知识。一周后的周四,二面百度:
1、自动化框架的实现,为什么这么做?
2、自动化过程中遇到的难点,困难?
3、面向对象的特性,简单阐述这些特性带来的优势
4、接口与抽象类的区别
5、异常类处理机制
6、反射机制,在实际写代码中应用
7、final,finally,finalize的区别
8、有没有用过spring框架
9、测试用例设计题:就linux下的CP命令设计测试用例。
10、如果让你设计一些log监控系统,你会从哪些方面考虑?
二面表现一般,但因为一面算法部分答得太差,最后没能进入三面。我的感觉,百度对技术要求真的很高,测试人员面试考算法的很少。如果大家将来面试百度,可以在网上找找相关的面经,做做类似的算法题,会有很大帮助。● 红帽软件(Redhat) —— 各种假设
我是几乎同时接到百度、支付宝、Redhat的面试邀请的。相比其他公司,红帽好像更注重员工的工作习惯的考核。红帽的一面顺利通过,二面结束一周后,查看面试状态“no longer in consideration”。在技术上面的问题,我有印象的好像有这么几道,“自动化框架,关键字实现的Java代码总共有多少行”,“Python程序共有多少个module”,“两个Linux系统之间如何传文件” 。来看看其他问题:
1、如果让你带实习生,实习生每天有很多问题,这可能会打乱你的工作,你会怎么处理?
2、如果到了预订日期,你的工作还没完成,你会怎么办?
3、当你和其他同事,在技术方案的选择上发生争执,怎么办?你会如何说服他
4、用十个以内的词来形容你自己
5、用英文描述下你的兴趣爱好
● 其他一些公司
Dell开始提供面试机会的是一个开发岗位,因为我觉得不合适,HR帮我推荐了一个虚拟化的职位,因为这是一个纯手工测试的岗位,我个人不是太感冒,面试一轮后就没消息了,我想说的是,Dell的HR manager Ripple是我遇到过的最nice的HR了,你有任何疑问邮件咨询,她会第一时间电话解答,并邮件确认。赞一个。HP的职位是我在51job中看到的,但也是发邮件申请的,面试挺顺利的,最后谈到了薪资这一块,但后来居然没消息了,接着传来了HP在裁员的消息。360的面试,就记得问过我,“闰秒”,“32位系统,和64位系统下的测试有何不同”,说实话,这两问题我真不知道。赛门铁克,面过,没留下任何印象。VMWare很向往的一家公司,但自动化测试偏重于UI方面的,问过的技术问题:hashmap与hasptable的区别,讲讲java collection framework的了解,Java反射机制。
● 支付宝 —— make it
支付宝的职位信息也来自weibo,看下面的截图:
投完简历不到一周时间,周四下午的四点多钟接到电话,有点奇怪的是支付宝并没有像其他公司一样,事先约定面试时间,而是直接就开始面试了。面试进行了四十多分钟,比较顺利,最后面试我的女生问,支付宝需要经常加班,你可以接受吗?
接下来的周一,接到支付宝HR到杭州面试的邀请。面试定在周五中午十一点,我是周四晚上到杭州的,住在支付宝附近的汉庭,晚上快十一点了,支付宝大楼依旧灯火通明。第一轮,是两位工程师面的,挺顺利的。很从容的拿着笔在白板墙上讲解自动化框架、流程。面试官问了:
1、自动化测试执行时间,容错处理机制
2、Robot Framework 框架的优缺点
3、自动化测试下一步的有哪些可以提高的地方
4、Java的多态机制
5、平日工作是如何设计测试用例,讲解下目前所测产品的一个模块的测试用例设计策略
6、在整个项目周期中,测试要做哪些事情
第一轮面试,大概进行了一个小时十分钟,接着休息了五分钟后,进入第二轮面试。第二轮面试,面试官是测试总监、HR。第二轮面试,简单阐述了目前的项目,我所做的事情。后来就是提问了:
1、C++和Java对内存的操作有何区别?Java的垃圾回收机制为什么不能避免内存泄露问题?
2、熟悉哪些网络协议?
3、不同网段的两台机器是如何通信的?
4、考研了吗
5、大学同学都从事哪些方面的工作(hr问)
最后,面试结束后,总监问我有什么问题?这个环节我准备的问题是,之前项目周四学习小组一起学习ET时,看taobao的探索式测试白皮书时,提出的疑问。听到这个问题后,总监笑了,说这个问题问得好,但我没法解答你,我也疑惑呢。
当我走出面试的那个房间时,我心里有80%的把握。接下来的两周是漫长的等待,因为支付宝面试不通过是发拒信的,我不时刷新我的邮箱,期盼着结果。最后实在忍不住,托帮我投递简历的人,查看了面试状态,答复“结果还好,但还没最后结果还在确认中”。第三周的时候,接到HR电话,聊了下薪资期望。第四周,开始有点睡不踏实了,真的很渴望这份Offer,我打电话一再和HR确认,周五晚上六点五十,收到了最终Offer。
结束语:大学毕业的那年春天去国展中心的招聘会,人头攒动,那时候的我很茫然,不知道自己能找到什么样的工作,也不是很清楚自己想要什么样的工作。这两年来我一直在努力,慢慢的我知道了自己想要找什么样的工作,渐渐地我也知道了我能找到什么样的工作。这条路,谈不上曲折,我一步步踏踏实实地走来。 -
测试修炼之道(转)
小_依凡 发布于 2013-03-01 11:28:22
这篇文章看了感触挺多的,而且也想采用此修炼之道也好好修炼自己,自己保存着有用,也想与大家分享这篇文章。
正文:前言
软件测试发展到今天,已经逐渐形成一门学科,但是还不够系统。
初学者面对铺天盖地的资料应该如何选取?应该从哪里入手?如何迅速的掌握各种业务各项测试技能以便开展工作?在保证测试质量的前提下,一日内编写或执行1000个测试用例是不是梦想?
入行多年者面对复杂的业务逻辑,海量的测试需求,如何在最短的时间内进行测试?如何尽可能更早的开展测试?如何对系统架构进行测试?如何全面提高测试质量与测试效率?如何百尺竿头更进一步?
本文将针对这些问题进行初步解答,主要阐述解决这些问题应该具备哪些能力及如何锻炼这些能力,至于实际工作中解决问题的具体操作步骤本文不做表述,可关注后续文章。前两章主要探讨一名合格的测试工程师应该具备哪些能力,对列举的能力将会做简要说明。第三章重点说明应该如何锻炼这些能力,此为本文的重点。最后一章是笔者对软件测试虚无缥缈杂乱无章的一些想法。
本文的读者群涵盖所有对软件测试感兴趣的朋友。
下面,我们开始。
第一章 综合素质
笔者以为,作为一名合格的测试工程师,综合素质是最重要的,综合素质也就是我们常说的软技能,它代表着一个人的潜力有多大,未来发展有多宽广。核心素质有以下五点:沟通、分析、组织、学习、心态,下面将会分别阐述。
沟通
作为一名软件测试工程师,优先加强的应该是哪方面的沟通能力?是文字沟通能力。试想,如果连缺陷描述都无法准确清晰的用文字表达出来,还有开发愿意和你合作吗?特别是随着异地开发的项目越来越多,文字沟通的场景也会越来越多。
当然,口头沟通也很重要,通过面对面或者电话语音交流是很直接的方式,这也是为什么许多鼓吹敏捷开发的团队喜欢坐在一起的原因,认为这样会降低沟通成本。但事实上,真的在任何时刻都能降低成本吗?无效冗长的会议大家都参与过,这里不做深入讨论。
不知道其他人有没有这种体验,笔者偶尔在查阅测试用例库或阅读工作邮件的时候会忍不住哈哈大笑,语句不通错别字也就罢了,写的像聊天记录一样尽是口头语就让人很无奈了。
所以,这里首先强调的是提高文字表达能力,其次才是口头沟通能力。
另外要特别注意的是,沟通能力包含两方面,一方面是说(写),一方面是听(读),表达与聆听同等重要。笔者发现很多测试工程师表达能力不错,但聆听能力很差,有时候甚至忽略聆听。对方话没讲完就急匆匆的打断,即使听了两句也马上反驳对方,这是恶习,比抽烟喝酒打老婆还要恶虐。
分析
早期我们认为测试的唯一工作就是发现问题,在很多文献资料上均有类似描述。但笔者以为,测试发展到今天,单纯的发现问题已不再是测试工作的全部,测试工作应包含发现问题、分析问题、解决问题三个方面。发现问题以测试人员为主开发人员为辅,分析问题开发测试共同完成,解决问题以开发人员为主测试人员为辅。
在测试工作中每时每刻都需要用到分析能力,同时,分析能力是评估一名测试工程师是否优秀最重要的考核点。就像我们常说的缺陷预防一样,怎么预防?对已发生问题的产生原因能准确定位并把类似问题进行归类,对未发生问题能充分预知风险并准备应对方案,这就是我们追求的零缺陷,这些工作有不需要高度分析能力的吗?
再例如测试计划,我们做计划是拍脑袋乱猜吗?是掐指算命吗?肯定很多人回答不是,但实际上往往很多人就是这么做的。测试计划的制定过程是首先收集大量相关信息,然后抽丝剥茧在杂乱无章的信息中寻找到关键点并梳理清脉络,最终据此定出计划。我们说部分未来是可以推测出来的,就是这个道理。在做计划时会用到许许多多辅助分析的理论方法,这里就不一一阐述了。
艾森豪威尔有句名言:“A plan is nothing,planning is everything.” Planning就是分析的过程。
组织
刘备自己不会带兵打仗,为什么他下面的五虎将会死心塌地的服从他?因为五虎将会将兵,刘备会将将。“运筹帷幄之中,决胜千里之外”,这是帅才;“三军中取敌上将之首级如探囊取物”,这是将才。帅才也好将才也好,都离不开组织能力。这里说的是广义上的组织能力,不仅仅指团队管理、跨部门协调这些内容。
不少人认为开发与测试的工作是对立的,经常会有冲突,没错,的确会有。出现冲突怎么办?这时候需要通过高度的组织能力对双方的合作关系进行充分的调整。人与人之间本来就会不断的有磨擦,有人的地方就有恩怨,有恩怨就有江湖,人就是江湖。那为什么有的人能左右逢源,让人感觉与他合作如沐春风呢?这就是组织能力的表现。
再比方说,在真正的敏捷团队中,无论工作有多苦多累,无论团队成员构成有多复杂,整个团队都会有一个共同的表象,那就是“开心”,真正的敏捷团队一定是个开心的团队。所以笔者常说,敏捷团队的领导者一定要有非常强烈的人格魅力,能牢牢的把整个团队凝聚在一起,这种人格魅力往往就体现在组织能力上。
有人也许会问,举办大型活动算不算组织能力的体现?算,当然算。但现在很多人白白浪费了这样的机会,在筹备过程中仅仅起到工作分解或传声筒的作用,可惜。
学习
“一目十行过目不忘”,这种天才是有的,笔者非常羡慕有时甚至是嫉恨他们。普通人需要花费一两年才能掌握的知识,这些天资纵横的人只用一两天就可以了,并且很多技能仿佛天生就会,根本不用后天的学习。幸好这种人非常少,否则根据社会达尔文主义的观点,我们普通人没有任何生存空间。
软件测试从业人员有个明显特点——复合型。“知己知彼百战百胜”,当我们要对某项产品进行测试,那么必然要先了解此产品的各种背景,这导致测试人员需要学习各种各样的知识,并且要不断的学习,快速的学习。入行几年后或许我们会感到掌握的技能杂而不精,此时需要深入的学习,全面的学习。
学习能力往往被看作是一个人有无潜力的重要标志,针对软件测试工程师而言,“快速学习”尤为重要。笔者一直想寻找一种方法,能让测试人员不了解行业背景不懂测试技术也能正常开展测试工作,但可惜的是一直没找到。那么变通下,通过“快速学习”是否也能达到类似的效果呢?应该是可以的。
学习最核心的是什么?知之者不如好之者,好之者不如乐之者。
心态
多年前笔者读过一篇文章——《写给浮躁的IT同仁》,读后深有同感。一个浮躁的社会造就了众多浮躁的人,软件测试本该是个做学问的领域,可惜啊可惜。
人往往是自私的,荀子曰:“人之初,性本恶。”笔者深以为然。绝大多数人都认为自己是最可怜最委屈最被不公正对待的,扪心自问真是这样吗?佛教有个观点“明心见性”,这是笔者孜孜不倦所追求的精神境界,与大家共勉。
大家应该都明白,没有绝对的公平社会,从来就没有,纵观古今中外历朝历代什么时候绝对公平过?我们不要一味的怨天尤人,如果改变不了环境就努力的去适应它,这是升斗小民应该具备的心态。
先做人后做事,不论是综合素质还是专业技能,在所有能力中,心态是最重要的。但要特别说明下,心态和态度不是一码事。此外,有人认为工作态度高于工作能力,笔者并不赞同这种观点,更有甚者把工作态度与是否听话混为一谈这就更扯淡了。
国人讲究“君以国士待我,我必国士报之”,一颗平常心加上一颗感恩心,足够了。
第二章 专业技能
《笑傲江湖》里有写到华山派分为剑气二宗,金大师在书中是褒扬剑宗的,令狐冲全无内力单凭神鬼莫测的剑法就打遍天下无敌手。那么在测试领域里,方法与技术哪个更重要?此话题争论太多一时半会说不清楚,但笔者是赞同方法更重要的。有道是万法归宗,一力降十会,就是这个道理。下文所说的技能涵盖了方法与技术。另请注意,当专业能力上升到一定程度后,需要从广度转为深度,即要在某一特定领域内做深做强,切勿变成杂而不精。
测试方法
目前测试领域内大大小小的测试方法上百种,有的被广大测试工程师所接受并在实际工作中大量运用,有的仅停留在理论研究阶段,还有的只是某些机构为了发表学术论文东拼西凑胡乱编造的。那么这么多方法应该如何选择?《神雕侠侣》里有这么一段:
法王笑道:“人各有志,那也勉强不来。杨兄弟,你的武功花样甚多,不是我倚老卖老说一句,博采众家固然甚妙,但也不免驳而不纯。你最擅长的到底是那一门功 夫?要用甚麽武功去对付郭靖夫妇?”这几句话可将杨过问得张口结舌,难以回答。他一生遭际不凡,性子又是贪多务得,全真派的、欧阳锋的、古墓派的、九阴真 经、洪七公的、黄药师的,诸般武功著实学了不少。这些功夫每一门都是奥妙无穷,以毕生精力才智钻研探究,亦难以望甚涯岸,他东摘一鳞、西取半爪,却没一门 功夫练到真正第一流的境界。遇到次等对手之时,施展出来固然是五花八门,叫人眼花撩乱,但遭逢到真正高手,却总是相形见绌,便和金轮法王的弟子达尔巴、霍 都相较,也是颇有不及。他低头凝思,觉得金轮法王这几句话实是当头棒喝,说中了他武学的根本大弊。
杨过第一反应是什么呢?
他走出茅棚,在山顶上负手而行,苦苦思索,甚是烦恼,想了半天,突然间心念一动:“我何不取各派所长,自成一家?天下武功,均是由人所创,别人既然创得,我难道就创不得?”想到此处,眼前登时大现光明。
最终他的决定是什么?
杨过睡了半夜,次晨一早起来又想。七日之中,接连昏迷了五次。说要综纳诸门,自创一家,那是谈何容易?以他此时的识力修为固然绝难成功,那更不昃十天半月 间之事。但连想数日之後,恍然有悟,猛地明白诸般武术皆可为我所用,既不能合而为一,也就不必强求,日後临敌之际,当用则用,不必去想武功的出处来历,也 已与自创一派想差无几。想明白了此节,登时心中舒畅。
这就是笔者想要表达的。作为一名合格的测试工程师首先一定要见识广博,最新的行业动态,各种测试方法等等都需要了解。然后在此基础上,实际工作中需要用到什么方法就用什么方法,信手拈来,千万不要书到用时方恨少。笔者一直在劝喻团队中的工程师,不要整天只知道埋头干活像鸵鸟一样,要经常抬起头来放眼看世界,井底之蛙坐井观天是要不得的,这样下去路只会越走越窄。最后,当各方面积累到一定程度会发生量变到质变,如果还具备过人的天赋并能百尺竿头更进一步,则可开宗立派自成一家,就象杨过最后自创“黯然销魂掌”一样。
笔者在日常工作中最常用的是路径法、场景法,以组合测试、探索性测试作为辅助。路径法主要用来做测试需求分析,关注的是节点;场景法主要用来做测试设计,关注的是路径;组合测试主要用来对规则性的用例进行筛选,减少测试用例数量;探索性测试主要用于交叉测试或测试大扫除之类的测试活动。这些方法的详细论述网上有很多,这里就不一一阐述了。如何把这些方法贯穿在一起?之前的分享有详细表述过,这里也不啰嗦了。
现在业内有两种测试理念很流行,一种是基于模型测试(MBT),一种是云测试。笔者以为这两种测试方式一定是未来测试行业发展的大方向。随着测试智能化的发展,今后测试工程师入行的门槛会越来越低乃至于消失。到那时,只需要很少一部分测试精英维护测试智能化平台,其它大部分的测试工作可交由任何人来完成,真正实现“IT民工”的梦想。
很多人应该都读过“四人帮”的《设计模式》,大多数人虽然看不懂但都明白这是核心,是重中之重。测试方法也是如此,它是测试工作的灵魂,测试用例与测试脚本孰重孰轻?不言而喻。
最后说明一点,在笔者印象中测试人员是肯定要参与需求分析及系统设计过程的。记得很早前有位工作十来年的开发工程师对笔者说:“你真牛叉这些工作你都参与”。实际上他没明白,这本身就是测试人员的工作,测试人员本来就需要具备这些能力。所以笔者总说现在国内合格的测试工程师很少,大部分都是滥竽充数,同时也是笔者为什么在所带领团队中大力提倡组员多研究测试方法的原因。
基础技能
基础,或许说基本更合适一点。工欲善其事,必先利其器。前面已经谈到测试人员是复合型的,要对待测产品的行业背景、技术背景有深入了解。在测试智能化远没有发展成熟的今天,测试工程师必需掌握基础技能。
笔者遇到过不少刚入行的新人,他们问的最多问题是“测试人员是否需要懂编码”。笔者一般回答“欲穷千里目,更上一层楼”。其实不仅仅是测试人员,但凡和技术沾边的工种都需要懂编码。编码是最基础的技能,无论哪一门语言,至少要会一种,如果能再具备一定的产品开发经验那就更好了。但请注意,过犹不及,不要单纯拿编码能力的高低来衡量测试人员水平的高低,测试人员最核心的技能仍是在测试设计上,不要本末倒置。
同样,像数据库、操作系统、网络协议、建模等等都属于基础技能的范畴。可能测试人员在这些技能的掌握程度上没有专业人士强,没关系,因为这些技能最终是为测试专有技能所服务的,如此而已。当然,如果个人有兴趣深入研究那是最好。笔者记得刚接触Linux系统的时候拼命读源码,刚接触网络协议的时候厚厚几本《TCP/IP详解》放在床头,可惜的是都没坚持下来。
为什么说测试工程师转岗容易?现在该明白了吧。
测试模式
瀑布开发、快速开发、迭代开发、敏捷开发等等等等,这么多开发模式听着是不是犯晕?探讨哪种模式更好其实是扯淡,就象探讨是由“开明君主治理的封建制度国家”好,还是由“腐朽无能政府统治的民主制度国家”好一样,均属于哲学问题。同理,测试模式有V模型、X模型、H模型、前置模型,淘宝还提出了SPR模型以及最近正在探索的CCI模型,哪种更好?合适的就是最好的。
尽信书不如无书,这道理很多人都说懂,实际上呢?大多数人依然是照本宣科,死搬硬套。在大多数情况下,工程师应该尽量追求神似而不是形似,特别是奋战在一线的工程师,要明白“将在外君命有所不受”的道理。在当前以结果为导向这种西式管理的氛围下,更多的是要拿出让各方面满意的成绩单。当然,也有部分人以此为借口逃避流程逃避制度,高举敏捷大旗却行偷懒之实。要知道能量守恒,在某方面偷懒在其它方面会付出更多,这样做其实是把自身工作转嫁到他人身上,比方说把自身应该完成的保证产品质量工作转嫁给他人,这样的人要招天谴。“适可而止”这四个字说起来简单,真要做到非常难,需要大量的实践经验,这也是为什么测试工程师职业生命周期较长的原因。
笔者认为,在当下绝大多数项目团队里,V模型足够使用,或者在部分地方进行改良即可适应项目团队工作的需要。要知道,经典是永远不会过时的。那么在行政体系上呢?一个测试部门应该采用怎样的组织结构?目前流行的是一分为二,一部分做技术支撑,另一部分做产品测试,还有极端的是测试人员只做测试技术支撑,产品测试交由开发人员自行完成。至于在产品测试里再细分单元测试、集成测试或功能测试、性能测试等角色,窃以为不需要,因为在广义上,都是功能。测试要做的就是V&V,检验已实现的功能是否正确,检验是否正确实现了功能。
测试工具
这里所说的工具是广义上的,可以说各种各样只要能辅助测试人员开展测试工作的工具都包含在内。
为什么Mercury(笔者还是习惯称为mercury而不是hp)的产品能得到广大测试工程师的认可?因为它满足了测试工程师工作的需要。工具干嘛用的?辅助测试工作用的。笔者一直觉得Mercury的架构师真是不得了,产品设计的如此漂亮。什么是测试架构师?这就是。
测试工具有很多,这里不一一列举了。每年国际上会评选年度最佳测试工具,有兴趣的朋友可以多了解下,这算是测试工具的风向标。
有人曾经争论什么才能称之为测试工具,例如针对某一特定产品开发的一段测试代码是否算是测试工具。笔者以为,从广义上讲是,但在通常所说的范围下不是,因为它不具备通用性,它只能为特定产品服务。所以笔者常常告诫测试人员,第一不要总吹嘘自己开发了多少测试工具,充其量那只能算是一段测试代码;第二要理解测试工具的本质,开发了一堆工具结果根本不能有效提高测试质量、测试效率,无法帮助测试人员发现更多的缺陷,有意义吗?
当然,有一点肯定没错,多试用不同种类的测试工具并研究其原理,如果能对其进行改进,那么恭喜,离专家又进了一步。
第三章 能力修炼
修炼要素
以下列举的十八要素仅供参考,这些要素并没有优先级或前后顺序,但有一点是必需确保的,那就是坚持,至少坚持一个月。如果能把全部要素坚持做一个月,笔者保证测试工程师自身能力会有大幅度提高。如果能坚持一年甚至更长时间直至养成习惯,那么恭喜,离牛人不远了。
1、 每日至少抽出30分钟关注测试行业新闻,包括各种业内动向,技术前沿等。推荐国内网站:51testing、ITPUB、Javaeye、infoq、博客园、Oracle中国用户组……。
2、 每日写一篇博文,200字左右,记录当日工作完成情况及次日需完成工作,流水帐也可。
3、 每晚入睡前回顾当天表现,检讨一言一行。
4、 每日清晨计划当日需完成工作并确定优先级。
5、 每日早晚对着镜子微笑一次。
6、 每日阅读,书的种类不限,不一定是技术类。
7、 每日选取一位从来没交流过的同事进行交流。
8、 每日至少编写30行代码。
9、 每日收看新闻联播,重播也可。
10、 每日洗澡。
11、 至少每隔两日看一集推理类电视剧,推荐《金田一少年事件簿》。
12、 至少每隔三日参加一次益智分析类游戏,推荐“围棋”、“三国杀”。
13、 每三日研究一个技术类工具并发表研究文章,推荐从Excel开始研究。
14、 每周至少与朋友外出活动一次,推荐极放松的活动,例如喝酒。
15、 一周内不要连续两天加班。
16、 每周至少一次与上级开展交流。
17、 每月至少单身外出一次,推荐西湖边静坐。
18、 每月至少储蓄20%当月收入,至多储蓄60%。
测试工程师的一天
7:30 起床
7:35 洗漱,计划当天工作
8:00 出门,面对镜子给自己个微笑
8:30 早餐,什么都不要想
8:50 公司,开机接收邮件、消息
9:10 浏览业内新闻
9:40 大多数人已到公司,开始当天工作
12:00 中饭,小饭桌上别谈工作更别一副忧国忧民的样子大谈国计民生
13:00 技术研究并沉淀
14:00 继续本日工作,编码,主动与没交流过的同事进行交流,组织晚上活动
18:00 晚饭,总结本日工作
18:30 撰写当日工作博文
18:45 加班
19:45 三国杀
21:00 回家,洗澡
21:30 中央新闻频道,喝酒
22:00 电视剧,喝酒
22:30 读书,喝酒
23:00 上床,自我反省
23:15 呼呼呼呼
注意:以上主要表达一种思路,勿纠结勿全部模仿。
进阶目录
通常情况下,能力提升是一个渐进过程,但提升到某一高度遇到瓶颈时则需要突破。这有点类似大乘佛法里所说的,从渐修到顿悟,再从顿悟到圆修。本身中国佛教界对此就有不少争论,南方慧能系(称南顿)与北方神秀系(称北渐)分别讲究顿悟与渐悟,而在顿悟中又有道生顿悟、禅宗顿悟,所以说每个人的进修道路是不尽相同的,也不一定有高下之分,主要看对自我认知是否清晰,在不同阶段需要何种提升方式,这才是重点。
在个人能力提升的道路上,上级主管的支持及培养是非常重要的。好主管会因地制宜因人而异,每次安排超出其能力一点的工作,让其不断的有挑战。同时在实施过程中,主管会默默支持,与其一同制定解决方案并跟进实施过程,最终让其独享成功的成果与喜悦。
此外,每人擅长的领域不同,有的人所具备的能力很契合当前工作,因此会成为主攻手,有的不太符合只能做辅助。但请注意,在多方协作工作中,必然有人在前攻城拔寨做明星,有人在后默默耕耘做后勤,这些不能单纯的以高下来衡量,况且说不定哪天换成其它工作,这主次之分就倒过来了。
以下是能力渐进提升的阶梯目录,从前到后有顺序之分。
1、 基础:前文所说的基础技能必需掌握,推荐Java+Oracle+Uml组合。掌握程度一般不用太深,测试工具开发职位的除外。特别注明,Junit是一定要掌握的。市面上书籍很多,笔者推荐《Java编程思想》、 《Oracle 9i 参考手册》、《UML精粹》。
2、 专业:前文所说的测试方法、测试工具必需掌握。其中对于测试工具,如果开源则尽可能阅读源码。推荐书籍《计算机软件测试技术》、《软件测试艺术》、《软件测试》。
3、 实战:前文所说的测试模式必需掌握。 至少全程参与二十次项目,至少参与两次50人以上规模的项目,至少编写测试用例10000个,至少发现缺陷5000个,至少编写测试脚本20000行,至少担任过三次测试负责人,所有产品发布后遗漏缺陷总数小于50个并呈收敛趋势。推荐书籍《设计模式》、《人月神话》、《软件测试经验与教训》。
4、 沉淀:深入了解质量控制原理,对功能性(含安全)、效率、易用性、可移植性、可维护性、可靠性等质量特性均有实际测试经验。推荐书籍《质量无泪》、《质量免费》、《ISO9126》等所有软件质量相关国标。
5、 领域:选取一至两门测试技术作为长期研究的方向,中途可适当调整,这里说的长期指的是五年、十年及以上,在这个层次重点是要做到专精。推荐方向“云测试”、 “基于模型测试”。
6、 专家:理论计算机科学研究。笔者不是专家,因此不敢臆测到达此层次后应该做些什么以及怎么做,但“P/NP问题”是笔者一直有兴趣并持续关注的,也是很多科研工作者选取的研究课题,在此郑重推荐。
第四章 杂谈
笔者刚入行时有次参加公司组织的培训,是一个微软的老外来讲课。培训那天会议室的前三排基本没人坐,有位副总站起来骂“这就是Chinese”,当即有人反问“你不是Chinese?”,说起来他还真不是,已经移民到加拿大了。做人切勿忘本,做事前要先学会做人。作为一名测试人员不要崇洋媚外迷信权威,但也不能做土八路。业内一般的说法是“做事要高调做人要低调”,笔者以为“做事要高调做人也要高调”,心有多大,舞台就有多大。
测试行业发展到今天需要求新求变,就象当年武侠小说一样。笔者一直很喜欢古龙,不知道谁能成为测试行业的古龙。
有位伟人曾经说过,“不管黑猫白猫能抓到老鼠的就是好猫”。同理,不管黑盒白盒能找到缺陷的就是好盒。工作中不论用的是正道、奇道还是王道,不论用的是阴谋还是阳谋,能解决问题的就是我们所需要的。
男女搭配,干活不累,这是至理名言。测试团队的男女比例1:3最好。
社会是个大染缸,测试人员要保持一颗纯真的心。做事要又猛又持久,做人要很傻很天真。
世上不如意事十常居八九,人生总会经历很多挫折。真的爷们,敢于直面惨淡的人生,敢于正视淋漓的鲜血。如果不爱测试,请尽早离开。
后记
终于写完了,原本就想写一千来字的,结果提笔后洋洋洒洒的写了这么多,看来还是高度不够,语言不够精炼。
文中提到的锻炼方法还有待临床验证,故征集小白鼠,欲被蹂躏者可向笔者报名。
笔者已能预计到本文发出后会引来多少质疑与唾骂,但没关系,“我可以不同意你丫说的话但我誓死捍卫你丫得瑟的权力”。欢迎大家拍砖,争议越多越好,讨论越激烈笔者越出名,哇哈哈哈哈。
转自:http://blog.163.com/tech_qa/blog/static/13017634920101114113413470/
-
QTP脚本手动编写(转)
iseedeadpeople 发布于 2009-12-22 11:46:59
QTP采用的关键字驱动与专家视图的设计思想,不但可以自动生成代码,使初学者快速入门,更为高级测试人员提供了便利的编程界面,使其可以高效的完成自动化测试脚本,不用完全依赖于录制和回放过程。下面就我个人的使用经验,简单谈谈如何不依赖于录制和回放来完成QTP脚本的。
操作步骤很简点,主要分为三步:
第一步,维护对象库,添加必需的对象以及配置对象的属性。
第二步,在专家视图中,编写测试代码。
第三步,运行并调试代码。举个简单的例子。
以在51testing的网站上搜索关键字QTP为例。
首先,打开QTP,点击工具栏上的Object Repository按钮,打开对象库维护界面。如图一(图片暂时上传不了)
点击Add Objects按钮,添加站内搜索的文本框以及后面的查询按钮对象,如图二然后,在专家视图中,手动输入如下代码:
Browser("软件测试专业网站:51Testing软件测试网").Page("软件测试专业网站:51Testing软件测试网").WebEdit("keyword").Set "QTP"
Browser("软件测试专业网站:51Testing软件测试网").Page("软件测试专业网站:51Testing软件测试网").Image("GO").Click由于录制的过程中,待测试的页面是已经打开的,所以为了保证这个测试的前提条件,在前面添加打开IE的语句。
SystemUtil.Run "iexplore.exe",""这样,使用QTP的自动化测试脚本就完成了,运行看看是否通过?结果是一次性通过,而且没有其他需要修改的地方了。
还可以在此基础上增加关闭所有IE的函数,增加验证点等等使脚本更加健壮和完整,这里就不赘述了。
如果使用录制和回放的方法来开发脚本,可能存在以下几个问题:
一个是自动生成的代码有一些是没有用的,有时候反而会影响代码的质量;
一个是通过录制生成的代码,健壮性都不好,如果要使脚本在无人值守的情况下顺畅地运行,还是需要手动修改的。比如在对象找不到的地方增加判断对象是否存在,再继续下一步操作等等;
再有,就是录制的过程中,会使你的对象库中多出来一些脚本正常运行以外的多余的对象,给维护对象库也增加了工作量。
比较这两种方法,总体感觉直接添加对象并编写代码的方式,可以弥补录制回放过程的不足,节省了脚本的开发时间,减少了对象库的维护工作量,大大提高了自动化测试脚本的开发效率。
当然,能够这样做是有前提的。
第一,必须对待测试的系统非常熟悉。即开始写自动化脚本之前就能从大脑中反映出每一个步骤中需要的对象及操作。
第二,对QTP的工作原理以及工具本身非常熟悉。能够有办法解决脚本运行时出现的任何问题。
第三,有良好的编程基础尤其是针对VBscrīpt语言的。如果对于代码的结构、可维护性都把握很好的话,那么效果就会更加明显了。补充一点,使用这种方法,你的对象库的设计一定要到位,保证在写代码的时候,很容易的找到你要操作的对象,否则就得不偿失了。
-
【QTP系列讲座 4】 == 资源池 ==
iseedeadpeople 发布于 2009-10-21 12:31:25
当我们在写完公共函数库的时候,我们就可以通过资源池来灵活的调用我们之前的函数库
下面就来介绍一下
首先我们新建一个"test.txt"文件
内容如下
- function hello_world_msg(tt)
- msgbox tt
- end function
- function hello_world_add(a,b)
- msgbox a+b
- end function
保存在D:\test.txt
1.我们打开QTP,新建一个TEST
2.选择菜单栏的FILE-->SETTING
3.选择RESOURCES,把刚才的d:\test.txt添加进资源池
4.点击OK
点击F7 弹出step generator
category: Function
library: Library Functions
选择我们刚才写的那个函数并输入参数点击确定
QTP就自动生成了一段代码
- hello_world_add 1,2
执行一下是不是弹出
其实我们还可以使用另外一种更加快捷的方法来写这个函数
那就是使用前面一章所讲到的COMPLETE WORD来快速编写函数
不熟悉的朋友可以去学习下:http://blog.csdn.net/zzxxbb112/archive/2009/08/31/4503585.aspx
选择后直接回车后,会显示相应的参数名
然后输入参数就OK啦~
-
QTP编码小技巧集锦
iseedeadpeople 发布于 2009-10-20 18:17:09
随着web开发技术变得越来越复杂,使QTP在处理web对象时也变得不那么容易,但是很多时候还是能通过调整对象属性的技巧,达到正确识别我们想要的对象(Web元素)。这同时也就提出了更高的要求,要能够了解一些Web开发的知识,分析测试页面的源程序。当然光分析仍然是有些马后炮,更好的应该是在界面开发时就为以后自动化测试做准备了。
确实在QTP的对象识别过程中,让QTP用户尤为头疼的就是对象识别。而当QTP识别不了对象时候,就不负责任的丢了一个"WebElement"给大家,而每个人都觉得这不是我想要的结果。那么如何更好的把这个WebElement做出我们想要的效果与操作呢?
……
详情请查看:http://www.51testing.com/html/74/n-108374.html
【QTP编码小知识 四 对象库与索引值】偏向喜欢使用对象库操作的QTP用户,在添加对象时候,会出现某几个子对象,都识别成一个对象,因为里面的所有属性几乎是一样的,很为难的不知道如何解决这个问题,借鉴与描述编程中的索引值index的使用,例如:
dim Input_Dec
set Input_Dec=description.create()
Input_Dec("Html tag").value="Input"
Input_Dec("Index").value=1
.....如何把index添加进去或者如何把这些描述的东西添加进去?在这里给了大家一个小的html page,大家下载下去后,可以先试试看,然后再看看下文,如何使用Index。自然这个不会识别成一个对象,因为它们的类型有区别,只是特定或者模拟某些情况而已。
……
详情请查看:http://www.51testing.com/?action-viewnews-itemid-96772
由于编码小知识出到第三帖,特此帖送出API手册一份,想要会自动化,还离不开Win32 API。
先说下小编对关于Web内存的一些小看法,之前已经有讨论过关于IE内存占用居高不下,导致了QTP对Web页面的操作出现种种问题。今天和大家说下简单的内存释放方法。首先我们使用的将浏览器最小化然后再做最大化的操作来实现这个释放工作。很多人知道,IE最小化后,内存占用不到2M,最大化后,会比之前最小化前占的内存更少。
……
详情请查看:http://www.51testing.com/?action-viewnews-itemid-94271
大家看看下面代码,代码是运行在谷歌的主页面,如果大家要试的话,大家同样也可以试试这代码的运行结果。
Dim LinkDes
Set LinkDes=description.Create()
LinkDes("html tag").value="A"
Set LinkObj=browser("Google").Page("Google").ChildObjects(LinkDes)
For i=0 to LinkObj.count
LinkObj(i).click
browser("Google").Back
Next代码运行完后,你会发现,原来在循环第2次连接点击的时候,抛出了一个“General run error”。这个是为什么会这样?之前也同样有论坛的朋友问到这样的问题,所以今天就在这里提到。
问题是出在了对第一个连接点击后,做了返回操作所导致的,在第一次back的时候,LinkObj对象就已经丢失了,失效了。所以你在做第2次操作的时候,LinkObj(i)就已经找不到了,因此它会出错。
正确的方法,这个也是我目前想到的,或者还有其它达人能做更好的方法出来。
……
详情请查看:http://www.51testing.com/html/52/n-93852.html
你学习过 了编程,知道了,如果and的条件,如果有一个否,哪么就全部为否,自然是这个是逻辑条件的问题,你有学过,所以你写成2个and的方法去简略代码。但问 题往往发生在这里,就和变魔术一样,大人看不出,但小孩就可以看出里面的问题,因为成人的思想会被自己所谓的经验所左右。
这段代码的错误地方发生在那里,估计读到这里的人大部分已经猜到了,错误会发生在第1片中的2 3行!!你会问为什么?这应该没错才对的呀?
详情请查看:http://www.51testing.com/?action-viewnews-itemid-93797
版权声明:以上作品均为51Testing软件测试网原创,由会员假装不在提供。原创作品,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明,否则将追究法律责任。
相关阅读: -
QTP工作原理的学习心得
iseedeadpeople 发布于 2009-10-20 16:31:36
一直认为学习一个工具一定要学会它的本质和原理才能真正的有所收获,不然工具换掉或者工具被淘汰就会很尴尬,又要从头学习。当你学会了本质,其他的工具学习起来也会很快的,并且从开发的角度去思考问题,更容易学习好一个工具。最近学习了几天的QTP,对QTP的原理有一个简单的认识,和大家分享下。个人认为QTP的脚本运行其实就是一组对象有组织的执行自己的方法,最终完成一个流程的过程。当打开一个web时, 想要脚本能够模拟人来操作整个流程,那多就要求这个脚本能够识别人的每一个操作,而人的操作实际上是对web页面上控件的操作,所以只要QTP的脚本能够 识别人操作过的控件就可以模拟人的操作流程,而web页面上的控件都是QTP脚本中的对象,也就是说只有QTP脚本中的对象能够被唯一的识别出来,就可以 模拟人的整个操作流程。而QTP又是如何识别对象的呢?
对象识别原理就是获取hwnd,然后判断ui属性,逐个判断,然后逐层递归,最 后获取每个对象的所有层面的属性,跟对象库里的属性进行比较,匹配则应用。也就是说在你添加一个对象到对象仓库中的时候,该对象的主要属性都被保存到对象 库中了,回放QTP脚本的时候实际上就是在被测试软件中寻找指定的对象,然后按照这些对象指定的方法去完成一个动作,而这些方法就是把windows win32中、web上的一些activex控件中的方法和微软控件对外的接口中的一些方法进行封装,成为qtp自己的方法。对于任何一个add-in都是先找到人家的对外接口,然后拿过来封装,需要的时候去调用接口事件,也就成为了QTP的动作。
所以QTP脚本回放实际上就是要做两个步骤:1)识别出要操作的对象控件。2)识别出对象控件后来完成该对象控件指定的方法。
在QTP识别对象的时候是按照对象的唯一属性来区分的,有时候QTP对象仓库保存的对象属性是不完全的,导致两个很相似的对象不能够识别出来,这样脚本 就会报错,或者说对象仓库中对象的属性每次都是变化的,那么每次回放脚本也会和对象仓库中保存的不一致导致脚本报错。这里介绍一个很好用的web对象的属 性——object属性。
QTP支持直接访问DOM,可以通过DOM来访问HTML标签。在QTP中,访问DOM是通过使用page测 试对象的object属性来进一步访问的,这样就可以访问到很底层的对象属性,可以用底层的对象属性来唯一区分web页面上的对象控件,这样就能够解决一 些关于对象识别的错误。
用page页中的Link对象举例说明object属性:
Browser("网易").Page("网易").Link("VIP收费邮箱").CheckProperty "URL",http://vip.163.com/
其中使用了CheckProperty方法来对比Link对象的URL属性是否等于指定的地址(http://vip.163.com/),也可以用Link对象的object属性中的herf属性来对比,代码如下:
herf = Browser("网易").Page("网易").Link("VIP收费邮箱").Object.href
If not herf = "http://vip.163.com/" Then
reporter.ReportEvent micFail,http://vip.163.com/, herf
End If
-
测试人员要注意的cookie and Session 区别
iseedeadpeople 发布于 2010-05-07 17:57:06
说明什么是http cookie?并解释“如果访问ASP网站的浏览器不支持Cookies,则不能够使用ASP的session对象来存放数据”这句话的含义。
答:Cookie是在HTTP协议下,服务器或脚本可以维护客户工作站上信息的一种方式。Cookie 是由Web服务器保存在用户浏览器上的小文本文件,它可以包含有关用户的信息(如身份识别号码、密码、用户Web站点购物的方式或用户访问该站点的次数)。无论何时用户链接到服务器,Web站点都可以访问Cookie信息。
Session是前端浏览器与服务器每一次会话的表示变量,它附在每次会话的所有网页数据中,在一段时间内有效。每个访问用户都可单独拥有一个Session变量,存储会话的信息。
Session与Cookie概念相似,区别在于,Cookie是把信息记录在客户端的浏览器中,而Session对象则把信息记录在服务器中。
Session是存储在服务器端的,但是SessionID是以Cookie方式存储在客户端的,客户端没有了Cookie再燃就找不到Session,也就不能够使用Session对象来存放数据了。 -
还有人不明白bug级别这回事!!!
iseedeadpeople 发布于 2011-03-01 16:10:14
ss级别 -阻碍测试 block
s级 — 严重缺陷 critcal
1. 系统崩溃
2. 导致程序重启,死机或非法退出
3. 死循环
4. 数据丢失或异常
5. 硬件故障
A级 — 重要缺陷 major
1. 功能不符合用户需求
2. 数据计算错误
3. 业务流程错误
4. 程序接口错误
B级 — 普通缺陷 minor
1. 数据长度不一致
2. 内容或格式错误
3. 响应时间较慢
4. 光标,滚动条定位错误
5. 功能性建议
C级 — 轻微缺陷 Trivial
1. 界面显示错误或拼写问题
2. 各种提示框信息使用不统一,未采用行业术语
3. 界面显示或描述建议
优先级定义
1. 高 -- 操作中断测试不能继续进行;程序崩溃;预期功能未实现;死机bug重现率在90%以上 (建议处理周期需控制在当天)
2. 中 -- 影响软件功能或性能的一般缺陷;死机bug重现率在30%~70%之间 (建议处理周期3天)
3. 低 – 对软件质量影响轻微或建议性bug;死机bug重现率在10%以下 (建议处理周期为7天)
blocker:阻碍了项目开发或者测试的继续进行。
Critical:冲突,数据丢失和严重的内存泄漏等问题。
Major:较大的功能缺陷。
Minor:较小的功能缺陷。
Trivial:拼写、对齐类的错误。
Enhancement:需要改进的。
-
正则表达式---测试里面也很重要
iseedeadpeople 发布于 2011-03-11 13:31:30
正则表达式30分钟入门教程
body { font-size: 100%; }h1 { text-align: center; }h2 { background-color: rgb(238, 238, 238); border-bottom: 1px solid gray; border-right: 1px solid gray; clear: both; }p { text-indent: 2em; line-height: 140%; margin: 5px 20px; }span { margin: 3px; }table { margin: auto; border-style. solid; border-width: 1px 1px 0pt 0pt; border-color: gray; background: none repeat scroll 0% 0% rgb(238, 238, 238); }td, th { border-style. solid; border-width: 0pt 0pt 1px 1px; border-color: gray; }caption { margin: auto; font-weight: bold; }dl { margin-left: 20px; }dt { font-weight: bold; }em { font-style. normal; font-weight: bold; }.webStandards { text-align: right; font-size: 80%; color: gray; }.webStandards a { text-align: right; font-size: small; color: gray; }#ad { margin-top: 60px; }.ad { border: 1px solid rgb(238, 238, 238); margin-bottom: 60px; clear: right; }.note { float: right; width: 300px; padding: 5px; background-color: rgb(238, 238, 238); border: 1px solid gray; clear: right; }#meta. { text-align: center; }.important { color: orange; }.name { font-weight: bold; }.code { color: blue; }.regex { color: red; }.part { color: green; }.string { font-style. italic; }.desc { text-decoration: underline; }#clearButton, #hideButton { text-decoration: none; border: 1px solid gray; background-color: rgb(238, 238, 238); } 来园子之前写的一篇正则表达式教程,部分翻译自codeproject的The 30 Minute Regex Tutorial。
由于评论里有过长的URL,所以本页排版比较混乱,推荐你到原处查看,看完了如果有问题,再到这里来提出.
一些要说的话:
- 如果你没有正则表达式的基础,请跟着教程“一步步来”。请不要大概地扫两眼就说看不懂——以这种态度我写成什么样你也看不懂。当我告诉你这是“30分钟入门教程”时,请不要试图在30秒内入门。
事实是,我身边有个才接触电脑,对操作都不是很熟练的人通过自己学习这篇教程,最后都能在文章采集系统中使用正则表达式完成任务。而且,他写的表达式中,还使用了“零宽断言”等“高级”技术。
所以,如果你能具体地说明你的问题,我很愿意帮助你。但是如果你概括地说看不懂,那不是我的问题。 - 欢迎转载,但请声明作者以及来源。
正则表达式30分钟入门教程
版本:v2.31 (2009-4-11) 作者:deerchao 转载请注明来源
目录
- 本文目标
- 如何使用本教程
- 正则表达式到底是什么东西?
- 入门
- 测试正则表达式
- 元字符
- 字符转义
- 重复
- 字符类
- 分枝条件
- 反义
- 分组
- 后向引用
- 零宽断言
- 负向零宽断言
- 注释
- 贪婪与懒惰
- 处理选项
- 平衡组/递归匹配
- 还有些什么东西没提到
- 联系作者
- 网上的资源及本文参考文献
- 更新纪录
本文目标
30分钟内让你明白正则表达式是什么,并对它有一些基本的了解,让你可以在自己的程序或网页里使用它。
如何使用本教程
最重要的是——请给我30分钟,如果你没有使用正则表达式的经验,请不要试图在30秒内入门——除非你是超人 :)
别被下面那些复杂的表达式吓倒,只要跟着我一步一步来,你会发现正则表达式其实并没有你想像 中的那么困难。当然,如果你看完了这篇教程之后,发现自己明白了很多,却又几乎什么都记不得,那也是很正常的——我认为,没接触过正则表达式的人在看完这 篇教程后,能把提到过的语法记住80%以上的可能性为零。这里只是让你明白基本的原理,以后你还需要多练习,多使用,才能熟练掌握正则表达式。
除了作为入门教程之外,本文还试图成为可以在日常工作中使用的正则表达式语法参考手册。就作者本人的经历来说,这个目标还是完成得不错的——你看,我自己也没能把所有的东西记下来,不是吗?
清除格式 文本格式约定:专业术语 元字符/语法格式 正则表达式 正则表达式中的一部分(用于分析) 对其进行匹配的源字符串 对正则表达式或其中一部分的说明
隐藏边注 本文右边有一些注释,主要是用来提供一些相关信息,或者给没有程序员背景的读者解释一些基本概念,通常可以忽略。
正则表达式到底是什么东西?
字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等等。字符串是0个或更多个字符的序列。文本也就是文字,字符串。说某个字符串匹配某个正则表达式,通常是指这个字符串里有一部分(或几部分分别)能满足表达式给出的条件。
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
很可能你使用过Windows/Dos下用于文件查找的通配符(wildcard),也就是*和?。如果你想查找某个目录下的所有的Word文档的话,你会搜索*.doc。在这里,*会被解释成任意的字符串。和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求——当然,代价就是更复杂——比如你可以编写一个正则表达式,用来查找所有以0开头,后面跟着2-3个数字,然后是一个连字号“-”,最后是7或8位数字的字符串(像010-12345678或0376-7654321)。
入门
学习正则表达式的最好方法是从例子开始,理解例子之后再自己对例子进行修改,实验。下面给出了不少简单的例子,并对它们作了详细的说明。
假设你在一篇英文小说里查找hi,你可以使用正则表达式hi。
这几乎是最简单的正则表达式了,它可以精确匹配这样的字符串:由两个字符组成,前一个字符是h,后一个是i。通常,处理正则表达式的工具会提供一个忽略大小写的选项,如果选中了这个选项,它可以匹配hi,HI,Hi,hI这四种情况中的任意一种。
不幸的是,很多单词里包含hi这两个连续的字符,比如him,history,high等等。用hi来查找的话,这里边的hi也会被找出来。如果要精确地查找hi这个单词的话,我们应该使用\bhi\b。
\b是正则表达式规定的一个特殊代码(好吧,某些人叫它元字符,metacharacter),代表着单词的开头或结尾,也就是单词的分界处。虽然通常英文的单词是由空格,标点符号或者换行来分隔的,但是\b并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置。
如果需要更精确的说法,\b匹配这样的位置:它的前一个字符和后一个字符不全是(一个是,一个不是或不存在)\w。
假如你要找的是hi后面不远处跟着一个Lucy,你应该用\bhi\b.*\bLucy\b。
这里,.是另一个元字符,匹配除了换行符以外的任意字符。*同样是元字符,不过它代表的不是字符,也不是位置,而是数量——它指定*前边的内容可以连续重复使用任意次以使整个表达式得到匹配。因此,.*连在一起就意味着任意数量的不包含换行的字符。现在\bhi\b.*\bLucy\b的意思就很明显了:先是一个单词hi,然后是任意个任意字符(但不能是换行),最后是Lucy这个单词。
换行符就是'\n',ASCII编码为10(十六进制0x0A)的字符。
如果同时使用其它元字符,我们就能构造出功能更强大的正则表达式。比如下面这个例子:
0\d\d-\d\d\d\d\d\d\d\d匹配这样的字符串:以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字(也就是中国的电话号码。当然,这个例子只能匹配区号为3位的情形)。
这里的\d是个新的元字符,匹配一位数字(0,或1,或2,或……)。-不是元字符,只匹配它本身——连字符(或者减号,或者中横线,或者随你怎么称呼它)。
为了避免那么多烦人的重复,我们也可以这样写这个表达式:0\d{2}-\d{8}。 这里\d后面的{2}({8})的意思是前面\d必须连续重复匹配2次(8次)。
测试正则表达式
其它可用的测试工具:
如果你不觉得正则表达式很难读写的话,要么你是一个天才,要么,你不是地球人。正则表达式的语法很令人头疼,即使对经常使用它的人来说也是如此。由于难于读写,容易出错,所以找一种工具对正则表达式进行测试是很有必要的。
不同的环境下正则表达式的一些细节是不相同的,本教程介绍的是微软 .Net Framework 2.0下正则表达式的行为,所以,我向你介绍一个.Net下的工具Regex Tester。首先你确保已经安装了.Net Framework 2.0,然后下载Regex Tester。这是个绿色软件,下载完后打开压缩包,直接运行RegexTester.exe就可以了。
下面是Regex Tester运行时的截图:
元字符
现在你已经知道几个很有用的元字符了,如\b,.,*,还有\d.正则表达式里还有更多的元字符,比如\s匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等。\w匹配字母或数字或下划线或汉字等。
对中文/汉字的特殊处理是由.Net提供的正则表达式引擎支持的,其它环境下的具体情况请查看相关文档。
下面来看看更多的例子:
\ba\w*\b匹配以字母a开头的单词——先是某个单词开始处(\b),然后是字母a,然后是任意数量的字母或数字(\w*),最后是单词结束处(\b)。
好吧,现在我们说说正则表达式里的单词是什么意思吧:就是不少于一个的连续的\w。不错,这与学习英文时要背的成千上万个同名的东西的确关系不大 :)
\d+匹配1个或更多连续的数字。这里的+是和*类似的元字符,不同的是*匹配重复任意次(可能是0次),而+则匹配重复1次或更多次。
\b\w{6}\b 匹配刚好6个字符的单词。
表1.常用的元字符 代码 说明 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配字符串的开始 $ 匹配字符串的结束 正则表达式引擎通常会提供一个“测试指定的字符串是否匹配一个正则表达式”的方法,如JavaScript里的RegExp.test()方法或.NET里的Regex.IsMatch()方法。这里的匹配是指是字符串里有没有符合表达式规则的部分。如果不使用^和$的话,对于\d{5,12}而言,使用这样的方法就只能保证字符串里包含5到12连续位数字,而不是整个字符串就是5到12位数字。
元字符^(和数字6在同一个键位上的符号)和$都匹配一个位置,这和\b有点类似。^匹配你要用来查找的字符串的开头,$匹配结尾。这两个代码在验证输入的内容时非常有用,比如一个网站如果要求你填写的QQ号必须为5位到12位数字时,可以使用:^\d{5,12}$。
这里的{5,12}和前面介绍过的{2}是类似的,只不过{2}匹配只能不多不少重复2次,{5,12}则是重复的次数不能少于5次,不能多于12次,否则都不匹配。
因为使用了^和$,所以输入的整个字符串都要用来和\d{5,12}来匹配,也就是说整个输入必须是5到12个数字,因此如果输入的QQ号能匹配这个正则表达式的话,那就符合要求了。
和忽略大小写的选项类似,有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项,^和$的意义就变成了匹配行的开始处和结束处。
字符转义
如果你想查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义。因此,你应该使用\.和\*。当然,要查找\本身,你也得用\\.
例如:unibetter\.com匹配unibetter.com,C:\\Windows匹配C:\Windows。
重复
你已经看过了前面的*,+,{2},{5,12}这几个匹配重复的方式了。下面是正则表达式中所有的限定符(指定数量的代码,例如*,{5,12}等):
表2.常用的限定符 代码/语法 说明 * 重复零次或更多次 + 重复一次或更多次 ? 重复零次或一次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次 下面是一些使用重复的例子:
Windows\d+匹配Windows后面跟1个或更多数字
^\w+匹配一行的第一个单词(或整个字符串的第一个单词,具体匹配哪个意思得看选项设置)
字符类
要想查找数字,字母或数字,空白是很简单的,因为已经有了对应这些字符集合的元字符,但是如果你想匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办?
很简单,你只需要在方括号里列出它们就行了,像[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!)。
我们也可以轻松地指定一个字符范围,像[0-9]代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)。
下面是一个更复杂的表达式:\(?0\d{2}[) -]?\d{8}。
“(”和“)”也是元字符,后面的分组节里会提到,所以在这里需要使用转义。
这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455,或02912345678等。我们对它进行一些分析吧:首先是一个转义字符\(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是)或-或空格中的一个,它出现1次或不出现(?),最后是8个数字(\d{8})。
分枝条件
不幸的是,刚才那个表达式也能匹配010)12345678或(022-87654321这样的“不正确”的格式。要解决这个问题,我们需要用到分枝条件。正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开。听不明白?没关系,看例子:
0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。
\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}这个表达式匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔。你可以试试用分枝条件把这个表达式扩展成也支持4位区号的。
\d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用分枝条件时,要注意各个条件的顺序。如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。
分组
我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作(后面会有介绍)。
(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。
IP地址中每个数字都不能大于255,大家千万不要被《24》第三季的编剧给忽悠了……
不幸的是,它也将匹配256.300.888.999这种不可能存在的IP地址。如果能使用算术比较的话,或许能简单地解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的IP地址:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)。
理解这个表达式的关键是理解2[0-4]\d|25[0-5]|[01]?\d\d?,这里我就不细说了,你自己应该能分析得出来它的意义。
反义
有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:
表3.常用的反义代码 代码/语法 说明 \W 匹配任意不是字母,数字,下划线,汉字的字符 \S 匹配任意不是空白符的字符 \D 匹配任意非数字的字符 \B 匹配不是单词开头或结束的位置 [^x] 匹配除了x以外的任意字符 [^aeiou] 匹配除了aeiou这几个字母以外的任意字符 例子:\S+匹配不包含空白符的字符串。
<a[^>]+>匹配用尖括号括起来的以a开头的字符串。
后向引用
使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
呃……其实,组号分配还不像我刚说得那么简单:
- 分组0对应整个正则表达式
- 实际上组号分配过程是要从左向右扫描两遍的:第一遍只给未命名组分配,第二遍只给命名组分配--因此所有命名组的组号都大于未命名的组号
- 你可以使用(?:exp)这样的语法来剥夺一个分组对组号分配的参与权.
后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。难以理解?请看示例:
\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。
你也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成'也行:(?'Word'\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b。
使用小括号的时候,还有很多特定用途的语法。下面列出了最常用的一些:
表4.常用分组语法 分类 代码/语法 说明 捕获 (exp) 匹配exp,并捕获文本到自动命名的组里 (?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp) (?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号 零宽断言 (?=exp) 匹配exp前面的位置 (?<=exp) 匹配exp后面的位置 (?!exp) 匹配后面跟的不是exp的位置 (?<!exp) 匹配前面不是exp的位置 注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读 我们已经讨论了前两种语法。第三个(?:exp)不会改变正则表达式的处理方式,只是这样的组匹配的内容不会像前两种那样被捕获到某个组里面,也不会拥有组号。“我为什么会想要这样做?”——好问题,你觉得为什么呢?
零宽断言
地球人,是不是觉得这些术语名称太复杂,太难记了?我也有同感。知道有这么一种东西就行了,它叫什么,随它去吧!人若无名,便可专心练剑;物若无名,便可随意取舍……
接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。最好还是拿例子来说明吧:
断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。
(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。
(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里面添加逗号的部分:((?<=\d)\d{3})+\b,用它对1234567890进行查找时结果是234567890。
下面这个例子同时使用了这两种断言:(?<=\s)\d+(?=\s)匹配以空白符间隔的数字(再次强调,不包括这些空白符)。
负向零宽断言
前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样:
\b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的\w*\b将会匹配下一个单词,于是\b\w*q[^u]\w*\b就能匹配整个Iraq fighting。负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:\b\w*q(?!u)\w*\b。
零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。
同理,我们可以用(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字。
请详细分析表达式(?<=<(\w+)>).*(?=<\/\1>),这个表达式最能表现零宽断言的真正用途。
一个更复杂的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容。(?<=<(\w+)>)指定了这样的前缀:被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=<\/\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是<b>和</b>之间的内容(再次提醒,不包括前缀和后缀本身)。
注释
小括号的另一种用途是通过语法(?#comment)来包含注释。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)。
要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。例如,我们可以前面的一个表达式写成这样:
(?<= # 断言要匹配的文本的前缀
<(\w+)> # 查找尖括号括起来的字母或数字(即HTML/XML标签)
) # 前缀结束
.* # 匹配任意文本
(?= # 断言要匹配的文本的后缀
<\/\1> # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签
) # 后缀结束贪婪与懒惰
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧:
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权——The match that begins earliest wins。
表5.懒惰限定符 代码/语法 说明 *? 重复任意次,但尽可能少重复 +? 重复1次或更多次,但尽可能少重复 ?? 重复0次或1次,但尽可能少重复 {n,m}? 重复n到m次,但尽可能少重复 {n,}? 重复n次以上,但尽可能少重复 处理选项
在C#中,你可以使用Regex(String, RegexOptions)构造函数来设置正则表达式的处理选项。如:Regex regex = new Regex(@"\ba\w{6}\b", RegexOptions.IgnoreCase);
上面介绍了几个选项如忽略大小写,处理多行等,这些选项能用来改变处理正则表达式的方式。下面是.Net中常用的正则表达式选项:
表6.常用的处理选项 名称 说明 IgnoreCase(忽略大小写) 匹配时不区分大小写。 Multiline(多行模式) 更改^和$的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,$的精确含意是:匹配\n之前的位置以及字符串结束前的位置.) Singleline(单行模式) 更改.的含义,使它与每一个字符匹配(包括换行符\n)。 IgnorePatternWhitespace(忽略空白) 忽略表达式中的非转义空白并启用由#标记的注释。 ExplicitCapture(显式捕获) 仅捕获已被显式命名的组。 一个经常被问到的问题是:是不是只能同时使用多行模式和单行模式中的一种?答案是:不是。这两个选项之间没有任何关系,除了它们的名字比较相似(以至于让人感到疑惑)以外。
平衡组/递归匹配
这里介绍的平衡组语法是由.Net Framework支持的;其它语言/库不一定支持这种功能,或者支持此功能但需要使用不同的语法。
有时我们需要匹配像( 100 * ( 50 + 15 ) )这样的可嵌套的层次性结构,这时简单地使用\(.+\)则只会匹配到最左边的左括号和最右边的右括号之间的内容(这里我们讨论的是贪婪模式,懒惰模式也有下面的问题)。假如原来的字符串里的左括号和右括号出现的次数不相等,比如( 5 / ( 3 + 2 ) ) ),那我们的匹配结果里两者的个数也不会相等。有没有办法在这样的字符串里匹配到最长的,配对的括号之间的内容呢?
为了避免(和\(把你的大脑彻底搞糊涂,我们还是用尖括号代替圆括号吧。现在我们的问题变成了如何把xx <aa <bbb> <bbb> aa> yy这样的字符串里,最长的配对的尖括号内的内容捕获出来?
这里需要用到以下的语法构造:
- (?'group') 把捕获的内容命名为group,并压入堆栈(Stack)
- (?'-group') 从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败
- (?(group)yes|no) 如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分
- (?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败
如果你不是一个程序员(或者你自称程序员但是不知道堆栈是什么东西),你就这样理解上面的三种语法吧:第一个就是在黑板 上写一个"group",第二个就是从黑板上擦掉一个"group",第三个就是看黑板上写的还有没有"group",如果有就继续匹配yes部分,否则 就匹配no部分。
我们需要做的是每碰到了左括号,就在压入一个"Open",每碰到一个右括号,就弹出一个,到了最后就看看堆栈是否为空--如果不为空那就证明左括号比右括号多,那匹配就应该失败。正则表达式引擎会进行回溯(放弃最前面或最后面的一些字符),尽量使整个表达式得到匹配。
< #最外层的左括号
[^<>]* #最外层的左括号后面的不是括号的内容
(
(
(?'Open'<) #碰到了左括号,在黑板上写一个"Open"
[^<>]* #匹配左括号后面的不是括号的内容
)+
(
(?'-Open'>) #碰到了右括号,擦掉一个"Open"
[^<>]* #匹配右括号后面不是括号的内容
)+
)*
(?(Open)(?!)) #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败
> #最外层的右括号平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配嵌套的<div>标签:<div[^>]*>[^<>]*(((?'Open'<div[^>]*>)[^<>]*)+((?'-Open'</div>)[^<>]*)+)*(?(Open)(?!))</div>.
还有些什么东西没提到
上边已经描述了构造正则表达式的大量元素,但是还有很多没有提到的东西。下面是一些未提到的元素的列表,包含语法和简单的说明。你可以在网上找到更详细的参考资料来学习它们--当你需要用到它们的时候。如果你安装了MSDN Library,你也可以在里面找到.net下正则表达式详细的文档。
这里的介绍很简略,如果你需要更详细的信息,而又没有在电脑上安装MSDN Library,可以查看关于正则表达式语言元素的MSDN在线文档。
表7.尚未详细讨论的语法 代码/语法 说明 \a 报警字符(打印它的效果是电脑嘀一声) \b 通常是单词分界位置,但如果在字符类里使用代表退格 \t 制表符,Tab \r 回车 \v 竖向制表符 \f 换页符 \n 换行符 \e Escape \0nn ASCII代码中八进制代码为nn的字符 \xnn ASCII代码中十六进制代码为nn的字符 \unnnn Unicode代码中十六进制代码为nnnn的字符 \cN ASCII控制字符。比如\cC代表Ctrl+C \A 字符串开头(类似^,但不受处理多行选项的影响) \Z 字符串结尾或行尾(不受处理多行选项的影响) \z 字符串结尾(类似$,但不受处理多行选项的影响) \G 当前搜索的开头 \p{name} Unicode中命名为name的字符类,例如\p{IsGreek} (?>exp) 贪婪子表达式 (?<x>-<y>exp) 平衡组 (?im-nsx:exp) 在子表达式exp中改变处理选项 (?im-nsx) 为表达式后面的部分改变处理选项 (?(exp)yes|no) 把exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no (?(exp)yes) 同上,只是使用空表达式作为no (?(name)yes|no) 如果命名为name的组捕获到了内容,使用yes作为表达式;否则使用no (?(name)yes) 同上,只是使用空表达式作为no 联系作者
好吧,我承认,我骗了你,读到这里你肯定花了不止30分钟.相信我,这是我的错,而不是因为你太笨.我之所以说"30分钟",是为了让你有信心,有耐心继续下去.既然你看到了这里,那证明我的阴谋成功了.被忽悠的感觉很爽吧?
要投诉我,或者觉得我其实可以忽悠得更高明,或者有任何其它问题,欢迎来我的博客让我知道.
网上的资源及本文参考文献
- 微软的正则表达式教程
- System.Text.RegularExpressions.Regex类(MSDN)
- 专业的正则表达式教学网站(英文)
- 关于.Net下的平衡组的详细讨论(英文)
- Mastering Regular Expressions (Second Edition)
更新纪录
- 2006-3-27 第一版
- 2006-10-12 第二版
- 修正了几个细节上的错误和不准确的地方
- 增加了对处理中文时的一些说明
- 更改了几个术语的翻译(采用了MSDN的翻译方式)
- 增加了平衡组的介绍
- 放弃了对The Regulator的介绍,改用Regex Tester
- 2007-3-12 V2.1
- 修正了几个小的错误
- 增加了对处理选项(RegexOptions)的介绍
- 2007-5-28 V2.2
- 重新组织了对零宽断言的介绍
- 删除了几个不太合适的示例,添加了几个实用的示例
- 其它一些微小的更改
- 2007-8-3 V2.21
- 修改了几处文字错误
- 修改/添加了对$,\b的精确说明
- 承认了作者是个骗子
- 给RegexTester添加了Singleline选项的相关功能
- 2008-4-13 v2.3
- 调整了部分章节的次序
- 修改了页面布局,删除了专门的参考节
- 针对读者的反馈,调整了部分内容
- 2009-4-11 v2.31
- 修改了几处文字错误
- 添加了一些注释说明
- 调整了一些措词
- 如果你没有正则表达式的基础,请跟着教程“一步步来”。请不要大概地扫两眼就说看不懂——以这种态度我写成什么样你也看不懂。当我告诉你这是“30分钟入门教程”时,请不要试图在30秒内入门。
我的栏目
标题搜索
我的存档
数据统计
- 访问量: 111844
- 日志数: 670
- 建立时间: 2007-07-19
- 更新时间: 2013-03-11