Archive for the ‘IT生活’ Category.

如何解决firefox下window.event的问题

window.event在IE和Opera中是一个全局变量,所以我们可以在dom对象所调用的函数中使用它。
但是在firefox中,event只是对当前触发的事件有效,有时我们想得到一些event的值(如键盘编码),就不是一件容易的事情了。
目前网上常见的方法是将event当作参数传递给dom对象的触发函数,不过这种方式在一些场合下并不适合,如为一个对象增加一个键盘抬起的监听函数,addEventListener(”onkeyup”, “doSomth(event)”),此时在firfox下,同样会报event没有定义的错误。

今天终于找到了一个能够比较圆满的解决这个问题的方案,有兴趣的同学可以看看这个例子里的toggleHighlight函数,就都明白了。
eventsexample1.html

function toggleHighlight(evt)
{
     evt = (evt) ? evt : ((window.event) ? window.event : "")

     // 这行是我新加的,用于获得当前的keycode,为了浏览器兼容要写不少莫名的代码 -_-!
     keyCode = evt.keyCode ? evt.keyCode : (evt.which ? evt.which :evt.charCode);

     if (evt) {
          var elem = (evt.target) ? evt.target : evt.srcElement
          elem.className = (evt.type == "mouseover") ? "highlight" : "normal"
     }
}

还有一篇文章,对event做了更为详尽的介绍:Supporting Three Event Models at Once

敏捷

今天参加了AgileChina&BJUG联合聚会活动,地点是在理想大厦19层,顺便说一句,sina的办公环境还真是不错~

这次活动的主要主题就是敏捷,本人对agile接触不深,故此次全当是听众。
活动一开始,大家都做了一下自我介绍,主要包括三部分,姓名、职业、三个词概括自己。
前两个倒好,有一说一,不过用三个词概括自己,这还真是不太容易。
我冥想了半天,轮到我的时候,我用了这三个词:发散,独立,理性。嘻嘻,不知道有没有不同意见啊~

这次准备Session的一共有5个,最后大家投票选出了三个,哈,我把票投给了selenium的developer之一huangliang。北京真是小,或者说这个圈子真是小,上次见到huangliang,是在linux的开源大会上,没想到,今天又在这见面了···

三个session分别是cmm和agile在实际应用中的考察,dsl和selenium的介绍,每个都很精彩,接触到了很多新的概念和理念,最受触动的还有那些实际的agile的案例。

session期间还有短暂的交流时间,和thoughtworks的QA聊了一些他们的开发过程,让我感到意外的是,他们竟然没有一个专门的缺陷管理,他们是通过频繁的每日构建和改进来解决这个问题的。恩,这个还有待研究。

活动结束后,几个意犹未尽的新老朋友一起去Mr.Pizza腐败了一把,吃的开心,聊的更开心。

敏捷,可以好好学学,需要好好学学~

WEB3.0

VC总在不知疲倦的寻找着下一个目标
他们需要比创业者更清楚的看到未来的趋势
当然,这种对趋势的看法也就行程了他们的投资口味

现在看来,似乎又有让VC兴奋的东西了
WEB3.0
不是哗众,今天确实看到了这个词

互联网创业瞄准Web新时代 - VC的造梦与毁梦

WEB1.0是小规模的精英的思考
WEB2.0是大规模的草根的思考
WEB3.0是草根的大规模的思考

WEB1.0里,传播是主题
WEB2.0里,分享是主题
WEB3.0里,融合是主题

WEB1.0里,精英的思考是具有号召性质的,草根只能马首是瞻
WEB2.0里,草根的思考是相对独立的,而有些最终又会退变为精英思考
WEB3.0里,草根的思考会形成一种趋势,会牵引一个互联区域的方向

貌似又一场WEB热浪要袭来了

光驱的测试用例

昨天跟他吉聊天时,谈到了如何测试一个DVD光驱。
当时我想了几个测试用例,后来自己又觉得需要补充几个,就都在这里写一下。
题目很简单:测试一个DVD光驱。
想到的测试用例如下:

1、插入一张单面DVD光盘,看是否正确读取
2、插入一张双面DVD光盘,看是否正确读取

3、插入一张被刮花的DVD光盘,看是否正确读取
4、插入一张小DVD光盘,看是否正确读取
5、插入一张塑料空盘,看是否正确读取
6、将光盘正面倒置插入光驱,看是否正确读取。

7、插入一张VCD光盘,看是否正确读取
8、插入一张CD光盘,看是否正确读取

9、插入一张DVDRW光盘,看是否能刻录(因为题中没有说是COMBO)

10、监测光盘读取的速度是否为光驱所标明的读取速度(如16X)

11、读取光盘时,对DVD光驱进行一下外界的振动,看是否正确读取
12、读取光盘时,对DVD光驱进行持续外界的振动,看是否正确读取
13、读取光盘时,突然掉电,重新插上电后,看光驱是否能正确读取

14、光驱读取数据后,是否能从数据线正确输出

15、读取光盘时,距离光驱上方1米处的声音是否超过15分贝

恩,大概就先想这么多。

其实在这里,我们可以将光驱想象成一个函数,光盘就是输入数据,读取后从数据线输出的就是输出数据。

那么很容易看出:
1、2属于有效等价类
3、4、5、6属于无效等价类
7、8测的是向下兼容性
9测的是是否超出需求规定的功能(要知道,这种情况也算是一个bug)
10测的是是否达到需求规定的性能
11、12、13是测试的是健壮性
14测试的是返回值的正确性
15测试的是用户易用性

恩,关于DVD的测试,如果大家还有什么好的测试用例,也都说说吧。

xdebug的安装

Q:xdebug是什么?
A:xdebug是一个开源的php调试器,以php模块的形式加载并被使用。

上周发现xdebug出了RC(release candidate)2版了,就拿下来安装了一下,顺便写了一个安装手册,希望对大家有用。

xdebug模块和相关工具的安装:

ps:一些配置的英文翻译可能不准确

一、安装xdebug模块
1、去www.xdebug.org下载相应版本php的模块文件,保存下载后的文件到php的ext目录,可以自己修改文件的名称,如保存成:xdebug-2.0.0RC1.dll
2、修改php.ini,增加如下信息

[Xdebug]
zend_extension_ts=”c:/php5/ext/xdebug-2.0.0RC1.dll”
xdebug.auto_trace=on
xdebug.collect_params=on
xdebug.collect_return=on
xdebug.trace_output_dir=”c:\Temp\xdebug”
xdebug.profiler_enable=on
xdebug.profiler_output_dir=”c:\Temp\xdebug”

参数解释:
zend_extension_ts=”c:/php5/ext/xdebug-2.0.0RC1.dll”
;加载xdebug模块。这里不能用extension=xdebug-2.0.0RC1.dll的方式加载,必须要以zend的方式加载,否则安装上后,phpinfo打印出来的里的xdebug段的会有Must LOADED AS ZEND EXTENSION的警告信息(原因未知)。

xdebug.auto_trace=on;
;自动打开“监测函数调用过程”的功模。该功能可以在你指定的目录中将函数调用的监测信息以文件的形式输出。此配置项的默认值为off。

xdebug.collect_params=on;
;打开收集“函数参数”的功能。将函数调用的参数值列入函数过程调用的监测信息中。此配置项的默认值为off。

xdebug.collect_return=on
;打开收集“函数返回值”的功能。将函数的返回值列入函数过程调用的监测信息中。此配置项的默认值为off。

xdebug.trace_output_dir=”c:\Temp\xdebug”
;设定函数调用监测信息的输出文件的路径。

xdebug.profiler_enable=on
;打开效能监测器。

xdebug.profiler_output_dir=”c:\Temp\xdebug”;
;设定效能监测信息输出文件的路径。

还有一些更为具体的参数设定,详见:http://www.xdebug.org/docs-settings.php

3、重启apache

这样,在本地运行php的时候,会在所设定的目录里产生一些调试信息的文件:

  • 函数调用过程监测信息文件的文件名格式:trace.××××××.xt。这个文件可以直接查看,里面包含了函数运行的时间,函数调用的参数值,返回值,所在的文件和位置等信息。内容格式还是相对直观的。
  • 效能监测文件的文件名格式:cachegrind.out.××××××××。
    这个文件也可以直接查看,不过信息格式不易被人类所理解,
    所以我们需要接下来的一个软件。

二、安装wincachegrind
由于效能监测文件:cachegrind.out.××××××××文件的内容不易被人类所理解,所以我们需要一个工具来读取它。windows下就有一款这样的软件:wincachegrind。
1、到http://sourceforge.net/projects/wincachegrind/下载安装wincachegrind
2、安装运行后,点击Tools->options,设定你的working folder(php.ini里xdebug.profiler_output_dir的值)
这样就可以比较直观的查看效能监测文件的信息了。

另:不知道是哪个参数没有设定正确,我机器上所有的php的运行后的函数调用过程监测信息都写到了一个trace.××××××.xt中,哪个达人要是知道就给指条明路吧。

TestLink的安装和及与BugFree的整合

TestLink是一款开源的测试管理工具,今天主要说说它的安装和它与BugFree的整合。

安装部分:

  1. 下载TL:https://sourceforge.net/project/showfiles.php?group_id=90976&package_id=143763&release_id=410971
  2. 安装:将解压缩后的文件放到服务器(如Apache)能访问到的目录,通过浏览器访问install目录。安装的引导界面很简明,一般这步不会有太大问题(有问题也主要是mysql版本问题)。安装成功后删除install目录,修改admin的初始密码。
  3. 登陆后,选择语言为中文,会发现界面是乱码。此时我们要修改一下config.inc.php:
    第一处:

    /** GUI CHARSET
    * Chinese users must comment the next line and uncomment the second one
    * @todo translate Chinese from gb2312 to UTF-8
    **/
    //define('TL_TPL_CHARSET', DB_SUPPORTS_UTF8 ? 'UTF-8' : 'ISO-8859-1');
    define('TL_TPL_CHARSET', 'gb2312'); // Chinese charset

    这样,TL就采用gb2312编码来表现和存储了。

    第二处:

    /** Set this to TRUE if your MySQL DB supports UTF8 (MySQL version >= 4.1) */
    define('DB_SUPPORTS_UTF8', false);

    第三处:
    修改中文日期显示的格式。修改$g_locales_date_format和$g_locales_timestamp_format两个数组中的zh_CN索引对应的值,这里的编码都是类似”%Y锟斤拷%m锟斤拷%d锟斤拷”的乱码,我们需要改成“%Y年%m月%d日 %时:%分:%秒”的格式。

  4. 配置发信功能。在注释:

    # @author Francisco Mancardi - 20051106
    # Contributed by wangyy, modified by Francisco Mancardi
    # Taken from mantis
    # for phpmailer config

    后面的部分按照实际配好用户名、密码、smtp之类的信息就ok了。

经过以上步骤,TestLink的安装基本完毕了。

TestLink提供了与bugzilla、mantis等工具整合的功能。
我按照TL的接口规则写了与BugFree整合的程序。

与BugFree整合部分:

  1. 修改lib/bugtracking/int_bugtracking.php,将其中的:

    $configFiles = array('BUGZILLA' => 'bugzilla.cfg.php',
    'MANTIS' => 'mantis.cfg.php',
    'JIRA' => 'jira.cfg.php',
    );

    增加一个值,改为:

    $interfaceFiles = array('BUGZILLA' => 'int_bugzilla.php',
    'MANTIS' => 'int_mantis.php',
    'JIRA' => 'int_jira.php',
    'BUGFREE' => 'int_bugfree.php',
    );
  2. 增加文件:lib/bugtracking/int_bugfree.php、cfg/bugfree.cfg.php(详见附件TLBugFree
  3. 修改config.inc.php,将define(’TL_INTERFACE_BUGS’, ‘NO’);改为define(’TL_INTERFACE_BUGS’, ‘BUGFREE’);

这样就将TL与BugFree整合在一起了。在执行测试用例的时候,会发现界面中多了一个问题报告的部分,如图:
TLBugFree
将每次执行失败后的BugID输入进去即可,多个bug用”,”格开(如图中的“2,34”)。点击“保存结果”后,就可以看到bug的状态和标题了(如图中的2:Active - 测试bug)。

在前一阵的使用中,我发现TL的中文本地化文件locale/zh_CN/strings.txt里有些索引不正确,结果导致界面中出现一些硬生生的英文,我就做了相应的修改。
另外TL的css文件主要还是面向西方字符的显示,所以在显示中文的时候,有些地方可能不是很美观,如字体偏小等。针对这种情况,我也对一些css文件进行了修改。
这些修改都放到了附件TLBugFree里,有兴趣的同学可以拿去试试。

可输入的select

先看看效果:create_select_input.php
兼容浏览器:ie7、ie6、firefox1.5.0、firefox2.0、opera9.01

可输入的select在网上可以搜到很多实现方法,实现的基本原理可以分成以下两种:
1、利用DIV来模拟select
2、利用CSS的clip来切割select,使其只剩下一个选择三角,然后用一个input框来占据原有的select位置

第一种方法由于是完全使用div来模拟,所以在表现样式上十分灵活,但也正是因为这个原因,他带来了大量的CSS,而且可能还会引入图片(实现下拉框的三角按钮),另外由于全部由DIV实现,可能会在兼顾各个浏览器的显示方面多做很多工作。个人觉得这种方法并不是很好。

第二种利用了css的布局属性clip,由于其只是引入了一个input,而且真实的选择还是基于select,所以可控的东西会减少很多。

这个实现版本就是基于第二种原理,当然,在一些方面进行了改进,主要有:

  1. 封装生成input的方法:利用一个js函数来将clip和生成input对象的过程进行封装,只需在每个select后调用一个js函数即可为select生成一个可输入的input框;
  2. 利用父对象进行重定位:由于clip需要在对象的opsition属性设置为absliute的时候才能生效,这样会导致select脱离父对象,引起页面显示结构的错位。利用select的父对象的位置进行重新定位就可以解决这个问题;
  3. 利用单态生成input:为页面每个select生成唯一的一个input框,关于input框的名字可以由用户制定,也可以由使用函数默认生成的名字;
  4. 先后继承select的onchange方法:input框的值的变化是通过select的onchange事件来实现的,但是为了不影响页面中select原有的onchange方法,可以利用attachEvent或addEventListener来对其onchange进行追加;
  5. 动态调整父对象宽度:发现当table的td单元格在包含select的时候,当select被切割时,td的大小会发生变化(原因未知),使得显示变形。利用临时变量来记录select父对象原有大小,在切割成功后再重新划定其父对象的大小就可以解决这个问题;
  6. ie表单唯一输入框的bug:在ie浏览器中,当form表单里只有一个input框时,用户在不点击submit按钮,而是直接回车来触发表单提交的情况下,input的onchange是不能被捕捉到的。只要利用js在input前再追加一个隐藏的匿名input框即可。在firefox下没有这个问题。在opera还没有解决这个问题;
  7. 针对不同的浏览器选择不同的宽度、高度等css值:为了使得显示效果尽可能的相近,不得不做这方面的工作;

其实做这么多,只是为了让用户更透明的使用这个js方法,让用户在客户端基本感觉不到它的存在。

这种实现方法也有缺点,就是提交的表单名称与原来的select名称不同,而是多了一个input的表单值,这需要服务器端的脚本多做点工作来判断一下。

其他的方面还没有想到,大家有兴趣的话可以研究一下,多提宝贵意见~~

解决DIV盖住select的方法-2

今天对上次div盖住select的方法进行了整合和改进,利用函数封装了一下,说说这次主要解决的问题:

  1. 将遮盖层与数据层分开。通过函数createEnvelopDiv方法动态生成遮盖层,来遮盖数据表现层,但是需要注意的是,当数据表现层的长宽和位置变化时,需要重新调用createEnvelopDiv方法
  2. 用insertAdjacentHTML方法来创建遮盖层。解决了必须要先创建遮盖层,后创建数据表现层的问题
  3. 利用单态的方式生成iframe。这样可以防止重复生成iframe对象,也就是针对每一个数据表现层只生成一个用于遮盖的iframe对象
  4. 将iframe的src定义为”javascript:false;”。今天在一个老外的blog上看到的,据说可以防止在https下出现安全警告框,这点有待考证
  5. 利用navigator增加对浏览器的判断。目前这个bug(div无法遮住select)存在与ie6里(ie更低的版本没有测过),ie7已经解决了这个问题,所以函数判断了浏览器的类型和版本号,以便防止在别的浏览器中做重复的工作
  6. 此方法还可以用来遮盖flash对象,但是在firefox下需要为flash的html域增加如下代码
  7. <param name="WMode" value="Transparent"></param>

具体的演示、应用和代码请查看
DEMO页

解决DIV遮盖select的方法

由于IE存在一个bug,会使得DIV层无法遮盖select控件。
我今天说的解决方法是用iframe找到的。其实这个问题的解决方法我今天在网上搜也会很多,不过大部分都是直接用html来实现的。但在实际应用中,我们会更倾向与用js动态生成对象来进行封装。

首先这个实现方式是从google-suggest那得到的启发,起初看suggest的js代码的时候,发现它里面用到了iframe,但是不清楚和div究竟是怎么关联上而又不互相影响的。昨天突然想到可以用selenium的viewdom模块看到其生成的dom对象是如何的,后来发现,suggest是通过两个div来实现的,一个专门用于包含iframe,一个专门用于表现数据,然后再将这两个div重叠即可。很巧妙,但是我怎么没想到。这就应了那句话:简单的才是美的。

现在开始说代码,hoho。
首先是用于遮盖select的层:s

// 创建层
var s=document.createElement("DIV");

// 设置层的相关属性
s.style.visibility="";

// 定义层的样式
s.style.position="absolute";
s.style.left="200";
s.style.top="100";
s.style.width="500";
s.style.height="90";
s.style.border="black 1px solid";
s.style.backgroundColor="white";

// 生成iframe
var L=document.createElement("IFRAME");
L.name="completionFrame";

// 定义iframe的样式,宽高与s相同
L.width=s.style.width;
L.height=s.style.height;

// 附加L到s
s.appendChild(L);

// 显示s
document.body.appendChild(s);

其次是你要表现数据的DIV层:t
js如下:

// 创建层
var t=document.createElement("DIV");

// 设置相关属性
t.style.visibility="";
t.zIndex=1;

// 定义样式表,长宽高和定位等
t.style.position="absolute";
t.style.left="200";
t.style.top="100";
t.style.width="500";
t.style.height="90";
t.style.border="blue 1px solid";
t.style.backgroundColor="white";

// 定义你要表现的内容
t.innerHTML = "Hello World";

// 显示
document.body.appendChild(t);

这样就大功告成了,经过测试,在ie和firefox下都是可以的。

这里有几个问题需要说明一下:

  1. 生成的L(IFRAME)我并没有指定其src,但是不影响效果。google-suggest里的iframe对象指定了src:http://www.google.com/webhp?complete=1&hl=en,其实就是一个空白页,我想这么写起来可能更严谨一些吧
  2. 按照我上面写的代码,在实际显示的时候,包含iframe的div层可能会稍大一些,也就是会露出“白边”,大家在实际使用的时候可以进行调整
  3. 注意两个层显示的顺序,也就是append到body的顺序,我是先让包含iframe的层显示,再让显示数据的层显示,如果调换,包含iframe的层就会遮住表现数据的层,即使是改两个层的zindex也不能解决,希望有人能关注一下哈
  4. 如果你拷贝我的代码到你的script中,发现不能运行,有可能是你网页编码的问题,因为我的注释全都是用的中文,如果你用en或utf8输出的话,可能就会有问题
  5. 即使是用iframe,在ie下仍然会有一个bug,就是如果其遮盖的地方有获得焦点的输入框时,它无法遮盖那个闪烁的光标。这个问题在gmail里面也没有解决。不过可以通过一些focus操作来解决这个小小的bug。

这里我只写了js实现的部分,有兴趣的同学可以试着自己封装一下,就先写到这,先去洗衣服了···

想看例子的同学请看这篇文章:http://www.leeyupeng.com/?p=265

GTALK的VoiceMail 酷~

哈哈,今天心情不错,不过不是因为风和日丽,而是因为我终于把ie的流氓插件给干掉了,用的是超级兔子。
之前有听说超级兔子也是个流氓软件,不过今天抱着死马当成活马医的想法,还是去www.pctutu.com下了一个解压缩版的,还挺好使,现在的ie清爽多啦。而且大伙的space都能看了,前几天只要一打开msn的space就死浏览器,今天狂看了一番,爽!!!

罗哩巴嗦一大堆,其实今天让我最兴奋的还是gtalk的新测试版本里的voicemail功能。
下载地址:http://dl.google.com/googletalk/googletalk-setup-testing.exe
一篇中文介绍文章:http://www.ilmay.cn/post/new-gtalk.html

有兴趣的同学可以试试啊,刚才跟他吉和cherry试了试效果,很不错的。
发送的语音邮件存在gmail里,还可以直接下载,很方便。
另外这版的gtalk还加入了传输文件功能,传输速度也很快。
视频聊天和自定义表情还没有,算是个缺憾,但是我想这点功能对google来说应该是小case吧~~,应该会在以后的版本中出现,也许会给我们带来更大的惊喜,期待ing~~

另外谁还没有gmail的话可以留个邮件地址哈,我这还有好多gmail的邀请没发出去呢。

啊,还有还有,明天七夕,祝所有有情人终成眷属,所有单身的命犯桃花
注:今年闰7月,会有两个七夕,yoyoyo~