qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

MySQL数据库性能优化之存储引擎选择

 InnoDB

  1、特性

  具有较好的事务支持:支持4个事务隔离级别,支持多版本读

  行级锁定:通过索引实现,全表扫描仍然会是表锁,注意间隙锁的影响

  读写阻塞与事务隔离级别相关

  具有非常高效的缓存特性:能缓存索引,也能缓存数据

  整个表和主键以Cluster方式存储,组成一颗平衡树

  所有Secondary Index都会保存主键信息

  2、适用场景

  需要事务支持(具有较好的事务特性)

  行级锁定对高并发有很好的适应能力,但需要确保查询是通过索引完成

  数据更新较为频繁的场景

  数据一致性要求较高

  硬件设备内存较大,可以利用InnoDB较好的缓存能力来提高内存利用率,尽可能减少磁盘 IO

  3、最佳实践

  主键尽可能小,避免给Secondary index带来过大的空间负担

  避免全表扫描,因为会使用表锁

  尽可能缓存所有的索引和数据,提高响应速度

  在大批量小插入的时候,尽量自己控制事务而不要使用autocommit自动提交

  合理设置innodb_flush_log_at_trx_commit参数值,不要过度追求安全性

  避免主键更新,因为这会带来大量的数据移动

  NDBCluster

  1、特性

  分布式:分布式存储引擎,可以由多个NDBCluster存储引擎组成集群分别存放整体数据的一部分

  支持事务:和Innodb一样,支持事务

  可与mysqld不在一台主机:可以和mysqld分开存在于独立的主机上,然后通过网络和mysqld通信交互

  内存需求量巨大:新版本索引以及被索引的数据必须存放在内存中,老版本所有数据和索引必须存在与内存中

  2、适用场景

  具有非常高的并发需求

  对单个请求的响应并不是非常的critical

  查询简单,过滤条件较为固定,每次请求数据量较少,又不希望自己进行水平Sharding

  3、最佳实践

  尽可能让查询简单,避免数据的跨节点传输

  尽可能满足SQL节点的计算性能,大一点的集群SQL节点会明显多余Data节点

  在各节点之间尽可能使用万兆网络环境互联,以减少数据在网络层传输过程中的延时

  注:以上三个存储引擎是目前相对主流的存储引擎,还有其他类似如:Memory,Merge,CSV,Archive等存储引擎的使用场景都相对较少,这里就不一一分析了,如果有朋友感兴趣,后面再补充吧。

  MySQL 的存储引擎可能是所有关系型数据库产品中最具有特色的了,不仅可以同时使用多种存储引擎,而且每种存储引擎和MySQL之间使用插件方式这种非常松的耦合关系。

 

  由于各存储引擎功能特性差异较大,这篇文章主要是介绍如何来选择合适的存储引擎来应对不同的业务场景。

  系列的第五篇文章:MySQL数据库性能优化之存储引擎选择

  系列的第四篇文章:MySQL数据库性能优化之SQL优化

  系列的第三篇文章:MySQL数据库性能优化之索引优化

  系列的第二篇文章:MySQL 数据库性能优化之表结构优化

  系列的第一篇文章:MySQL 数据库性能优化之缓存参数优化

  MyISAM

  1、特性

  不支持事务:MyISAM存储引擎不支持事务,所以对事务有要求的业务场景不能使用

  表级锁定:其锁定机制是表级索引,这虽然可以让锁定的实现成本很小但是也同时大大降低了其并发性能

  读写互相阻塞:不仅会在写入的时候阻塞读取,MyISAM还会在读取的时候阻塞写入,但读本身并不会阻塞另外的读

  只会缓存索引:MyISAM可以通过key_buffer缓存以大大提高访问性能减少磁盘IO,但是这个缓存区只会缓存索引,而不会缓存数据

  2、适用场景

  不需要事务支持(不支持)

  并发相对较低(锁定机制问题)

  数据修改相对较少(阻塞问题)

  以读为主

  数据一致性要求不是非常高

  3、最佳实践

  尽量索引(缓存机制)

  调整读写优先级,根据实际需求确保重要操作更优先

  启用延迟插入改善大批量写入性能

  尽量顺序操作让insert数据都写入到尾部,减少阻塞

  分解大的操作,降低单个操作的阻塞时间

  降低并发数,某些高并发场景通过应用来进行排队机制

  对于相对静态的数据,充分利用Query Cache可以极大的提高访问效率

  MyISAM的Count只有在全表扫描的时候特别高效,带有其他条件的count都需要进行实际的数据访问

 InnoDB

  1、特性

  具有较好的事务支持:支持4个事务隔离级别,支持多版本读

  行级锁定:通过索引实现,全表扫描仍然会是表锁,注意间隙锁的影响

  读写阻塞与事务隔离级别相关

  具有非常高效的缓存特性:能缓存索引,也能缓存数据

  整个表和主键以Cluster方式存储,组成一颗平衡树

  所有Secondary Index都会保存主键信息

  2、适用场景

  需要事务支持(具有较好的事务特性)

  行级锁定对高并发有很好的适应能力,但需要确保查询是通过索引完成

  数据更新较为频繁的场景

  数据一致性要求较高

  硬件设备内存较大,可以利用InnoDB较好的缓存能力来提高内存利用率,尽可能减少磁盘 IO

  3、最佳实践

  主键尽可能小,避免给Secondary index带来过大的空间负担

  避免全表扫描,因为会使用表锁

  尽可能缓存所有的索引和数据,提高响应速度

  在大批量小插入的时候,尽量自己控制事务而不要使用autocommit自动提交

  合理设置innodb_flush_log_at_trx_commit参数值,不要过度追求安全性

  避免主键更新,因为这会带来大量的数据移动

  NDBCluster

  1、特性

  分布式:分布式存储引擎,可以由多个NDBCluster存储引擎组成集群分别存放整体数据的一部分

  支持事务:和Innodb一样,支持事务

  可与mysqld不在一台主机:可以和mysqld分开存在于独立的主机上,然后通过网络和mysqld通信交互

  内存需求量巨大:新版本索引以及被索引的数据必须存放在内存中,老版本所有数据和索引必须存在与内存中

  2、适用场景

  具有非常高的并发需求

  对单个请求的响应并不是非常的critical

  查询简单,过滤条件较为固定,每次请求数据量较少,又不希望自己进行水平Sharding

  3、最佳实践

  尽可能让查询简单,避免数据的跨节点传输

  尽可能满足SQL节点的计算性能,大一点的集群SQL节点会明显多余Data节点

  在各节点之间尽可能使用万兆网络环境互联,以减少数据在网络层传输过程中的延时

  注:以上三个存储引擎是目前相对主流的存储引擎,还有其他类似如:Memory,Merge,CSV,Archive等存储引擎的使用场景都相对较少,这里就不一一分析了,如果有朋友感兴趣,后面再补充吧。

posted @ 2012-05-09 10:04 顺其自然EVO 阅读(1468) | 评论 (0)编辑 收藏

如何在15分钟内掌握JavaScript面向对象编程

     摘要: 导读:经常看到一些JavaScript的代码脏乱得无法理解,到处都是属性和方法,或者一个循环套着一个循环。但如果使用面向对象就能很好的理清代码,并方便理解和修改代码。如果你不希望自己的代码只有上帝理解的话,就请尽量考虑使用面向对象的模式。  译文正文:  到处都是属性、方法,代码极其难懂,天哪,我的程序员,你究竟在做什么?仔细看看这篇指南,让我们一起写出优雅的面向对象的JavaScript代码吧!...  阅读全文

posted @ 2012-05-09 10:02 顺其自然EVO 阅读(781) | 评论 (2)编辑 收藏

什么让验收测试的签收时间不断推迟?

  做项目的时候,我们都有很好的计划,也在不断的强化风险承受力等等~~~ 但事实上,Devolpment完了,到了test和UAT的时候了,通常时间处于这个阶段的时间都比计划安排或者领导认为需要的时间要长的多。程序员一次又一次的收到bug report 和new changes。这里面new changes 当然是新添加的修改了,可以要客户再算钱的,bug就不是了。优秀的程序员团队的code中一般的range异常阿,null异常阿,分支阿,算法阿等等真正的技术bug是很少的。最常见的,也最难修改的是logic error和实现情况与真正需求不一致。

  最让整个团队懊恼的就是实现和真正需求不一致的情况,程序员抱怨:需求文档明明就是这么写的,我这么做是对的。需求分析人员则抱怨更多,我明明是这么写的,怎么他们做成了那个样子啊?客户当初就是这么说的啊,怎么现在到测试了,他们说不是这个意思啊,都快变的面目全非了?.......

  总结一下个人对于实现与需求不一致现象出现的原因:

  1、需求文档表述不明确,这个包含2个意思,一是需求条款含义模糊;二是需求信息不全面。这导致分析人员与设计人员理解出现较大偏差。而且,一般公司如果有专业的分析人员和职位,他们做完一个项目的分析后可能马上就接收下一个项目的需求了,这导致在开发中间需要需求再讨论和澄清的时候,分析员可能自己都不能完全确定需求或者表示错误了。

  2、需求挖掘不深,记录的未能表达客户真正需要的。这通常表现为将产品拿到客户那里测试时,客户没看完几眼,就说:这个***怎么是这样的? 这个报表要加*** ........

  3、分析人员未能引导客户那边决策人员与实际操作人员的需求统一。这表现为时常的,我们按照客户项目负责人的表述完成了需求分析。最后UAT的时候几乎都是由实际的操作人员参入的,于是很多操作人员开始7嘴8舌的表述自己的要求 。客户的项目负责人在这时候表现出极高的尊重下属意见的素质:这个是他们用的,当然他们都说是那样,当然要改成那个样子了,不然我买来干嘛~~~~ 云云

  4、不断的发现问题和小修小改,导致最后如果要查询一个部分的最终详细需求,可能需要参考n个相关文档.人之常情,即使假设所有人都知道这些文档并能获得,那也不如去找一个人问,所以问下 程序经理/分析人员/项目经理,而对被改动过的需求,他们(被问者)是否都对修改了然于胸呢?就算他/她很明确,他/她的表述力如何?

  出现test和UAT不断延期的状况后影响是极大的,几乎你见到的每个人都在抱怨.领导开始不满,怎么拖了这么久阿,原计划将人马投入下一个项目的计划不得不变更了.项目成本不断增加,而项目的总订单额倒不一定增加了多少.程序员开始在bug-fix的过程中情绪低落,因为项目拖的久了,修改的东西有没有新意,而且对所有人都一样的会催化情绪的是,要做的(实现的)变来变去.分析人员面对着压力,但很多人会把责任推到程序员和客户.项目经理最为倍受煎熬.一个现象也可能出现了: 加班,加班,再加班.....

  那么我们应该怎样来减少这种事件的概率呢?这里列举1,2所想:

  1、需求表述一定要保留文字描述,不要以为使用了OOA和UML后就不写描述性需求了。

  2、需求表述每项尽量简短明确,意思单一,进出唯一。

  3、分析人员要保管好未整理前的需求调研材料。

  4、分析人员对需求的理解尽量要达到与分析人员每一项都一样,可以采用讲解,复述,确认等手段。

  5、分析人员最好能在详细设计文档初步完成后和设计人员一起讨论确认详细设计。

  6、保持纪录和维护需求文档.这一点非常重要。

posted @ 2012-05-09 09:52 顺其自然EVO 阅读(191) | 评论 (0)编辑 收藏

LR 细节解析,为什么LR脚本会去访问“脚本中不存在的“资源?

  结论

  到这里结论其实也就出来了。(结论只针对HTML-Based Mode录制方式)

  HTML页面中的资源,如页面里写的<img>(跟是不是在表格中无关...),是不会显示在脚本中的。

  而外部链接中的资源,如<link type="text/css>连接的CSS文件中使用的图片,是会通过EXTRARES属性显示在脚本中的。

  运行上面这个脚本,Replay Log中会显示:

Action3.c(8): Downloading resource http://search.thunisoft.com/skins/default/images/bg_top.gif (specified by argument number 9)     [MsgId: MMSG-26577] 
Action3.c(8): Downloading resource http://search.thunisoft.com/skins/default/images/nav_bg.gif (specified by argument number 11)     [MsgId: MMSG-26577]
Action3.c(8): Downloading resource http://search.thunisoft.com/skins/default/images/nav_right.jpg (specified by argument number 13)     [MsgId: MMSG-26577]
Action3.c(8): Downloading resource http://search.thunisoft.com/skins/default/images/search_m.gif (specified by argument number 15)     [MsgId: MMSG-26577]
Action3.c(8): Downloading resource http://search.thunisoft.com/skins/default/images/button02.gif (specified by argument number 17)     [MsgId: MMSG-26577]
Action3.c(8): Downloading resource http://search.thunisoft.com/skins/default/images/nav_r.gif (specified by argument number 19)     [MsgId: MMSG-26577]
Action3.c(8): Downloading resource http://search.thunisoft.com/skins/default/images/button01.gif (specified by argument number 21)     [MsgId: MMSG-26577]
Action3.c(8): Downloading resource http://search.thunisoft.com/skins/default/images/nav_l.gif (specified by argument number 23)     [MsgId: MMSG-26577]
Action3.c(8): Downloading resource http://search.thunisoft.com/skins/default/images/search_l.gif (specified by argument number 25)     [MsgId: MMSG-26577]
Action3.c(8): Downloading resource http://search.thunisoft.com/skins/default/images/search_r.gif (specified by argument number 27)     [MsgId: MMSG-26577]

  细心的人可以发现,这个日志和第一步实验中的不一样呢。再次对比上面写出的两种Replay Log,可以发现一个是"Found resource ... in HTML ...",一个是"Downloading resource ..."(标记蓝色两处)

  这样也可以解释了。

  HTML文件内部的资源,不需要显示在脚本中就可以下载,因为会在访问这个页面时“发现”。

  而外部链接的资源,必须在脚本中显式写出,才会去“下载”。

  所以EXTRARES属性下面的资源,只要注释掉相应的脚本,就可以避免该请求。

  而HTML页面文件中的资源,则只能通过修改MODE="HTTP"属性,或者改为URL-Based Mode录制方式,才能避免请求。

  说到这,基本都清楚了,最后再翻一下官方文档(Function Reference)吧。

web_url

EXTRARES:
A demarcation parameter indicating that the next parameter will be a list of resource attributes.

List of Resource Attributes:
A list of resources generated by non–HTML mechanisms in the Web page. These include the resources requested by Javascript, ActiveX, Java applets and Flash. VuGen's Recording Options allow these elements either to be recorded within the current script step (the default mode) or recorded as separate steps (see "Recording in HTML–Based Mode" in the VuGen Online Book).

  再次验证了我们的结论,EXTRARES中只显示非HTML文件中的资源。

  问题描述

  同事遇到的一个问题,LR执行性能测试脚本时,总报出错误,无法访问一个图片的地址,但脚本中明明没有对该资源的请求。

Action4.c(12): Warning -27796: Failed to connect to server "10.11.204.35:80": [10060] Connection timed out      [MsgId: MWAR-27796]Action4.c(12): Warning -26000: Empty or no response for URL=http://10.11.204.35/iwebfiles/yqlj/26/107/10/4/361.gif      [MsgId: MWAR-26000]

  我查了一下,确实脚本中看不出问题,所有不相干的请求都删掉了,页面的请求中EXTRARES属性中的资源列表也都删掉了,只保留了主页面的请求。但只要一执行,就会去访问那个无法连接的资源。

  分析与实验

  查看了该页面的源文件,确实可以看到那个有问题的图片链接,是写在一个表格里的。于是很自然的猜测,是不是表格中的资源,录制不到脚本中、但是又访问了呢?

  这种问题,其实确信只要把录制方式转换为URL-Based Mode就肯定能解决,因为可以显式的录下所有请求。但还是想把HTML-Based Mode下的问题解决,于是做了一些测试。

  模拟那个问题页面,创建测试用页面。特意写了两个图片资源做对比,一个普通的图片,一个是放置在表格中的图片超链接,测试访问这个页面录制的脚本。

<html> 
    <head>
        <meta http-equiv="content-type" content="text/html;charset=gb2312">
        <title>测试页面</title>
    </head>
 
    <body>
        <p>
        普通的图片
        <img src=http://172.16.1.3/bbs/attachments/month_1110/20111008_3f1828e9b28294cb7f23Wu3TykOUV9RM.jpg width="126" height="45" border="0"/>
        </p>
        <p>
            <table border=2>
            <tr>
                <td>
                表格中的图片跳转链接
                </td>
            </tr>
            <tr> 
                <td>
                <a href=http://172.16.1.3/bbs/viewthread.php?tid=44597&extra=page%3D1###zoom target="_blank"><img src=http://172.16.1.3/bbs/attachments/month_1110/20111008_67cebe2ca85b66fe580cGUGESOM05AWo.jpg width="126" height="45" border="0"/></a>
                </td>
          </tr>
            </table>
        </p>
    </body>
</html>

  创建如上的HTML,放到TOMCAT的ROOT目录中,则可以通过tomcat访问该页面。

  测试:

  1、默认的HTML-Based Mode方式进行录制,只录到一个请求。

web_url("test_mode.html", 
        "URL=http://172.16.6.17:8080/test_mode.html",
        "Resource=0",
        "RecContentType=text/html",
        "Referer=",
        "Snapshot=t12.inf",
        "Mode=HTML",
        LAST);

  脚本中看不到对资源的请求,但实际运行时,还是会去获取两个图片资源。通过Replay Log可以看到请求的证据:

Action_HTML.c(7):Found resourcehttp://172.16.1.3/bbs/attachments/month_1110/20111008_3f1828e9b28294cb7f23Wu3TykOUV9RM.jpg in HTML http://172.16.6.17:8080/test_mode.html     [MsgId: MMSG-26659]
Action_HTML.c(7): Found resource http://172.16.1.3/bbs/attachments/month_1110/20111008_67cebe2ca85b66fe580cGUGESOM05AWo.jpg in HTML http://172.16.6.17:8080/test_mode.html     [MsgId: MMSG-26659]

 2、URL-Based Mode录制方式,可以录制到所有的请求,包括一个页面请求,两个图片请求。

web_url("test_mode.html",  
        "URL=http://172.16.6.17:8080/test_mode.html", 
        "Resource=0", 
        "RecContentType=text/html", 
        "Referer=", 
        "Snapshot=t13.inf", 
        "Mode=HTTP", 
        LAST);

    web_concurrent_start(NULL);

    web_url("20111008_3f1828e9b28294cb7f23Wu3TykOUV9RM.jpg", 
        "URL=http://172.16.1.3/bbs/attachments/month_1110/20111008_3f1828e9b28294cb7f23Wu3TykOUV9RM.jpg", 
        "Resource=1", 
        "RecContentType=image/jpeg", 
        "Referer=http://172.16.6.17:8080/test_mode.html", 
        "Snapshot=t14.inf", 
        LAST);

    web_url("20111008_67cebe2ca85b66fe580cGUGESOM05AWo.jpg", 
        "URL=http://172.16.1.3/bbs/attachments/month_1110/20111008_67cebe2ca85b66fe580cGUGESOM05AWo.jpg", 
        "Resource=1", 
        "RecContentType=image/jpeg", 
        "Referer=http://172.16.6.17:8080/test_mode.html", 
        "Snapshot=t15.inf", 
        LAST);

    web_concurrent_end(NULL);

  对比两种录制方式可以发现,对主页面的请求,两个脚本的唯一差别就在Mode属性为"HTML"还是"HTTP"(代码中标记黄色处)。通过修改测试1(HTML-Based Mode),可以很容易的获得以下信息:

  如果MODE="HTML",那么访问页面的请求,会自动去请求页面上的资源。

  如果MODE="HTTP",那么会只请求这个页面的HTML文件。

  但熟悉LR的人又肯定记得,在默认的HTML-Based Mode录制模式下,web_url脚本中应该会记录所请求的资源文件啊?在EXTRARES属性后经常会看到"Url=/image/test.jpg"这样的语句,那为什么出现问题的那个页面,和我们的测试页面录下来的脚本确实没记录资源文件呢?

  要查明这点很容易,只要随便找一个网站录制一下,去看看脚本中记录的资源文件有什么特点就知道了。

  用我们公司的搜索平台做一下实验,录制主页面如下。果然得到了我们期望的EXTRARES属性,下面列出了很多资源文件。

web_url("search.thunisoft.com",  
        "URL=http://search.thunisoft.com/", 
        "Resource=0", 
        "RecContentType=text/html", 
        "Referer=", 
        "Snapshot=t16.inf", 
        "Mode=HTML", 
        EXTRARES, 
        "Url=/skins/default/images/bg_top.gif", ENDITEM, 
        "Url=/skins/default/images/nav_bg.gif", ENDITEM, 
        "Url=/skins/default/images/nav_right.jpg", ENDITEM, 
        "Url=/skins/default/images/search_m.gif", ENDITEM, 
        "Url=/skins/default/images/button02.gif", ENDITEM, 
        "Url=/skins/default/images/nav_r.gif", ENDITEM, 
        "Url=/skins/default/images/button01.gif", ENDITEM, 
        "Url=/skins/default/images/nav_l.gif", ENDITEM, 
        "Url=/skins/default/images/search_l.gif", ENDITEM, 
        "Url=/skins/default/images/search_r.gif", ENDITEM,
        LAST);

  分析一下页面的源文件,搜索脚本中出现的各个图片名,居然发现一个都找不到!而源文件中出现的图片文件,在脚本中又都没记录。

  那么继续寻找脚本中图片的来源吧。其实到这应该很自然的想到了CSS文件了吧,于是随着源文件中的<link>找到连接文件,果然EXTRARES中的所有资源文件都找到了。

posted @ 2012-05-09 09:48 顺其自然EVO 阅读(524) | 评论 (0)编辑 收藏

说说软件的质量控制

 引用:

  软件质量得控制牵涉到很多变量。关键是在每个步骤都需要管理和控制。需要规范化整个软件开发过程。

  1、需求得时候做需求评审。但是怎样引导客户来提出确切得需求,就需要很好得沟通技巧,在客户需求了解得前提下,针对开发项目所做得技术需求,应该进行评审。

  2、概要设计时体系结构的评审、多次讨论。并保证足够的时间和精力来充分讨论所做的概要设计是否真正满足需求。不能以进度太紧等借口将概要做的马马乎乎,直接开始代码编写。(这也是以前做项目时最常犯的毛病。)项目经理必须有胆量有信心顶住老板的压力,很多BOSS衡量进度就会问,你编了几行代码了?怎么还在这里什么都没做?

  3、详细设计尽可能统一、规范。编码时要有统一的编码规则。命名规则等约束。即使天才程序员也应遵循适当的规范。否则大家以后在维护天才的代码的同时,肯定会在心里大骂。

  4、测试要在需求和设计阶段就开始,不能等到编码结束再进行。再编码过程中的单元测试应得到重视,程序员之间的交换测试可以取得一定的效果。发现问题越早,麻烦越少。

  5、对重要的功能实现代码做CODEREVIEW。为避免流于形式,在会前要充分协调,作好准备。

  6、版本控制。需求变动控制。适当地使用工具进行版本和需求变更的控制。避免后期版本混乱,做无用功。

  7、当然还有文档,要做就做规范,做踏实。应付检查和交差的文档不做也罢,浪费时间而已。文档太难控制的话,在编码时作好注释也可作为一种方法。

  而现实中是:

  1、产品中没有白盒测试的概念,从最底层代码开始,经过多年的修改,已经是千疮百孔。具体一个函数有多少隐含的问题要进行测试、统计一下。

  2、代码不进行重构,公司领导不重视重构,导致代码腐烂很严重。很简单的事实,一个配置变量在多处进行维护着 ,一旦进行修改,就要去修改很多处。再加上模块充斥着几千行的类和几千行的文件。最大的一个类triadapter达到了16258行,welldatamanager 17055行,类使用起来倒是很方便,要数据相关的东西,你只要找welldatamanager就好了,然后你就在几万行的代码中徘徊吧。其他的代码重复、过度依赖等等问题就更多了。

  3、黑盒测试力度不够。七八个人编码,两个人进行测试。并且随着时间长了,固定的两个人对软件产生了习惯性,导致很多地方测试不到。

  4、没有规范的软件开发流程。软件设计、测试用例编写

  5、测试时间不足,软件发布前一周还在进行软件功能的开发。

  6、需求不稳定。需求反复修改带来的问题。比如绘制刻度的时候,现实垂直画、后来水平画、再后来还是垂直画

posted @ 2012-05-09 09:31 顺其自然EVO 阅读(169) | 评论 (0)编辑 收藏

把你的软件测试用例当作一幅画

  Kevin Fjelsted是一个盲人,他曾写了一篇文章《A Brief History of the Accessibility of Computers by Blind People》,收录在《Amplifying Your Effectiveness》一书中。文中从一个盲人的视角描述了几十年来计算机的演进和变化。

  我对Kevin所描述的一个小细节很感兴趣:由于看不见,Kevin经常听别人为他描述一些图画或者画面。他发现,绝大部分人描述一幅画的时候,实际上是在描述一些画的特征,比如“画里有三个人”、“这是一副关于房子的画”。人们很少会描述画的细节部分,这就为听者留下了广泛的思考和遐想空间。

  当你用文字表述一件事情或一个事务的时候,不论你用多少文字、多么精雕细琢,当让接收者亲自去体验这件事情的时候,比如亲自用眼睛看这幅画、或者亲自动手去实验一下,接收者总是会有新的感受、会发现一些文字之外的东西。这就是一副图画可能胜过万语千言的道理了。

  对照我们的测试,写作测试用例的时候,不就是试图用文字向测试执行人员传达测试设计人员的想法吗?从传递者的角度,也许你期望不同的执行人员拿到这个用例,其执行结果都是一样的,希望测试效果受测试执行人员经验的影响降到最低,因此你试图准确而详细地描述每一个步骤。然而你的测试用例是不可能写得事无巨细的,因为不会有那么多的时间允许你这么做(假如你真的有这么多的时间,我倒建议你多做做探索性测试、多想想更有价值的测试内容);另外一方面,即使真的给你这么多时间写详尽的测试用例,你仍然无法保证囊括每一个与之相关的细节。从接收者的角度,优秀的测试执行人员阅读测试用例,就要像欣赏一幅画一 样,不仅仅靠听--这样只能接到别人描述的表面特征,更重要的是靠看--用你的眼睛去观察,去想一想设计人员是怎么想的?设计这个用例的目的是什么?为什么要这样设计用例?我怎样测试才能保证最优的测试效果?和用例相关的部分哪些也值得我关注?哪些是我所知道的重要信息但用例却没有提到?我应该以怎样的顺序执行这些用例为佳?我以大概怎样的进度执行这些用例比较合适?最重要的是靠动手--用你的心去思考,当你拿到一份待执行的用例,如果上述问题,你通过审视用例,就基本了然于胸,那很好。如果不是这样,比如你对被测特性还不大了解,也没有关系,你可以在执行用例的过程中进一步思考这些问题,通过动手操作,你得到了被测对象的一些最真实的反馈,你对测试用例有了更深刻的认识,你也在随时调整着自己的测试策略。

  所以,传统的脚本化测试(Scripted Testing)方法,即先花一段时间设计测试用例、再依据用例去执行的测试方法,不仅仅对测试设计人员有很高的要求(这里体现了大量的创造性的劳动),同时对测试执行人员也提出了相当高的要求:你得通过测试用例尽可能准确猜测出测试设计人员的心思,还得高于测试设计人员,找到测试用例文字以外的被忽略的但同时也是很重要的信息 --除非你不想得到更好的测试效果。所以测试执行也是体现了大量的创造性思维的劳动。记得昨日在某一ISTQB-FL课程研讨会上,某位讲师讲到了一页胶片,胶片上赫然把测试执行等之后的环节归为“机械式的活动”,而把之前的一系列测试设计活动归为“创造性活动”,如果你的测试执行都是工具在自动化的做,也许这样分类是说得通的吧。

  很多组织都过分地看重测试用例,认为测试用例是测试人员最核心的资产,让最优秀的人专职设计测试用例(他们从不或很少做测试执行了),花大量的时间去创建并维护这些用例,这些前端的活动投入非常大。而在最后一段路程,投入反而不那么大了:请一些缺乏经验的测试人员或者干脆雇佣一些对特性不熟的外包人员,依据用例做测试执行即可。当版本发布,用户反馈一些问题后,开始分析这些问题为什么会漏测,准确地说,应该是分析为什么会漏测试设计,因为鲜有人关注测试执行环节能力的提升。人们开始在测试设计阶段运用更多、更复杂的测试设计方法,开始添加更冗长的测试设计流程,开始采用更为详细要求的测试设计模板。。。

  我时常听到来自测试设计人员的求助,希望我告诉他们“如何才能提升测试用例的有效性?”“如何确保我设计的用例漏测率最低?” 在他们心中,很有责任感地认为:测试漏测,首先是我没有设计好的缘故。我常常会告诉这些测试设计人员:单单依靠测试用例没有必要也不可能发现大部分的bug,很多bug要依赖执行人员在测试执行阶段发现,这是正常的测试现象--你不可能要求盲人通过听得来的对一副画的理解和一个正常人通过看对一副画的理解一致;我不建议测试设计人员长期不做测试执行,不建议测试设计和测试执行的分离,如果你的组织还没有办法做到这一点,请你--测试设计人员--一定要时常和测试执行人员沟通,向他请教对你的用例的看法,实时收到反馈信息,调整你的设计;过分重视测试设计而忽视测试执行,就如同“行百里者半九十”一样,最终的测试效果很可能会输在“测试的最后一公里”上。

  探索性测试也许就是看中了人在测试中发挥的作用要大于文档在测试中发挥的作用这一点吧。

posted @ 2012-05-09 09:29 顺其自然EVO 阅读(199) | 评论 (0)编辑 收藏

如何让软件测试更理性?

  一、前二天在写一份PPT,看到波普尔哲学:

  卡尔.波普尔的哲学:科学理论和人类所掌握到的一切知识,都不过是推测和假想,人在解决问题的过程中不可避免地掺入了想象力和创造性,人们只能依靠仅有的数据来证明一条科学理论。这一“可错性”原则所推演出的“真伪不对称性”(真不能被证明,只有伪可以被证明)。

  二、软件测试是一份非理性的职业

  1、软件测试能证明软件存在Bug,不能证明软件不存在Bug。

  2、软件测试无止境,但测试周期有严格限制。

  3、软件质量是一步一步积累、提高的。

  4、《软件测试的艺术》,虽然当前还是很苦逼的职业。

  三、举例个人经历过的3个不同行业的故障

  ● 故障:

  1、2008年,同一个版本,上海、成都同时割接(通信行业专有说法)新版本,成都用户投诉,手机不能访问网站,上海正常。

  2、2011年,新版本(金融行业)上线后,4个用户扣款失败。

  3、2012年,版本(团购)发布后商品价格设置为19.9,显示变成18.89。

  ● 原因:

  1、成都的无线信号比上海的差,网络大量重发包,导致句柄耗尽。

  2、新版本部署过程中,有4个正在扣款的任务;部署完成后,补偿处理扣款任务失败。接口有一个备注参数调整(英文->中文),支付方校验前后参数不一致,扣款失败。

  3、19.9–>18.99,Java的浮点计算精度丢失。

  ● 总结:特定环境、特定用户、特定场景下发生的bug,测试人束手无策。

  四、如何让测试更理性

  ● 系统实现透明–>代码质量提高

  1、告别黑盒。

  2、学习代码、框架,理解实现(一个月)。

  3、code review开发代码(长期)。

  4、充分了解与外部的交付细节。

  5、促进代码质量(长期)

  ● 测试设计更全面–>自动化持续积累

  1、拥有:测试理论 + 业务知识 + 系统实现。

  2、用最少的用例达到业务覆盖。

  3、用最多的思考,追求场景的丰富。

  4、长期积累,如果实现自动化更佳。

  五、做到什么程度才理性

  1、本身就是一个非理性的职业,没有答案。

  2、测试覆盖率要多少?缺陷密度要多少?转测试标准要如何?code review要多少?自动化率要多少?探索性测试多少?没有答案。

  3、根据公司、产品、团队情况,做到当前的理性就可以,慢慢积累向更理性努力。

  4、不过,如果一个人坚持理性主义,那么他本身就是有非理性主义因素的。

posted @ 2012-05-09 09:28 顺其自然EVO 阅读(176) | 评论 (0)编辑 收藏

软件测试自动化

  最近公司在搞大规模弄自动化测试,所以今天想来谈谈测试自动化这个问题,当然我说的“测试自动化”跟“自动化测试”是不同概念,一样的字,不同的顺序。

  所谓的“自动化测试”,一般是说用一些工具来帮助测试,比如LoadRunner可以帮忙测试负载,QTP可以帮忙做功能测试,当然很多公司还自己写一些脚本做单元测试。这些工具的帮忙,可以极大地提高公司的测试效率,从而可以解放很多资源去做更加复杂、高级的测试。(所以“自动化测试”只是一个工具或者技术)

  而所谓的“测试自动化”,主要是说我们的测试流程,应该怎样来充分地结合各种工具/系统(测试管理工具、自动化测试工具等等工具/系统),使得这个测试流程更加合理、更加高效。前面说的LoadRunner这类“自动化测试”工具对于“测试自动化”而言只是一个帮助因素。(所以“测试自动化”是一个方向,一个理论,一门科学研究)

  在像LoadRunner这类工具出现之前,其实我们对于“测试自动化”的理论早已存在,出现的原因是由于软件发展速度太快,带来了越来越多光靠人力难解决的问题,比如:

  1、性能问题:很多软件都是很多人一起使用的,比如股票系统,可能会几百万、几千万人在用,但是股票系统开发公司不可能用人力来模拟这么多人一起使用

  2、功能问题:软件功能和逻辑是越来越多、越来越复杂,但是有不少旧的逻辑其实一直没怎么变,比如新建项目,备份项目等操作,但是这些虽然不变化,但是在每个Release时,总是需要测试的,这样子,就需要人力和时间了

  3、变更问题:很多功能虽然表面上看起来样子没啥变化,但是其实内在逻辑什么都可能在不断变化,优化算法啊,修Bug,都可能带来改变,怎么去保证能Catch到每次改变呢?这个是问题。

  4、……

  就这样子,大家为了解决这种问题,推出了各种各样的工具,而且也解决地很不错,不过其实很多公司还是继续存在着问题,什么原因呢?过度地认为工具能帮忙解决一切,整天叫嚣着工具代替人,而忽视了一个重要因素:人的思维。

  我们知道工具虽然很厉害,但是思维绝对无法超过人,工具里面的逻辑都是人编进去的,而人的思维确实无限的,如果工具真的解决一切,为啥这些工具还不断经常推出新版本,不正是说明还有很多事情工具做不到,需要人来帮忙去让它们实现吗?

  所以在“测试自动化”的理论体系中,人总是在“训练”工具,而不是在“使用”工具。

  在测试自动化现有理论体系中,主要由以下几部分组成:

  1、人

  2、自动化测试工具(LoadRunner,QTP,SeleniumTest Complete……)

  3、测试管理工具 (DevTest, TestDirector ……)

  关于“人”,我最后介绍了,先把2和3介绍一下,2其实已经介绍过了,对于3而言,虽然表面上可能没2厉害,但是其实起得作用可能比2还大,因为自动化测试工具只能测试产品的一个部分,而怎样能保证整个产品的所有部分都能被测好呢,这个就需要用到测试管理工具,比如TechExcel的DevTest,它的测试用例可以绑定自动化测试工具,而所有的测试用例就代表了一个完整的产品了,当这些测试用例去触发绑定的自动化测试工具运行后返回结果以后,相当于这个产品全部测完了。

  而最重要的“人”的作用呢?其实我不说,大家应该都能想出很多作用来,接下来我来总结一下:

  1、维护产品的完整性:需要根据功能的变化,Bug的发现、自动化测试工具的局限性,经常地更新测试用例、测试脚本。这个是最基本的。

  2、发挥人的能动性、发散性:自动化工具永远无法把一个产品测好,所以作为人而言,不要以为懂了自动化测试工具而骄傲,也不用因为只懂手工测试而感到沮丧,关键是要了解测试的内涵,从而就能了解产品的内涵,最后让产品在你的脑海中能融会贯通,这样子,你自己的脑袋就是无敌的自动化测试工具了。

  3、吸收+创新+创造:相信我,即使一个完美的产品的测试,如果真正意义上说完成了是永远无法做到的,更何况普通产品了。所以这也就意味着这里面会有大量的地方可以得到加强,吸收以往经验,发掘与加强遗漏点,追寻潜在点,创造新方法,都是一个“人”都能做到的,当然你需要大量地去思考、去探索。

  4、更新体系:我们说“测试自动化”是一个方向,是一个理论,是一个科学研究,这个就意味着它可以不断进步,至于进步到什么程度,我也无法想象,有可能会出现类似自动分析产品逻辑从而得到测试用例与脚本这样子,不过唯一能知道的是,人还是会占主导地位,无论更新到什么样子,人会一直带领着这个系统前进!

posted @ 2012-05-09 09:26 顺其自然EVO 阅读(185) | 评论 (0)编辑 收藏

6年软件测试总结

先讲个引子:

  上个工作部门:测试环境是测试工程师自己部署和维护;

  现在工作部门:测试环境是开发工程师部署和维护;

  刚开始的一个月非常不爽,偶尔服务异常(尼玛)、偶尔测试执行失败(诡异)、偶尔测试过程被中断(暴躁)、偶尔自动化执行失败(Fuck),强烈觉得这些情况打断我的测试思想、甚至测试的持续性,开始思考通过什么方式拿回测试环境的维护权。

  可以尼玛两个月过去之后,我放弃了。因为当服务异常、执行失败的时候,肯定开发在部署新版本,那我去刷刷微博、刷刷豆瓣。换句话说:我用测试工程师维护测试环境的时间刷微博去了,为什么不呢?不过增加了一个约定:开发部署环境的时候先通知,测试工程师同意才可以部署。

  结论:

  开发维护测试环境的优势:快速与准确。如果有问题的话,测试还是需要找开发解决,这是一种浪费。

  最终结论:PD、PM、Dev、Test,在产品研发过程中,大家都做自身角色最高效的工作,紧密合作。

  6年总结正文开始:

  思想 > 技术:

  技术实现你的思想,思想推动你的技术成长。如果技术视野不够开阔,将严重限制你的技术。

  技术更新太快,你不能保持技术的更新,但是思想可以,需要的时候你进行学习与实现。

  典型的反面教材:#鄙视链# 性能测试->自动化测试->手工测试。

  产品 > 质量:

  产品兴,测试兴;产品亡,测试亡。作为测试工程师,守护产品(架构、需求、方向),守护产品质量。

  如果产品提前上线一天,收入多100w,提前n天就是n*100w,作为测试工程师你什么测试策略?

  合作 > 争斗:

  如引子中所讲,不同的角色会有一些交互点的磨合,减少争斗,多多合作。

  亚马逊有个很好模式:先从客户的需求开始,然后再往后推,立项、申请资源、开发,大家都只做这个产品,直到产品下线,解散到下一个产品,没有资源共享的情况(甚至UXD也是独占式)。

  综合 > 精通:

  未来以产品划独立团队,未来开发自测质量越来越高,QA将转移至集成测试、性能测试、自动化、工具开发、也参与白盒测试。技术能力上和开发处于同一水平,只是开发代码熟练,QA测试熟练。

  我们有一个测试数据中心,用于造各种测试数据。由所有的测试同学开发和维护,完成自己所测试的系统的造数据功能,没有工具组。

  团队 > 个人:

  团队的短板,代表团队的水平。提高团队的整体水平,才是一个高水平的团队。

  自我方向调整:

  1、不再纠结测试技术、不再纠结测试流程、不再纠结个人,视角投向产品。

  2、关注测试技术动态、关注行业数据、关注团队成长、关注生活

  补充:

  1、旧:一周5天,2天在研究技术细节,1天开会,2天项目相关工作,周末没有生活安排。

  2、新:一周5天,0.5天关注技术动态,1.5天关注团队成员,1天开会,2天项目相关工作,周末生活安排。

posted @ 2012-05-07 09:54 顺其自然EVO 阅读(660) | 评论 (0)编辑 收藏

软件测试对质量负主要责任?

  你的公司,产品发布时,是否要求测试说出个“产品质量是XX的”论断,如果发到用户那里出了问题,就首先打测试的板子,老大都在问“测试为什么没有测试出来”,仿佛测试是最后一道关、是质量警察?测试应该对质量负主要的责任吗?

  我的观点:测试不对质量负主要责任,测试只起到质量辅助的作用;测试是一种服务,为其他角色提供服务,提供关于质量的信息。

  为了说清这个观点,有必要先讨论一下:什么是质量、什么叫做对质量负责、对谁负责、谁定义的质量。

   当然质量的定义有很多种,我比较赞赏Jerry Weinberg的定义”Quality is value to someone who matters“,测试最主要的目的就是要找到那些削弱产品价值(value)的点,将这些与产品质量相关的重要的信息提供给项目决策者,以便他们做出更 准确的决策。

  正如Michael Bolton所言,”Consider quality not as something simple, objective, and abstract, but as something messy, subjective and very human.“ 质量不是什么简单的事务,而是一个关乎产品、人、系统之间的复杂关系。

  为了提升质量或保证质量,需要有方方面面的考虑,是那些产品的管理者们真正有权利决定使用什么开发方法和流程、雇佣什么样的人员、采用什么样的质量目标、如何度量、花多大成本等等来确保产品的质量,而不是测试人员。

  作为测试人员,不要努力去影响别人做什么、怎么做,而是要聚焦于提供实时的、准确的有关产品的信息(问题和风险),以有助于别人做出更恰当的提升质量的决策。

  测试是一种服务,为项目其他角色提供服务。当然,每一个角色都是为其他角色提供服务的。开发人员为测试人员提供”软件可测试“的服务,使得软件更容易测试;测试人员帮助开发人员测试他们的代码,使用专业的测试技能和测试思维。

  测试人员、包括QA,都不应该将某种方法强加于开发人员,那是质量警察干的事。一是因为测试人员和QA都没有优势告诉开发如何开发质量更好的产品;二是因为当你强加某种东西给别人的时候,你获得的往往是假的数据。

  征得Michael Bolton的同意,转译了他的一篇博文:http://www.51testing.com/html/24/n-812424.html

  其实,“负责”是个很重的词。对质量负主要责任的人,得有一定的权力做各种质量有关的决定。测试是否有权力或能力做这些决定呢?

   质量本身是一系列活动的结果,当然最重要的是设计和编码,如果设计和编码都完全符合需求和用户期望,那也就不需要测试了。然而,我们的认知和智力都是有 限的,不可能那么完美,而且有时候用户都不知道自己的需求,还需要我们去引导(乔布斯理论),所以还是需要一个中立的或者第三方的组织来判断产品的实 现是否符合用户和我们最初的需求和期望,这就需要测试来给相关的利益关系者提供客观、准确的质量信息和评估了。

  测试活动本身不能带来产品质量的变化。测试就是一个信息提供方,精确反映出产品需求的实现和在哪种情况可能给客户带来的风险就是测试的职责,当做一个质量播报员,就像最近的牛奶风波一样,我们只要把牛奶中成分的真实情况反映出来,剩下的就由用户或制造者来做决定吧。

   质量是设计出来的,但设计者是人,也有考虑不足的,需要通过测试发现,发现后设计者进行改进,测试的职责是发现问题。设计和实现是有差距的,没有缺 陷的设计只是一个终极目标,只是一种理想,因此测试必须进行一种权衡,判断哪些缺陷是必须改进的,哪些是现在可以忽略的,这种决定不是仅由测试说了算的。 我不知道哪个团队的测试人员可以做这个决策?除非你比开发人员还懂业务、你比项目经理还了解风险、你比客户还了解需求?

  产品“零缺陷”只能是一个理想,即使排除时间和投入成本也是不可能达到的。但我们要把产品可能存在的潜在风险和失效条件找出来,发布与否这样的决定就不是测试说了算了,要看客户能否容忍这样的风险和失效,由决策者做成最终决定。

   当然,测试这把尺子,只能提供有关产品质量的“相对”的信息,不是“绝对”的信息。实际上,“XX产品的质量就是什么样子的“这个论断没有人能给得出。 如果你能准确无误地说出”XX产品的质量现在就是这样“, 很快就会发现一个反例的出现将打破你原来对它的认识–当然,你根本无法准确无误地说出质量的样子,那是一个无穷的集合,就像测试是一个永远测不完的活一 样。因此,测试提供的信息只是相对准确的,不是绝对准确的,这个局限性也正是测试所面临的挑战。

  不过,测试努力做到的是,用我们的专业技能和测试思维,尽可能学习了解真实的产品、发现别的角色意想不到的问题和风险,并报告给他们:”在XXX的 背景/上下文/场景下,XXX产品在XXX质量属性方面表现正常;在当前进行了XXX的测试后,目前XXX产品存在XXX的问题,如果XXX使用该产品, 会存在XXX的风险。“

  说“测试对质量负主要责任”这样的说法是错误的,不是代表测试就和质量没有关系,实际上测试非常关心质量,并且测试的工作对质量有很大的影响。但同时我们认为其他角色关心质量的程度一点也不 比我们小,或者不应该比我们小,大家共同对质量负责。但是像敏捷里的“完整团队”的说法,每个人都对质量负责、大家是个自组织团队的做法在现实中还是遇到 很多问题的,还是得有人做决策,做那些为了提升质量而采取什么动作的决策,这个决策者,首先得有权利做决策,才能控制了项 目,才能控制了质量,才能对质量负责。

  也许在很多公司,是项目管理者 有这样的权力吧。测试像一把尺子衡量产品质量后会给出测试知道的有关质量的信息,同时我们也很清楚,管理者那里还有很多测试不知道的、同样也很重要的、有 关质量的信息,管理者会基于所有信息作出最终的质量决策,可能是发布产品、可能是更改流程、可能是更改需求、可能是引入工具......管理者有做这些决 策的权利和能力,他们会想办法让所有角色关心质量,所以,不是测试对质量负主要责任,而是决策者要对他做的决定负责。

posted @ 2012-05-07 09:51 顺其自然EVO 阅读(228) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 329 330 331 332 333 334 335 336 337 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜