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

发布新日志

  • web前端性能分析工具

    2008-05-02 00:20:18

     

        以前关注服务器端性能测试,现在投了一些精力在了解web前端性能测试。有几个很趁手的工具

    1)ibm page detailer。注册IBM 帐号后,下载了basic版本的。第一个感觉就是惊艳,能把网页duration(切分服务器时间、下载时间等,与loadrunner page break down类似),item等等.基本上满足我们目前需求.

      在启动page detailer后,再启动IE后的HTTP 请求都被截获。

    2) firefox插件firebug。呵呵,这个工具开源的,功能也很强大,而且javascrīpt调试能力好。呵呵,目前 ALIBABA的部分应用支持firefox不如ie好啊。

    3)yahoo yslow。也是firefox插件。偶还没有试用过:)

      看来好工具还是很多的,关键是要有发现的眼光:)

     

     

     

     

     

  • 前端技术-- ajax框架

    2008-05-02 00:06:35

        by liangjz

         以前性能测试关注重心在服务器端,最近有几个应用提出客户端性能度量问题。呵呵,正在了解前端技术领域。

         前端技术包括Javascrīpt、Actionscrīpt、CSS、xHTML等传统技术与Adobe AIR、Google Gears等新技术。 淘宝网大规模应用ajax框架

       Ajax框架主要有如下几种 :

    Prototype http://prototypejs.org, http://scrīpt.aculo.us
    JQuery    http://jquery.com      
    Ext JS2.0-  javascrīpt library    http://www.extjs.com
    scrīpt.aculo.us
    Mootools
    YUI              http://developer.yahoo.com/yui,淘宝网采用YUI,现在自主研发Tbra(不是100%确信)
    JSON
    Dojo             http://dojotoolkit.org
    BackBase

      另外找到一个firefox上调试js的好插件:firebug

  • 截取mysql 慢语句

    2008-04-30 20:22:25

    by liangjz

     

    最近和开发、DBA一起对MYSQL作性能调优,发现几个点对抓取MYSQL慢语句很有帮助

    在/etc/my.cnf 文件加入

    log_slow_queries
    log-queries-not-using-indexes
    log_long_format
    long_query_time=1

     

      将在mysql数据目录下( datadir = /home/mysql ) 生成一个如test-slow.log的文件,内容有:

    # Time: 080430 20:06:53
    #
    User@Host: match_account[match_account] @  [10.0.4.114]
    # Query_time: 0  Lock_time: 0  Rows_sent: 9  Rows_examined: 18
    SELECT * FROM `tree_menus`   WHERE (parentid = 0)  ORDER BY sequence desc, id desc;
    # Time: 080430 20:09:04

     

    查询用了0秒,返回9行,一共查了18

     

    如何利用呢,有2 种方法:

    1) [root@test mysql]# grep Rows_examined   test-slow.log  | sort -g -k9 -r|uniq -u |head -100
    # Query_time: 0  Lock_time: 0  Rows_sent: 30  Rows_examined: 24460
    # Query_time: 0  Lock_time: 0  Rows_sent: 10  Rows_examined: 24440
    # Query_time: 0  Lock_time: 0  Rows_sent: 9  Rows_examined: 24439
    # Query_time: 0  Lock_time: 0  Rows_sent: 2  Rows_examined: 24432
    # Query_time: 0  Lock_time: 0  Rows_sent: 1  Rows_examined: 24430
    # Query_time: 0  Lock_time: 0  Rows_sent: 0  Rows_examined: 12043
    # Query_time: 0  Lock_time: 0  Rows_sent: 34  Rows_examined: 2441
    # Query_time: 0  Lock_time: 0  Rows_sent: 12  Rows_examined: 1449
    # Query_time: 0  Lock_time: 0  Rows_sent: 15  Rows_examined: 30
    # Query_time: 0  Lock_time: 0  Rows_sent: 5  Rows_examined: 23
    # Query_time: 0  Lock_time: 0  Rows_sent: 6  Rows_examined: 22
    # Query_time: 0  Lock_time: 0  Rows_sent: 9  Rows_examined: 18
    # Query_time: 0  Lock_time: 0  Rows_sent: 1  Rows_examined: 6
    # Query_time: 0  Lock_time: 0  Rows_sent: 1  Rows_examined: 5
    # Query_time: 0  Lock_time: 0  Rows_sent: 2  Rows_examined: 2
    [root@test mysql]# grep -A 1 -B 2  "Rows_examined: 24460"  test-slow.lo
    grep: test-slow.lo: No such file or directory
    [root@test mysql]# grep -A 1 -B 2  "Rows_examined: 24460"  test-slow.log
    # Time: 080430 20:02:29
    #
    User@Host: match_account[match_account] @  [10.0.4.114]
    # Query_time: 0  Lock_time: 0  Rows_sent: 30  Rows_examined: 24460
    SELECT * FROM `profiles`    ORDER BY position, created_at DESC LIMIT 0, 30;

     

    2)方法2:

    [root@test mysql]# mysqldumpslow   -s  t   -t  20

    Reading mysql slow query log from /home/mysql/test-slow.log
    Count: 1  Time=0.00s (0s)  Lock=0.00s (0s)  Rows=6.0 (6), match_account[match_account]@[10.0.4.114]
      SELECT * FROM `reports`    ORDER BY sequence desc LIMIT N

    Count: 1  Time=0.00s (0s)  Lock=0.00s (0s)  Rows=15.0 (15), match_account[match_account]@[10.0.4.114]
      SELECT * FROM `experts`   WHERE (email IS NULL)  ORDER BY sequence desc LIMIT N

     

    一般我们关注的3类,参见

    http://blog.dreamhosters.com/kbase/index.cgi?area=2868

     

    A) "Rows_examined" is more than 2000
    B) "Rows_examined" is less than 2000 but that query is being run 20 times a second.
    C) "Rows_examined" is three times bigger than "Rows_sent"

     

  • 测试中经常遇到的文件句柄打开过多的解决_by_WXC

    2008-04-29 17:23:54

    特别是在搜索性能测试的时候遇到比较多的类似问题:

    有一些概念性的东西还是需要分下类,写一下吧,好记性不如烂笔头。呵呵~

     

    /proc/sys/fs/file-max整个系统可以打开的文件数的限制。
    ulimit -n
    修改的是当前shell和它的子进程可以打开的文件数的限制。

     

    echo 200000 > /pro/sys/fs/file-max 改变当前的系统句柄数目,仅适用于运行中的系统。

    /etc/sysctl.conf文件中加入一行 fs.file-max = 200000 ,然后在命令行中输入 sysctl –p

    永久生效。

     

    ulimit –n 65535 :仅改变当前用户,当前shell及其子shell的句柄数。

    /etc/security/limits.conf: 文件,插入一行:user * nofile  65535:永久改变所有登录用户的句柄数目。

     

    在大并发量的测试时候,遇到too many files open,用一下以上的设置,相信问题会迎刃而解。

  • 解决 perl xml getNodeValue 为空值的过程

    2008-04-19 22:31:29

     今天翻到以前写的一段程序,决定改变文本方式为xml方式描述增强可读性。不想碰到了一个问题折腾了几个小时。

    一 网络安装xml 模块

    ActivePerl-5.8.8.819-MSWin32-x86-267479.msi安装后的路径c:\perl 加入环境变量

    ppm  install  XML::Writer
    ppm  install  XML::DOM

    二 编写XML文件scenarios.xml

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!--
    loadrunner  scenario  drive  events 
    -->
    <scenarios>
     <scenario name="test1"> 
      <loadrunnerscenario>
       <path>f:\1.lrs</path>
       <resultlocation></resultlocation>
      </loadrunnerscenario>   
     </scenario>
     <scenario name="test2">
      <loadrunnerscenario>
       <path>f:\2.lrs</path>
       <resultlocation></resultlocation>
      </loadrunnerscenario>
     </scenario>
    </scenarios>

     

    三 编程获取 path元素的值

     第一次写的程序

     use XML::DOM;
     XML::DOM::Element;
     my $parser = new XML::DOM::Parser;
     my $doc = $parser->parsefile ("scenarios.xml");
     my $nodes = $doc->getElementsByTagName ("loadrunnerscenario");
     my $n = $nodes->getLength;

     for (my $i = 0; $i < $n; $i++)
     {
         my $node = $nodes->item ($i);
         #print  "value=" . $node->toString() . "\n";
         my $subNodes= $node->getElementsByTagName("path");
         my  $subel =$subNodes->item(0);
         print  "nodetype=". $subel->getNodeTypeName . ",value=". $subel->getNodeValue();
              
     }
     # Print doc file
     #$doc->printToFile ("out.xml");
     # Print to string
     #print $doc->toString;
     # Avoid memory leaks - cleanup circular references for garbage collection
     $doc->dispose;

    执行导致
    C:\Perl\bin>perl part2.pl
    nodetype=ELEMENT_NODE,value=
     

    不明白为何getNodeValue=空值?

    再看上下文:
    getNodeValue and setNodeValue (value)
    Returns a string or undef, depending on the node type. This method is provided for completeness. In other languages it saves the programmer an upcast. The value is either available thru some other method defined in the subclass, or else undef is returned. Here are the corresponding methods: Attr::getValue, Text::getData, CDATASection::getData, Comment::getData, ProcessingInstruction::getData.

    似乎也没有错误。到底问题在哪里?

    没有很好的办法,google 到 http://www.ibm.com/developerworks/library/xml-perl2/?S_TACT=105AGX52&S_CMP=cn-a-x


    改写如下,得以解决。问题的关键在于:($node->getNodeType() == TEXT_NODE 才能获取到element的值

     use XML::DOM;
     XML::DOM::Element;
     sub traverse($)
     {
     
      my($node)= @_;

      if ($node->getNodeType == ELEMENT_NODE)
      {
          foreach my $child ($node->getChildNodes())
         {
           return traverse($child);
         }
      }
      elsif ($node->getNodeType() == TEXT_NODE)
      {
        #print $node->getData . "\n";
        $data=$node->getData;
        return $data;
      }
    }

     my $parser = new XML::DOM::Parser;
     my $doc = $parser->parsefile ("scenarios.xml");
     my $nodes = $doc->getElementsByTagName ("loadrunnerscenario");
     my $n = $nodes->getLength;
     for (my $i = 0; $i < $n; $i++)
     {
         my $node = $nodes->item ($i);
         #print  "value=" . $node->toString() . "\n";
         my $subNodes= $node->getElementsByTagName("path");
         my  $subel =$subNodes->item(0);
         #print  "nodetype=". $subel->getNodeTypeName . ",value=". $subel->getNodeValue() . "\n"; 
       
         my $rv=&traverse($subel);

         print $rv ."\n";
         if ($subel->getNodeType == ELEMENT_NODE)
         {
     print  "nodetype=". $subel->getChildNodes()->item(0)->getNodeTypeName. ",nodevalue=". $subel->getChildNodes()->item(0)->getNodeValue(). "\n";
         }
            
     }
     # Print doc file
     #$doc->printToFile ("out.xml");
     # Print to string
     #print $doc->toString;
     # Avoid memory leaks - cleanup circular references for garbage collection
     $doc->dispose;

     

     

  • Acunetix web vulnerality scanner 安全测试使用

    2008-04-19 13:19:39

    推荐一款非常强悍的web 安全测试工具

    http://bbs.51testing.com/thread-112410-1-1.html

  • inet_ntoa(remote_addr.sin_addr) 在64位linux下core dump

    2008-04-15 21:18:52

    在编写一个网络应用程序,在32位Linux下已经运行了相当长时间,无core dump,移植到64

    我都是单进程执行的。

     

     

    Program terminated with signal 11, Segmentation fault.

    #0  0x0000003a53c75350 in strlen () from /lib64/libc.so.6

    (gdb) bt

    #0  0x0000003a53c75350 in strlen () from /lib64/libc.so.6

    #1  0x0000003a53c45b88 in vfprintf () from /lib64/libc.so.6

    #2  0x0000003a53c60e09 in vsprintf () from /lib64/libc.so.6

    #3  0x0000003a53c4b958 in sprintf () from /lib64/libc.so.6

    #4  0x000000000040156b in socket_server () at getlinuxstat.c:183

    #5  0x0000000000401c90 in main (argc=1, argv=0x7fff4b872328) at getlinuxstat.c:349

    (gdb) f 4

    #4  0x000000000040156b in socket_server () at getlinuxstat.c:183

    183                                                                                                             sprintf(buf_log,"received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));

     

      咨询开发用线程安全的inet_ntop函数,但是这样的话,就会用到两个额外的数组。总要有些牺牲的。
    使用inet_ntoa的话,就不能够在同一个函数的几个参数里面出席那两次inet_ntoa,或者是第一个inet_ntoa未使用结束之前,不要使用第二个。

    更改实现为:

     if ( NULL== (char*) (inet_ntop(AF_INET,&remote_addr.sin_addr.s_addr,str,31)) )

     

    详细的代码如下:

    int socket_server()

    {

        int sockfd,client_fd; /*sock_fd:监听socketclient_fd:数据传输socket */

        struct sockaddr_in my_addr; /* 本机地址信息 */

        struct sockaddr_in remote_addr; /* 客户端地址信息 */

        int sin_size;

        char  recv_buf[MAX_BUF_SIZE]={0};

        int   recv_size=0;

        char  send_buf[MAX_BUF_SIZE]={0};

        int    send_size=0;

        int  pid;

        int  status;

        struct timeval tv;

        struct in_addr clientaddr ;

        char  str[32]={0};

        char  buf_log[MAX_BUF_SIZE]={0};

     

        enum  stat_action  action;

        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

            sprintf(buf_log,"socke errno=%d,desc=%s\r\n",errno,strerror(errno));

            buf_log[strlen(buf_log)]=0;

            writelog(g_logfile,buf_log);

            return 1;

        }

     

       my_addr.sin_family=AF_INET;

       my_addr.sin_port=htons(SERVPORT);

       my_addr.sin_addr.s_addr = INADDR_ANY;

       bzero(&(my_addr.sin_zero),8);

       if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))  == -1) {

          sprintf(buf_log,"bind errno=%d,desc=%s\r\n",errno,strerror(errno));

          buf_log[strlen(buf_log)]=0;

          writelog(g_logfile,buf_log);

          return 1;

       }

       if (listen(sockfd, BACKLOG) == -1) {

         sprintf(buf_log,"bind errno=%d,desc=%s\r\n",errno,strerror(errno));

            buf_log[strlen(buf_log)]=0;

            writelog(g_logfile,buf_log);

         return 1;

        }

        tv.tv_sec= SOCKET_TIMEOUT_SECOND;

        tv.tv_usec=0;

     

        while(1) {

             memset(&remote_addr, 0, sizeof(struct sockaddr));

            sin_size = sizeof(remote_addr);

            if ((client_fd = accept(sockfd, (struct sockaddr *)(&remote_addr), &sin_size)) == -1) {

               sprintf(buf_log,"accept errno=%d,desc=%s\r\n",errno,strerror(errno));

               buf_log[strlen(buf_log)]=0;

               writelog(g_logfile,buf_log);

               continue;

              }

     

            //sprintf(buf_log,"received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));

     

            if ( NULL== (char*) (inet_ntop(AF_INET,&remote_addr.sin_addr.s_addr,str,31)) )

            {

               printf("inet_ntop error,errno=%d,desc=%s\r\n",errno,strerror(errno) );

            }

            sprintf(buf_log,"received a connection from %s\n", str);

     

            buf_log[strlen(buf_log)]=0;

            writelog(g_logfile,buf_log);

     

           if (setsockopt(client_fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1)

           {

              sprintf(buf_log,"warning!setsockopt  errno=%d,desc=%s\r\n",errno,strerror(errno));

             buf_log[strlen(buf_log)]=0;

             writelog(g_logfile,buf_log);

           }

     

           if ( (pid=fork()) == 0) { /* 子进程代码段 */

               while(1)

               {

                 memset(recv_buf,0,MAX_BUF_SIZE);

                 recv_size=recv(client_fd,recv_buf,MAX_BUF_SIZE -1 ,0);

                 if(recv_size ==-1)

                 {

                    sprintf(buf_log,"recv errno=%d,desc=%s\r\n",errno,strerror(errno));

                     buf_log[strlen(buf_log)]=0;

                    writelog(g_logfile,buf_log);

                    close(client_fd);

                    exit(1);

                 }

                 else if( 0== recv_size)

                {

                   sprintf(buf_log,"connection reset by peer!\r\n");

                    buf_log[strlen(buf_log)]=0;

                    writelog(g_logfile,buf_log);

                   exit(1);

                }

                 else     //if (1 == recv_size)

                 {

     

                   action=atoi(recv_buf);

                   sprintf(buf_log,"recv_buf=%s,recv_size=%d,action=%d\r\n",recv_buf,recv_size,action);

                   buf_log[strlen(buf_log)]=0;

                   writelog(g_logfile,buf_log);

                   memset(send_buf,0,MAX_BUF_SIZE);

     

                   if (exec_command(2,action,send_buf) ==-1 )

                    {

                         continue;

                    }

     

                   send_buf[ strlen(send_buf)] = 0;

                   sprintf(buf_log,"begin send...,send_buf=%s\r\n",send_buf);

                   buf_log[strlen(buf_log)]=0;

                   writelog(g_logfile,buf_log);

                   if (send(client_fd, send_buf,strlen(send_buf), 0) == -1) {

                      sprintf(buf_log,"send errno=%d,desc=%s\r\n",errno,strerror(errno));

                       buf_log[strlen(buf_log)]=0;

                       writelog(g_logfile,buf_log);

                      close(client_fd);

                      exit(1);

                   }

     

                 }

              }

          }

          else if(pid <0)

          {

            sprintf(buf_log,"socket_server fork errno=%s\n",strerror(errno));

            buf_log[strlen(buf_log)]=0;

            writelog(g_logfile,buf_log);

          }

          else

          {

            //parent;

            close(client_fd);

            waitpid(pid,&status,0);

     

           }

     

       }

      return 0;

    }

     

     

     

     

     

     

  • ADODB.Connection使用OraOLEDB.OracleOracle字串链接数据库

    2008-04-14 09:35:52

    我们自动化脚本很多时候需要链接数据库进行数据验证或者数据准备,一般是用ADODB.Connection对象的open方法获取数据库链接,open方法的链接字串可以有很多种的形式,如:使用odbc、OraOLEDB.OracleOracle,但我们需要只需读取某个配置文件中的host、port、sid、userid、password就可以获得adobd的数据库链接,而不想在运行脚本的每台机器单独配置odbc或者oracle的tnsnames.ora,我们可以用OraOLEDB.OracleOracle字串获取链接adodb的数据库链接

    strHost=从配置文件获取

    strPort=从配置文件获取

    strSID=从配置文件获取

    strUser=从配置文件获取

    strPassword=从配置文件获取

    strConnectionString = "Provider=OraOLEDB.Oracle;Persist Security Info=True;"&_
            "Data Source=(DEscrīptION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST ="+strHost +")(PORT = "+strPort+")))"&_
            "(CONNECT_DATA =(SID = "+strSID+")));User ID="+strUser+";Password="+strPassword+";"

    Set ōConnection= createobject("ADODB.Connection")

    oConnection.ConnectionString = strConnectionString
    On error Resume Next 
    oConnection.open
    If err.Number <> 0 Then
     msgbox "数据库连接失败"
    End

  • SUSE10 XGL超牛的3D桌面效果视频

    2008-04-08 22:32:09

  • 如何得到localmachine的odbc driver安装配置?

    2008-04-08 14:31:20

     

    同样,在获取odbc driver时,也可以用下面方法来实现:

    Const HKLM = &H80000002
    Set reg = GetObject( "winmgmts:\\.\root\default:StdRegProv" )
    keyPath = "SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers"
    reg.EnumValues HKLM, keyPath, valueNamesArr, valueTypeArr
     For i = 0 to UBound( valueNamesArr )
       reg.GetStringValue HKLM, keyPath, valueNamesArr( i ), valueStr   
        Print valueNamesArr( i ) & " –> " & valueStr
     Next

    打印显示条目,具体可以参照附件。

  • 如何得到odbc数据源中系统DSN的安装配置?

    2008-04-08 14:22:28

     

    上个月在研究框架excel遍历提速时,起初设想通过dsn对象来访问excel,

    但需要遍历操作系统中是否安装excel driver和是否已经存在dsn, 但迫于这种方案比较土。后来没有这么做而是采用jet对象直接动态访问excel数据源. 其间在实现上述提到的方案,后来找到相关实现方法, 没有用到任何wmi和com对象,只是遍历与访问注册表。

    Const HKLM = &H80000002 '定义常量
     Set reg = GetObject( "winmgmts:\\.\root\default:StdRegProv" )
     keyPath = "SOFTWARE\ODBC\ODBC.INI\ODBC DATA SOURCES" ' 欲取注册表分支
     reg.EnumValues HKLM, keyPath, valueNamesArr, valueTypeArr  '前面两个参数是传入,后面两个是传出参数, 均为数组。


     For i = 0 to UBound( valueNamesArr )  
       reg.GetStringValue HKLM, keyPath, valueNamesArr( i ), valueStr      
        Print valueNamesArr( i ) & " –> " & valueStr
        Next

  • sshd服务连接过慢问题的解决

    2008-04-08 13:49:43

    经常遇到在一台服务器ssh到另外一台server的时候,半天才出来一个输入密码提示。

    解决方案如下:1。在server上/etc/hosts文件中把client端的ip和hostsname加入

    (ssh连接过程中需要做dns逆向解析),没有获得明显连接提速

    2。server的/etc/ssh/sshd_config配置中修改GSSAPIAuthentication no,重起sshd服务

    连接过慢问题得以解决。后经研究发现,GSSAPI参数是提供kerberos验证的,连接过慢正是由于

    kerberos安全验证身份时太多耗时。一般情况下,在测试机上ssh,通常不需要这种高级别的安全验证。

  • 借助jclasslib与javassist修改java class字节码

    2008-04-05 20:18:59

     

    http://bbs.51testing.com/thread-110784-1-1.html

      有时候,我们在没有java源程序的情况下,想改变.CLASS文件的部分内容输出或者改变跳转流,怎么办呢?
      介绍2个java hacker的工具javassist 以及jclasslib。

  • 一个清除共享内存段的小工具

    2008-04-02 10:14:26

    # !/bin/sh

    filter="admin"

    for i in `ipcs -m | grep $filter | awk '/0x/{print $2}'`

    do
    ipcrm -m $i
    done

  • 免费跨站攻击扫描工具

    2008-04-02 00:14:42

    免费跨站攻击扫描工具paros与appscan 对比

    2者对比发现paros的结果有很多的不足

     

    1)      SQL 注入扫描貌似有问题

    2)      跨站脚本有遗漏

    3)      Lotus dimino 有安全问题误报

    4)      报表、修复建议没有appscan强大

    5)      Appscan集成强大的安全规范

    6)     

    更多见http://bbs.51testing.com/viewthread.php?tid=110473&extra=page%3D1&frombbs=1

  • 修改HTTP Post/get数据利器TamperIE

    2008-04-01 23:31:07

    近期关注安全测试,将陆续介绍接触到的一些很好的工具。

    安全工具是一把双刃剑,用好了给测试工作带来很大的便利。

    本期介绍修改HTTP Post/get数据利器TamperIE。

    http://bbs.51testing.com/thread-110474-1-1.html

  • 阿里巴巴质量保证部介绍

    2008-04-01 10:20:48

     

    一、部门简介:

    阿里巴巴质量保证部门是通过测试、流程管理、配置管理等手段保证高质量软件的产生;部门人员的角色主要为:测试工程师、软件质量保证工程师(SQA)和配置管理工程师(SCM)。

    部门主要职责如下:

       1、公司各产品线项目的功能及性能测试;

       2、公司各产品线质量保证体系的制订、维护、流程控制和检查;

       3、公司个产品线与质量有关的文件和代码维护和管理。

    二、精英辈出:

    阿里巴巴质量保证部门是互联网领域质量保证的先行者,一直致力于将领先的技术和理念运用于构建世界级互联网平台的质量保证中。部门汇聚了业内各个方面的精英,特别在性能测试技能方面,一直是业内领先的;并且,部门内部建立了完善的个人成长、技能提升和系统培养的职业发展体系,创造优异的条件让更多的工程师成为各个领域的专家。

    三、快乐工作:

    快乐工作是阿里巴巴的文化,在质量保证部门更是突出——我们提倡努力工作,更倡导快乐生活!目前的36位同事就像一个大家庭,不仅有“帅哥+美女”的组合,还有FUN的气氛,杭州每一处秀丽的风景都留下了我们团队的欢声笑语!

     

    热烈欢迎更多的精英加入阿里巴巴质量保证的大家庭,共同打造有质量的软件,共同享受有质量的生活!

     

  • 从limits.conf说开去

    2008-03-31 22:35:10

    一日,遇到log中too many open files的问题,在limits.conf中设置了 * - nofile 10240后,该问题得到解决。但是limits.conf的后面是怎么工作的呢?

    后端是这样的:limits.conf是pam_limits.so的配置文件,然后/etc/pam.d/下的应用程序调用pam_***.so模块。譬如说,当用户访问服务器,服务程序将请求发送到PAM模块,PAM模块根据服务名称在/etc/pam.d目录下选择一个对应的服务文件,然后根据服务文件的内容选择具体的PAM模块进行处理。

    一个例子:限制admin用户登录到sshd的服务不能超过2个

    在/etc/pam.d/sshd 中添加 session required pam_limits.so

    在/etc/security/limits.conf中添加 admin - maxlogins 2

    查看应用程序能否被PAM支持,用ldd

  • ntp 同步linux 机器时间

    2008-03-24 18:51:31

     

      1台机器时间同步很容易的,当同步很多台机器的时候还用一台机器的同步方法就很落后了。所以在google、yahoo等大型网络公司,它们的系统管理技术变成一门很高深的技术。

      扯远了。我简单说说我的一个实现方式

    1)

    service ntpd stop 停止ntpd服务。root 用户crond 任务列表加入定时更改时间的任务

       [root@crm_test_1 root]# crontab  -l
    1 * * * * /usr/sbin/ntpdate 10.0.1.228

     

     上述就是每分钟同步一次。 ntpdate 后面跟的是基准的时间服务器

    2)  service crond restart  重启服务生效。

      建议做之前用/usr/sbin/ntpdate 10.0.1.228 测试一下:

    [root@crm_test_1 root]# /usr/sbin/ntpdate 10.0.1.228
    24 Mar 18:46:24 ntpdate[27579]: adjust time server 10.0.1.228 offset 0.033429 sec

     

     

     

     

  • 如何对qtp无法识别的web对象输入值

    2008-03-24 11:00:14

    在我们录制自动化脚本的时候,常常会发现某些activeX的对象的输入操作,qtp是无法录制的,但该输入项又是页面的必填项,其实这些无法识别的activeX对象qtp基本统一识别为WebElement对象,我们可以利用WebElement对象的innertext属性复制来模拟输入操作

    1、对于无法识别的对象,我们可以通过object spy,add到对象库

    2、然后对该对象的innertext属性进行赋值:

    Browser("xxx").Page("xxx").Frame("Frame").WebElement("WebElement").Object.innerText = "xxx"

     

     

1567/8<12345678>
Open Toolbar