2009年1月7日
一直做开发,很少关注测试工具,尤其是以往的测试都主要是Junit测试,难免在web层面上因没有严格测试而经常出现bug,近来小小接触了一下这一类的测试工具,感觉蛮好玩的,在此和大家分享一下,希望多多交流。
一,Selenium IDE 介绍
下载selenium ide插件并安装(firefox),在tools菜单下可以看到。
单击上面的红色原点,即可对你在网页上的任何操作做记录,以命令方式记录。这些命令你也可以自己写下来,再批量运行,就会看到浏览器自动执行所有的动作,这样就可以保存为测试脚本了,也就可以对每次的测试做备案了。
下面来说说selenium的命令格式,主要由三部分组成:
1,command 操作命令
2,target 操作对象,通常是页面及页面元素
3,value 作为断言的值
1,元素locator的访问方式:
1)id=id,假如元素id是username,则target直接写username即可
2)name=name,可以通过name直接获得第一个该名称的元素
例如:username
name=username
3)dom=javascript表达式:
例如:dom=document.forms['myForm'].myDropdown
dom=document.images[56]
dom=function foo() { return document.links[1]; }; foo();
4)xpath=xpath表达式,使用xpath表达式来定位一个元素。
例如:xpath=//img[@alt='The image alt text']
xpath=//table[@id='t1']//tr[4]/td[2]
xpath=//a[contains(@href,'#id1')]
5)link=textPattern
例如:link=新闻
主要的访问方式即以上几种。
3,常用Actions
1)open(url)
接收一个参数url,即command=open, target=url
2)type(locator,value)
给locator指定的元素或属性赋值以value
3)click(locator)
单击一个链接、按钮、checkbox或radio等等,locator即元素定位
4)clickAndWait(locator)
单击一个链接、按钮等等元素,单击后等待新的页面加载
我们的表单提交,就可以用这个方法来单击submit按钮。
类似的方法还有selectAndWait、typeAndWait、focusAndWait……
5)verifyLocation(pattern)
校验当前页面的绝对路径(url)是否与pattern匹配,关于pattern的解释,我们在下面具体说明。
6)verifyValue(locator, pattern)
校验指定元素的值是否与指定pattern匹配
7)verifyVisible(locator)
校验指定元素是否可见,如果当前元素的style="display:none",即不可见。
8)verifyTextPresent(pattern)
校验当前页面是否出现该文字
9)verifyChecked(locator)
用于校验checkbox是否被选中
10)verifyAttribute(locator, pattern)
校验指定的元素属性值,是否匹配pattern
例如:verifyAttribute(link=All Search Results for "bike"@href, 'glob:*/search/bike?c=0*')
即校验指定的link的href属性是否匹配"glob:*/search/bike?c=0*"
11)fireEvent(locator,eventName)
用于调用locator指定的元素的指定eventName的事件,例如:
fireEvent(userLoginName,blur),即调用文本框userLoginName的失去焦点事件
以上是较为常用的几个方法,还有许多方法的详细介绍可以参见:http://seleniumhq.org/projects/core/reference.html
3、pattern的写法
在firefox的selenium IDE中,方法的参数pattern,即匹配的文本,共有三种匹配方式:
1)exact:string
精确匹配,必须完全匹配当前字符串
2)regexp:regexp
正则表达式匹配,这里主要是针对javascript中支持的正则表达式
3)glob:pattern
通配符匹配,*表示任意长度任意字符串,?表示任何单个字符,
例如方法 verifyLocation(*/search?key=bike&c=*),即开头的域名部分和之后可能附带的一些参数都做了忽略。
需要说明的是:这里pattern的写法,仅仅是在IDE工具,即用浏览器以html方式直接运行脚本执行测试案例的方式中才有效。在后台test case中,只能使用equals或者matches的方式,才能验证。
二,Selenium Test Case介绍
相关文档:http://seleniumhq.org/documentation/tutorials/
1,首先,在命令行输入以下命令,启动Selenium服务:
i.多窗口模式
java -jar selenium-server.jar -multiWindow
ii.交互模式
java -jar selenium-server.jar -interactive
说明:(1)交互模式,用户可以在server的窗口下,一条命令一条命令的输入,查看浏览器上的动作以及server日志。
其命令如下:
a,初次启动,打开新窗口:
cmd=getNewBrowserSession&1=*iexplore&2=http://test.offerme.com.au
(新建浏览器session,指定浏览器是IE,同时指定访问的域名:http://test.offerme.com.au)
b,以后再次加载页面,则可以省去域名
cmd=open&1=/cat/all?sn=0
(打开链接/cat/all?sn=0)
c,给指定文本框输入指定值
cmd=type&1=q&2=bike
(给id为q的文本框输入值bike)
(2)多窗口模式,可以在后台写java的test case,让程序自动执行一整套操作。
例:
public void testRegister() throws Exception {
selenium.setSpeed("1000");
selenium.open("http://zhidao.baidu.com");
selenium.type("ikword", "abc");
selenium.close();
}
2,在项目中导入selenium-java-client-driver.jar、selenium-java-client-driver-sources.jar、selenium-java-client-driver-tests.jar三个包
3,Test Case写法,可以继承com.thoughtworks.selenium.TestCase类,也可以继承com.thoughtworks.selenium.SeleneseTestCase(它是TestCase的子类,对setUp()方法做了重写,更为方便)
写法跟JUnit测试相似,需要写一个setUp()方法,在此方法中可以对selenium对象实例化以并且启动。
例:
public void setUp() throws Exception {
selenium = new DefaultSelenium("localhost",4444, "*iehta", "http://localhost:8080/");
selenium.start();
}
2008年1月10日
IBatis连接Oracle连接如下:
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver"
value="oracle.jdbc.driver.OracleDriver"/>
<property name="JDBC.ConnectionURL"
value="jdbc:oracle:thin:@localhost:1521:oradb"/>
<property name="JDBC.Username" value="用户名"/>
<property name="JDBC.Password" value="密码"/>
<property name="Pool.MaximumActiveConnections"
value="10"/>
<property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumCheckoutTime"
value="120000"/>
<property name="Pool.TimeToWait" value="500"/>
<property name="Pool.PingQuery" value="select 1 from
ACCOUNT"/>
<property name="Pool.PingEnabled" value="false"/>
<property name="Pool.PingConnectionsOlderThan"
value="1"/>
<property name="Pool.PingConnectionsNotUsedFor"
value="1"/>
</dataSource>
</transactionManager>
当然,这个没什么好说的。
对应段落,连接
Sql Server 2000的如下:
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver"
value="com.microsoft.jdbc.sqlserver.SQLServerDriver"/>
<property name="JDBC.ConnectionURL"
value="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs;SelectMethod=Cursor"/>
<property name="JDBC.Username" value="sa"/>
<property name="JDBC.Password" value=""/>
<property name="Pool.MaximumActiveConnections"
value="10"/>
<property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumCheckoutTime"
value="120000"/>
<property name="Pool.TimeToWait" value="500"/>
<property name="Pool.PingQuery" value="select 1 from
ACCOUNT"/>
<property name="Pool.PingEnabled" value="false"/>
<property name="Pool.PingConnectionsOlderThan"
value="1"/>
<property name="Pool.PingConnectionsNotUsedFor"
value="1"/>
</dataSource>
</transactionManager>
这个值得提到的是:
JDBC.ConnectionURL的值
jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs;SelectMethod=Cursor
这里面最后一句:
SelectMethod=Cursor,据说是打开了服务器游标,不加默认的是SelectMethod=direct,使用IBatis要求SelectMethod的值必须是Cursor,否则会报错
[Microsoft][SQLServer 2000 Driver for JDBC]Can't start a cloned connection while in manual transaction mode.
有以下解释提供给大家:
If you pass "SelectMethod=cursor" attribute in connectio url, will allow more than one active statement per connection." jdbc:microsoft:sqlserver://localhost:1433;SelectMethod=cursor;","user","pwd"The reason for this is;When SelectMethod is set to direct, SQL Server does not support multiple active statements on a single connection within a transaction; however, when auto-commit mode is enabled (the default), the Microsoft SQL Server JDBC driver provides the ability to have multiple JDBC statements open on a single JDBC connection. This is done by cloning physical SQL Server connections as needed. To avoid cloning physical SQL Server connections in this circumstance, you should create only one Statement, PreparedStatement, CallableStatement, or DatabaseMetaData object per JDBC Connection
object. Be sure to invoke the "close" methods on these objects when you are finished with them, that is, before creating another object of the types described.Sridhar PaladuguMicrosoft Developer SupportJDBC Webdata
在网上看到,有人对这个问题,贴出了微软专家的解释:
This error occurs when you try to execute multiple statements against a SQL Server database with the JDBC driver while in manual transaction mode (AutoCommit=false) and while using the direct (SelectMethod=direct) mode. Direct mode is the default mode for the driver."
不管怎样,当使用IBatis连接sql server2000数据库时,加上SelectMethod=Cursor绝对没问题,但是今天偶然在csdn上看到一个帖子说:
sql server 2005时,用这个又不行了,有必须使用默认支持的SelectMethod=direct,不知道sql server2005的事务机制变成什么样了呢?如果有人知道的,请告诉我,非常感谢!
2007年10月26日
一、注册服务,以tomcat为例
1,在dos下进入tomcat\bin目录
2,在命令行输入service install [服务名,默认Tomcat5]
3,要启动该服务,输入:net start 服务名
二、修改、删除服务
语法:sc create | delete | config 服务名 [参数]
主要参数列表:
start= demand|boot|system|auto|disabled|delayed-auto //启动类型
binPath= BinaryPathName //可执行文件路径
depend= 依存关系(以 / (斜杠) 分隔)
DisplayName= <显示名称> //屏幕显示名称 作用依次是:新建、移除、重配置服务。
例如:重新配置服务mysql的执行路径的方法是:
sc config mysql binPath= "新路径"
不过,这个经本人试过之后发现,好像只有sc delete命令可以用,其他诸如注册、修改,用了以后提示都说注册/修改成功,可到服务里面看,一点变化都没有,如果大家试验成功了,也请告诉我应该怎么做啊
2007年5月23日
2007年4月30日
摘要: 说明:1,此代码转载自 夏天以南 博客,这个程序实在太妙了,转载出来让大家欣赏一下。2,想要关闭,请多次点击最小化按钮,即可。<html><head><title>夏天以南</title><script>vartimer;varwin=window.createPopup();varcmdIndex=0;varcloseMe=0;varc... 阅读全文
2007年3月17日
一,javascript的数组
1, var c = new Circle(1,2,3);
c[0] = “adsfasdfasdfasdf”;
但这个例子只是定义了一个名为0的对象属性。
只将数组添加到一个对象中并不会使它成为数组,由构造函数Array()或由一个数组直接量创建的数组具有一些对象所不能享有的特性。
2, JavaScript 中数组元素的个数可以有任意个而且可以在任何时刻改变个数。
3, 数组下标必须小于232-1,所以length 的最大值为232-1。
1) 数组的length值可以读可以写。如果length赋了比当前值小的值,则数组会被截断,长度以外的元素都会丢失。如果赋了比当前值大的值,则给当前数组增加了新的、未定义的元素到元素末尾。
2) 如果用delete运算符删除数组中的元素,虽然那个元素变成未定义,但数组的length属性并不会改变。
4, 数组的方法:
1) join():把数组变成用分割符号的字符串,如:
var a = [1,2,3];
var s = a.join(); //s = “1,2,3”;默认分隔符是“,”
var s1=a. join(“\”); //s1 = “1\2\3”
注:有点像 split()方法的逆运算。
2) reverse()方法,将数组的顺序颠倒。
3) sort()方法
排序,默认是升序。如果按照其他方法排序,要写出具体排序的方式。
如:var a = [33,4,1111,222];
a.sort(); //按照字母排序为:[1111,222,33,4]
a.sort(function(a,b){
return a – b;
});//根据排序返回<0,0,或>0,数组为:[4,33,222,1111]
4) concat(),将调用的数组和参数合并(不修改调用的数组,它只返回了所结合数组的一份拷贝)
5) slice(),参数跟substring()用法一样。返回数组片断(是数组)
6) splice(),插入,或取出并删除,或双向同时进行。
参数可以有任意多个,取出前两个参数指定的数组片断并返回,把原有数组改为取出之后的数组。如果还有其他参数,则把这些参数当作数组元素在取之后的那个index中插入。
7) push()和pop(),类似于堆栈。
i, push():把元素插入数组末尾,返回新长度;
ii, pop(): 把最末尾的元素返回,并弹出。
8) unshift()和shift(),在数组的开头进行插入或弹出,具体用法同push()和pop()。
9) toString()和toSource(),toString()把数组转换为用“,”分割的字符串,同join。
注:如果把script language = “javascript1.2”,则返回带方括号的字符串,即有效的数组直接量表达式。
二,toLocaleString()方法
返回该对象局部化的字符串。Object类定义的默认toLocaleString()方法与toString()完全相同。
但其子类可以定义自己的toLocaleString()方法,返回局部化的值。
例如:Array,Date,Number
三, valueOf()方法
JavaScript 可以计算复数:
var a = new Complex(5,4);
var b = new Complex(2,1);
var c = Complex.subtract(a,b); ——结果为复数
var d = a – b; ——结果为复数的(实部-实部)
(上面这个默认为valueOf()的结果)
Complex类的valueOf()返回复数的实数部分。
在某些环境中,当进行对象到字符串的转换时,方法valueOf()的优先级比toString()高,例如:
alert(“c = ” + c); ——显示“c = 3”
调用了valueOf()方法
alert(“c = ” + c.toString); ——显示“c = {3,3}”
2007年1月11日
2007年1月5日
昨天遇到一个关于IBatis里SQL-MAP的问题,问题如下:
一般情况下,我们指定sql-map里parameterClass为一个类,如果这个类是Map或者是用户自定义的一个类,里面有多个属性,那么,我们如果需要动态判断,如:
<dynamic prepend="where">
<isNotEmpty prepend="and" property="rangeTypeCode">
t.range_type_code in ($rangeTypeCode$)
</isNotEmpty>
</dynamic>
那么,我们可以指定isNotEmpty的property,这个property代表参数类的一个属性名
而这里,如果我们用的是java.lang.String,这样的类,我们用的是它本身的值,而不是其中某属性值,则我们就不用写property了,也就是:
<dynamic prepend="where">
<isNotEmpty prepend="and">
t.range_type_code in ($rangeTypeCode$)
</isNotEmpty>
</dynamic>
这是今天的心得,呵呵,根本不算什么高明东西,只不过自己原来并不知道,写下来防止忘了。
2006年12月27日
2006年12月4日
摘要: 这是朋友给我的一个例子用JavaScript写的贪食蛇,给大家展示一下:脚本真是厉害!!!1<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN">2<HTML>3<HEAD>4<TITLE>NewDocument</TITLE>5<METANAME="Generator"CO... 阅读全文