记录阿里巴巴QA架构组成长点滴。2008年关键词为效率,技术,影响力!QA/测试架构师定义:开发和设计测试框架测试库;纵横全局的考虑产品的功能,设计复杂的测试系统;负责研发某一项特定的测试技术;为公司考虑如何提高测试效率。领导公司测试技术的发展和测试策略上的方向,关注整个公司的测试部门的问题,前瞻性的考虑未来的版本的测试策略和技术。测试架构师计划/设计测试平台,关注着产品的测试过程,提供咨询服务,影响到公司内的测试机构测试社区,以及开发机构等,对产品各个方面施加深远而正确的影响,最终提高整体软件质量。

我的最新日志

  • QTP的Browser对象部分方法失效问题的解决

    2008-9-28

    by jack

    一直以来有个问题,困扰着部分使用QTP的同学:部分Browser方法,如Navigate、Back、Home、Refresh等在某些人的机器上是好用的,但在另外一些人的机器上就不好用了。脚本执行到这些方法,并不会抛出错误;而且qtp日志里看到的状态是"done"。

    经过一段时间的观察,终于发现这些机器上IE加载项(IE"工具"->"管理加载项")的不同:

    BHOManager Class插件的问题。文件名是BHOManager.dll,部分人的机器上该插件被禁用或删除掉了,猜测原因可能是使用了某些清理ie的工具导致。

    解决该问题的方法很简单:

    如果是被禁用了,只要重新启用即可;如果是被删除掉了,可以重新安装qtp,或者从别处拷贝BHOManager.dll文件过来,用regsvr32 BHOManager.dll注册后就可以了。

    Navigate、Back、Home、Refresh等方法还是很实用的,不能使用确实是比较麻烦的:)

  • Spring Velocity macro应用与调试

    2008-9-26

     

      默认情况下,velocity macro文件修改没有被应用服务器检测,必须重启才能生效。

     

     

    Spring  web.xml contextConfigLocation配置包含属性文件mvc-config.xml

     

    <servlet>

    <servlet-name>dispatcherServlet</servlet-name>     

    <servlet-class>  org.springframework.web.servlet.DispatcherServlet        </servlet-class>      

    <init-param>          

    <param-name>contextConfigLocation</param-name>         

    <param-value>

    /WEB-INF/mvc-config.xml

    /WEB-INF/alert-config.xml

    </param-value>   

    </init-param>  

    <load-on-startup>1</load-on-startup>  

     </servlet>

     

     

    mvc-config.xml 部分内容如下:

     

                  <bean id="velocityConfigurer"                           class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">

                  <property name="resourceLoaderPath">

                  <value>WEB-INF/velocity/</value>  

                  </property>

                  <property name="velocityProperties">

                         <props>

                         <prop key="input.encoding">gb2312</prop>

                         <prop key="output.encoding">gb2312</prop>

                         <prop key="contentType">text/html;charset=gb2312</prop>

                         <prop key="file.resource.loader.cache">false</prop>

                         <prop key="file.resource.loader.modificationCheckInterval">1</prop>

                         <prop key="velocimacro.library.autoreload">true</prop>

                         <prop key="velocimacro.library">templates.vm</prop>

                         <prop key="runtime.log.logsystem.class">org.apache.velocity.runtime.log.SimpleLog4JLogSystem</prop>

                         <prop key="runtime.log">com.ali</prop>

                         <prop key="runtime.log.error.stacktrace">true</prop>

                         <prop key="runtime.log.warn.stacktrace">true</prop>

                         <prop key="runtime.log.info.stacktrace">false</prop>

                         <prop key="runtime.log.invalid.reference">true</prop>

                  </props>

                  </property>

     

           </bean>

          

             <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">

               <property name="suffix"><value>.vm</value></property>

                         <property name="exposeSpringMacroHelpers"><value>true</value></property>

                         <property name="exposeRequestAttributes"><value>true</value></property>

                         <property name="exposeSessionAttributes"><value>true</value></property>

                         <property name="contentType" value="text/html;charset=gb2312" />

                         <property name="dateToolAttribute">

          <value>dateTool</value>

               </property>

            </bean>

     

     

     

    Velocity 文件包括库文件templates.vm都放在WEB-INF/velocity/

    确保velocity文件被修改都立即重新扫描,关键的参数:

    <prop key="file.resource.loader.cache">false</prop>

                         <prop key="file.resource.loader.modificationCheckInterval">1</prop>

                         <prop key="velocimacro.library.autoreload">true</prop>

     

     

    index.vm上通过:

    #parse("templates.vm") 引入velocity 模版。

     

  • 一次mysql部分汉字乱码解决过程

    2008-9-26

     

        从Confluence db导出数据在mysql控制台上乱码,在SPRING MVC页面也乱码,如。从confunce应用页面上看,无乱码。到底原因在哪里呢?

     

    由于涉及的层非常多,只能用隔离法。

        主要有几种可能

    1)      db里面的数据是否真有乱码

    2)      输出到页面上的汉字有乱码

    3)      页面编码识别有错

     

    1.1.1    mysql 控制台检查:

    mysql> show variables  like  'char%';

    +--------------------------+-----------------------------------+

    | Variable_name            | Value                             |

    +--------------------------+-----------------------------------+

    | character_set_client     | gb2312                            |

    | character_set_connection | gb2312                            |

    | character_set_database   | utf8                              |

    | character_set_filesystem | binary                            |

    | character_set_results    | gb2312                            |

    | character_set_server     | utf8                              |

    | character_set_system     | utf8                              |

    | character_sets_dir       | D:\MySQLServer5.0\share\charsets\ |

    +--------------------------+-----------------------------------+

    8 rows in set (0.05 sec)

     

    mysql> show variables  like  'coll%';

    +----------------------+-------------------+

    | Variable_name        | Value             |

    +----------------------+-------------------+

    | collation_connection | gb2312_chinese_ci |

    | collation_database   | utf8_general_ci   |

    | collation_server     | utf8_general_ci   |

    +----------------------+-------------------+

    3 rows in set (0.00 sec)

     

     

    在控制台依然乱码。

     

    下载MYSQL Administrator,用Mysql query browser查看,OK的。

     

    只能剩下2种可能了。

     

    1.1.2    JDBC直接连接DB

    String url =     "jdbc:mysql://127.0.0.1:3306/scmproj?user=root&password=mysql&useUnicode=true&characterEncoding=GB2312";

     

                         java.sql.Connection con = DriverManager.getConnection(url);

     

                         Statement stmt = con.createStatement();

     

          

                         String query = "select * from users where email='yi.suy@alibaba-inc.com'";

     

                         ResultSet rs = stmt.executeQuery(query);

     

                while (rs.next())

     

                         {

                                // System.out.println(new

                                // String(rs.getString(1).getBytes("UTF8")).toString());

                                System.out.println(new String(rs.getString("fullname")));

                         }

      

      同样输出正确。

     

    1.1.3    IBATIS API连接DB

    private static SqlMapClient sqlMapper;

     

    private static SqlMapClient sqlMapper;  Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");

                         // Reader reader =

                         // Resources.getResourceAsReader("D:/eclipse-SDK-3.3.2-win32/project/SCMProj/bin/SqlMapConfig.xml");

                         sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);

                         reader.close();

     

    List list =sqlMapper.queryForList("getProjectByName", queryStr);

                                        SCMProject proj=(SCMProject) list.get(0);

     

    正常。

     

    剩下来的就是检查SPRING的编码格式了。

     

    最后锁定SPRING   VelocityViewResolver

    <property name="contentType" value="text/html;charset=UTF-8" />

     

  • 批量点击链接(去重)

    2008-9-24

    by jack

    日前忽然有人问我,想把一个页面上的搜索结果链接都点一遍分别检查,这个脚本怎么写

    想想这个需求很简单,就顺手用descrīption对象写了,以口碑网搜索结果为例,脚本如下:

    SystemUtil.Run "http://bendi.koubei.com/search/searchlocal.html?option.key=%D1%C5%CA%CB%D4%B7&option.cityname=%BA%BC%D6%DD&searchFlag=1&city=2595"


    Set ōDesc = Descrīption.Create()

    oDesc("micclass").Value="Link"
    oDesc("url").Value="http://hangzhou.koubei.com/store/detail--storeId-.*"

    Set Lists = Browser("title:=雅虎口碑.*").Page("title:=雅虎口碑.*").ChildObjects(oDesc)
    NumberOfLists = Lists.Count()

    For i = 0 To NumberOfLists - 1 
      Lists(i).click
      ……
    Next

    点击的都是http://hangzhou.koubei.com/store/detail--storeId-这种格式的链接,也就是结果链接的统一格式

    这里有个点要注意:descrīption对象默认就是支持正则表达式的,可以用正则表达式作为属性值

    但是很快就反馈回来一个问题:页面上有重复的链接,这样实际是存在重复点击的;在结果比对时出现了点问题

    想了想,就再加入了一段去重的处理,修改脚本如下:

     

    SystemUtil.Run "http://bendi.koubei.com/search/searchlocal.html?option.key=%D1%C5%CA%CB%D4%B7&option.cityname=%BA%BC%D6%DD&searchFlag=1&city=2595"


    Dim arrClickedLink()
    ReDim Preserve arrClickedLink(0)

    Set ōDesc = Descrīption.Create()

    oDesc("micclass").Value="Link"
    oDesc("url").Value="http://hangzhou.koubei.com/store/detail--storeId-.*"

    Set Lists = Browser("title:=雅虎口碑.*").Page("title:=雅虎口碑.*").ChildObjects(oDesc)
    NumberOfLists = Lists.Count()

    For i = 0 To NumberOfLists - 1
        sCurrentLink = Lists(i).getroproperty("url")
     If not isClickedLink(sCurrentLink) Then
      Lists(i).click
      ……
     End If
    Next

    Function isClickedLink(url)

     iClickedLinkLen = ubound(arrClickedLink)

     For n=0 to iClickedLinkLen
      If url = arrClickedLink(n) Then
       isClickedLink = True
       Exit Function
      End If
     Next

     ReDim Preserve arrClickedLink(iClickedLinkLen+1)
     arrClickedLink(iClickedLinkLen+1) = url
     isClickedLink = False

    End Function

     

     

  • [Ruby学习] 在ruby中调用dll

    2008-9-24

                                                                          -----by Nish 

      开源测试工具watir是采用的ruby语言进行开发的。在研究watir框架的时候,发现有一部分函数watir没有提供而且暂时没找到合适的gem包,而很多功能在我们原来的自动化测试框架中都通过c写的dll进行了实现,于是我们希望能够把这部分的dll无缝的移植到watir上,减少我们的工作量,而且可以更高效的实现我们需要的功能。

      在ruby的开源项目中,Win32Api这个gem可以实现我们需要的功能。通过以下方法 ,我们就可以调用外部dll中的函数。

    Win32Api.new(dllname, proc, import, export)

    参数说明

    dllname:dll文件的名字,如果想只写dll的名字,可以将dll放到system32目录或者当前目录下,或者写上dll文件所在的路径

    proc: dll中函数的名字

    import:函数传入参数的参数类型,其中 "p" 对应指针,"n","l"对应long,"i"对应 int,"v" 对应void,如果有多个参数,可以通过 ["p","n"]数组的方式来实现,其中置为nil可以表示没有参数

    export:函数的返回值类型,参数类型同上

     

    Win32API#call([args ...])

    调用dll中的函数,参数和返回值应该与new申明中的一致,如果返回一个指针,需要事前初始化,否则可能会有内存溢出问题。

     

    例子:

    有个dll的头文件的申明为:

    extern "C" long PASCAL EXPORT BMPToJPG(char *jpg,char *bmp);

    那么在将指定的dll文件放在当前目录,ruby代码如下

    require 'rubygems'

    require 'Win32Api'

    JPG=Win32API.new(File.dirname(__FILE__)+"\\JpgDll.dll","BmpToJpg",["p","p"],"l")

    JPG.call("D:\\1.bmp","D:\\1.jpg")

    执行上述代码后,就能把D盘下的1.bmp文件另存为 1.jpg文件

  • bash3.0的新特性-ps命令

    2008-9-24

    ps命令中的status状态 bash3.0以上支持(kernel 2.6以上)
        D Uninterruptible sleep (usually IO) 
        R Running or runnable (on run queue) 运行中
        S Interruptible sleep (waiting for an event to complete) 可打断的后台进程,类似守护进程httpd、ntpd、crond等
        T Stopped, either by a job control signal or because it is being traced. 
        W paging (not valid since the 2.6.xx kernel) 
        X dead (should never be seen) 
        Z Defunct ("zombie") process, terminated but not reaped by its parent. 

        For BSD formats and when the stat keyword is used, additional characters may be displayed: 
        < high-priority (not nice to other users) 高优先级
        N low-priority (nice to other users) 低优先级
        L has pages locked into memory (for real-time and custom IO) 
        s is a session leader 主进程
        l  is multi-threaded (using CLONE_THREAD, like NPTL pthreads do) 表示线程
        + is in the foreground process group 前台运行
     
        譬如:ps -axuf后status column中:Ss表示父进程、R+正在前台运行的进程、SN表示低优先级的进程,S+、Sl表示线程、SL等
  • bash3.0的新特性-history命令

    2008-9-24

    bash3.0之后,history命令推出一个新的常量

    HISTTIMEFORMAT变量:记录历史命令的执行时间

    譬如:HISTTIMEFORMAT="[%F %T]"

    执行history,显示:

    490  [2008-07-16 15:12:23]HISTTIMEFORMAT="[%F %T]"
    491  [2008-07-16 15:12:25]history
    492  [2008-07-16 15:12:32]man date

    在监控用户何时使用了哪个具体的命令,监控用户行为方式有很大的用处

  • 利用托盘程序显示自动化执行进度

    2008-9-17

    by jiale

    在自动化执行过程中需要显示自动化执行的进度,如果使用msgbox,就需要人工干预,且无法一直显示执行进度并实时刷新,理想的结果是脱离qtp且能够实时得到执行的进度。

    在自动化执行过程中将执行进度写入文本文件,利用windos托盘程序,实时读某文件,且利用托盘程序并可显示或隐藏进度窗口。

    vb托盘程序在网上可以轻易找到,不再附上。

  • HTTP GET请求传输汉字给SPRING MVC的处理

    2008-9-15

    HTTP GET请求在提交数据给服务器方面和POST有很多差异。比如传输字节数大小,编码要求等。

    HTTP GET请求要求对汉字进行URL 编码。

     

    IE客户端javascrīpt/vbscrīpt代码。

        

     

    <scrīpt language="vbscrīpt">

    Function GetByteCode(ch)   

        code = Asc(ch)          ' -20001

        GetByteCode = Hex(code) ' "B1DF"

    End Function

    </scrīpt>


    <scrīpt language="javascrīpt">

    String.prototype.urlEncode = function() {

        var r = "";

        for (var i = 0; i < this.length; i++) {

            var code = "" + GetByteCode(this.charAt(i));

            if (code.length > 2) {

                var b1 = code.substr(0, code.length - 2);

                var b2 = code.substr(code.length - 2);

                if (i == 0) {

                    //alert("" + code + ", " + b1 + ", " + code.length + ", " + b2);

                }

                r += "%" + b1 + "%" + b2;

            } else {

                r += "%" + code;
            }
        }
        return r;
    }

    </scrīpt>

     

     

     

    调用上述函数编码

    Var  projectname=”项目1”;

    var urlEncoded=projectname.urlEncode();

     var url="insertCheckList.do?projectname="+urlEncoded;

    接下来就是用AJAX  httprequest发送给JBOSS/TOMCAT。

     

     

     

    服务器端SPRING 接收到字符串解码:

     

    public ModelAndView handleRequestInternal(HttpServletRequest request,

               HttpServletResponse response) throws Exception {

     

    String encodeProj = request.getParameter("projectname");

          

               //客户端经过编码后的汉字

              

               String projectname= new String( encodeProj.getBytes( "8859_1" ) , "gb2312" );

               System.out.println(projectname);      

     

    }

  • webtable对象,利用嵌套字典对象来转化,从而具有逻辑意义

    2008-9-10


    by Wiston Li

    页面中存有大量的webtable,利用getcelldata方法,需要指定行、列的index. 但若在页面上用户

    进行操作上排序,数据排列将发生变化,下面的方法,利用嵌套字典对象来转化,从而具有逻辑意义

    表现访问单元格的值,从而减少参考物理单元格。(数据表如附件所示:)

     

     

     Dim oDataTable
     Dim solarExch
     Dim nRows

     set  ōDataTable=objIdentifyPage ("阿里助手","n").WebTable("text:=操作指南.*","index:=0").WebTable("text:=选择.*")
     Set solarExch = CreateObject("scrīpting.Dictionary")
     nRows=oDataTable.rowcount  
     For  nRow=2 to nRows
      symbolKey =oDataTable.getcelldata(nRow,2)
      solarExch.add symbolkey, createObject("scrīpting.Dictionary")
      solarExch(symbolKey).add "quantity", oDataTable.getcelldata(nRow,3)
      solarExch(symbolKey).add "price", oDataTable.getcelldata(nRow,4)
      solarExch(symbolKey).add "oneprice", oDataTable.getcelldata(nRow,5)
      solarExch(symbolKey).add "highprice", oDataTable.getcelldata(nRow,6)
      solarExch(symbolKey).add "situation", oDataTable.getcelldata(nRow,7)
      
     Next

        msgbox solarExch("asf").item("oneprice")'显示附土中,asf(关键词)这一行,一口价的值,并不依赖当前行列的顺序,即便重新排序。
        msgbox solarExch("试纸").item("price")

Open Toolbar