qileilove

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

接口验证模式

 摘要:接口验证是软件测试中一个重要的方面。本文按被测对象与周边实体的消息处理关系将接口验证方式抽象成几种模式:C模式、S模式、C&S模式、分发模式、异步模式等。然后按模式从接口契约定义、请求和响应配合等方面,给出接口验证的一般要求。

  关键词:接口验证 测试模式 协议一致性

  1、相关概念

  1.1 接口

   这里所说的接口主要是指的是消息接口,是二个部件之间的通信契约,有发送方、接收方等方面的属性,同GUI接口、文件接口一样,它本质上属于一种输入、 输出方式,只是它涉及到2个不同部件/实体,有请求/响应、有连接通道要求,由此带来超时、重发、重连等方面的一系列要求。

  1.2 接口、流程、处理的关系

  一个流程由一系列的处理、接口调用组成。

  一个流程可能涉及多个不同部件,涉及多个不同的接口调用。

  一个接口可能服务于多个流程,多个流程共用同一个接口。由此,接口验证里需要对同一个接口遍历不同的流程调用场景。

  接口作为数据的一种形式,它影响流程的走向。

  接口作为数据的一种形式,它影响流程的结果。

  有些接口处理可能是纯接口的、只做中转、协议转换等。例:下面例子中的E部件接口;有些接口处理可能有较强的功能逻辑,根据需要可能还会进一步细化成内部接口。由此,接口验证可能需要针对接口处理作进一步的功能逻辑验证。

  2、一个例子

  以下为某个处理的简化流程。P部件发出请求,E部件协议转换后转发给M部件,M部件进业务逻辑处理后返回响应给E部件。

  接口的测试设计思路:

  ● 列出与每个部件的交互点。 包括:与P 部件的交互点1.1~1.2;与E 部件的交互点2.1~2.4;与M部件的交互点3.1~3.2

  ● 对每个部件的每个交互点进行正常与异常方面的验证。

字体:        | 上一篇 下一篇 | 打印  | 我要投稿 

  3、接口验证模式

  3.1 基本模式

  ● C模式:被测对象作为客户端发送请求消息。一般来说,流程起点的接口(例子中的P部件接口)多数为C模式。

  基本验证要求:

  ◇ 发送请求消息正确性。包括:协议、消息格式、各参数验证。

  ◇ 响应消息字段、错误码遍历。确认根据对端不同响应作了相应的正确处理。比如:根据错误码展示

  正确的错误提示也为一种正确处理方式。

  进一步验证要求:

  ◇ 考虑接口请求和响应配合上的异常,包括:

  ——请求发送异常:发送失败、失败重发。

  ——响应接受异常:无响应、响应超时、超时重发、收到重复请求
● S 模式:被测对象作为服务端接收请求,一般来说,流程终点的接口(例子中的M 部件)多数为S模式。

  基本验证要求:

  ◇ 收到的请求消息参数合法性校验。包括:

  ——协议、消息格式的验证、非系统识别消息、存在非法字段、收到重复消息

  ——遍历各字段进行参数合法性校验:是否可选、唯一性、类型、取值范围、长度(<、=、>)等

  ◇ 遍历请求消息的各字段取值及组合,确认根据不同输入返回了不同的结果(可以等价)

  ◇ 发出响应消息正确性:协议、消息格式、各参数验证等。

  S&C 模式:被测对象既作为服务端接收请求又作为服务端发送请求。一般来说,流程中点(例子是的E 部件)多数为S&C 模式。

  如果将周边部件1 作为被测对象一部分,它即是C

  如果将周边部件2 作为被测对象一部分,它即是S

  基本验证要求:除了C 模式和S 模式的基本验证要求,考虑对不同消息间相关参数一性性进行校验。

  例:R1 接口中X 参数取值为1-255,经过转换后的R2 接口中相应的X 参数取值也应为1-255。

  进一步验证要求:参见C 模式和S 模式中的进一步验证要求。

  3.2 复合模式

  ● 异步模式:被测对象发出消息后,对端立即响应,对端在处理结束后再发送回执消息给部件,部件根据对端所给出的消息作出相应的处理,流程结束。一般来说,如果对端处理较为复杂、为避免被测对象长时间被阻塞,会采用此通信方式。

  对于异步模式,可以拆分为2 对消息,但这2 对消息是基于事务、有状态的。因此,对这类消息的验证除了基本模式C 和S 的验证要求外,还需要考虑2 对消息关系的配合对被测对象的状态影响验证。

  以图示为例,被测对象的验证内容包括:

  ◇ 对A 接口的验证。参见C 模式

  ◇ 对B 接口的验证。参见S 模式

  ◇ A 和B 接口的配合:

  条件:A 接口处理失败、未收到B 接口消息、B 接口处理失败、B 接口处理成功

  结果:被测对象的状态、数据

 ● 分发模式:需要将消息采用同步方式向其它多个部件进行分发,待消息收齐后才能决定自身的最终状态。例:被 测对象通过分发部件将数据同步分发给不同的部件。需要说明的是:图示中的分发部件,这时从物理上来说,可能看到的只是一个部件,由它统一接受和分发消息, 但从逻辑上来说,它是代表了不同部件的接口处理的。

  对于分发模式一般也是基于事务、有状态的,但由于涉及到了2 个以上的周边部件,还需要考虑对不同部件的接口消息处理结果进行结合。

  以图示为例,被测对象的验证内容一般包括:

  ◇ 对A 接口的验证。(参见C 模式)

  ◇ 对B 接口的验证。(参见C 模式)

  ◇ 对部件1 和部件2 处理结果结合验证:

  条件:1 成功2 成功;1 成功2 失败;1 失败2 成功;1 失败2 失败

  结果:被测对象的状态、数据

  ● 异步分发模式:即采用异步方式进行消息分发,为异步和分发模式的结合。比较 典型的是数据同步异步接口。被测对象 通过分发部件 同时将数据同步消息通知分发给不同的部件,各个不同部件收到通知后再向被测对象请求获取同步数据。如果通知有优先级,例:部件1> 部件2,待部件1 处理完再通知部件2,即为异步分发模式1。如果多个部件的分发并行执行(一般来说,部件1 和部件2 可能代表的是同类部件的不同物理实例),即为异步分发模式2。

对于异步分发模式,也即异步+分发模式的组合。此时被测对象涉及到2 种类型的消息配合:同一个部件的通知和回执的组合;不同部件间的消息处理结果的配合。由此,被测对象的状态迁移会更为复杂些。

  以图示为例,被测对象的验证内容包括:

  ◇ 对A 接口的验证。(参见C 模式)

  ◇ 对B 接口的验证。(参见S 模式)

  ◇ 对C 接口的验证。(参见C 模式)

  ◇ 对D 接口的验证。(参见D 模式)

  ◇ 对A 和B 接口的配合验证。(参见异步模式)

  ◇ 对C 和D 接口的配合验证。(参见异步模式)

  ◇ 对部件1 和部件2 处理结果组合验证。(参见分发模式)

  4、相关说明

  ● 参数合法性检验策略

  如果业务流程涉及多次转发,原则上由逻辑处理部件进行接口参数的强校验;其它转发部件(例:E部件)进行弱校验。

  消息序列验证

  如果不同的接口消息之间是基于事务、有状态的,则还需要考虑消息序列异常的问题,无论是何种模式。其验证点包括:消息乱序、少传消息包、多传消息包、传重复消息包、事务超时后收到消息等。

  接口可靠性保证

  ◇ 对于重发的验证,一般来说,重发机制中需要有重发策略、重发次数方面的考虑,不能出现消息反复重发引发消息风暴的问题。

  ◇ 对于超时的验证,需要考虑各部件超时配置不一致的问题。

  ◇ 对于处理失败造成双方数据不一致问题,需要有事务号、回滚或补偿机制等方面的设计考虑。

  ● 接口验证的不同阶段

  对于接口验证在单部件测试、点-点接口联调、E2E联合测试等不同阶段都有所涉及。一般来说:

  单部件测试:理论上通过测试桩可以模拟对端各种情况,对于真实实体只能通过系统状态预置、输入数据从外部触发。所以,能在单部件测试考虑的尽可能放到单部件去做,至少保证单部件自身是OK的。

  点-点接口联调:如果将2个部件看作一个整体的话,则相当于单部件测试。对于部件-部件间的接口无法通过测试桩来模拟,需要通过外部驱动输入。另外还需要关注部件-部件间的网络连接,包括:是否可正常建立连接、连接中断后是否会重连、连接吊死与释放、时断时续等。

  E2E联合测试:所有内部部件均为真实实体,对于接口间配合的问题(例:事务或数据一致性问题)可以考虑放到此考虑。除此还需要关注与外部部件间的接口对接测试。

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

对Oracle数据库性能优化技术的研究

大型关系数据库Oracle已经广泛应用于各行各业,如政府、交通、公安、电信、金融、能源等部门,并已逐渐成为企业信息化建设的重要数据库平台,但随着 Oracle 数据库规模的扩大,数据库用户人数的增加,数据库性能问题越来越突出,因此,有必要对 Oracle 数据库性能进行调整与优化, 使之在满足需求条件下,系统性能达到最佳和系统开销最小。

  1、性能优化目标

  1.1 缩短响应时间

  响应时间是指从用户提交SQL语句到数据库返回结果集的第一行数据所需要的时间,缩短响应时间可以通过减小系统服务时间或用户等待时间来实现,通过使用毫秒ms来表示,通过缩短响应时间,既能减少用户请求的处理时间,又能提高系统资源利用率。

  1.2 提高系统吞吐量

  数据库吞吐量指在单位时间内数据库所能完成的SQL 语句事务数量,吞吐量=事务量/时间,通常用TPS(每秒钟的事务量) 来表示,提高数据库的吞吐量可以在同样的时间内处理更多的请求,即在相同的资源环境内做更加多的工作

  1.3 提高数据库多个指标的命中率

  数据库指标包括数据库高速缓冲区命中率、库缓冲区命中率、软解析率等,其中,高速缓冲区命中率是最常用的指标, 高速缓冲区命中率=高速缓存命中总数/数据请求总数,通常使用高速缓冲区命中率来衡量Oracle数据库的性能。

  1.4 优化磁盘I/O

   Oracle 数据库将数据储存在磁盘和内存中,想要往Oracle中写入和读取数据基本上都会涉及到 I/O 操作,通过对磁盘合理的进行规划,利用高速缓存技术,可以提高系统吞吐量,缩短用户响应时间,尽可能有效地利用系统物理内存而尽量避免或推迟使用磁盘 I/O 操作。

  1.5 合理使用内存

  在大量并发用户数下,若Oracle 内存尺寸不够会降低程序的处理效率,延缓数据库的响应时间,内存是否合理使用,一般可以从使投资得到最大回报和使争用减到最小这两个指标来判断,通过合理使用内存,可以大大提高系统性能。

  1.6 减小磁盘排序

  当用户提交的 SQL 语句含有聚合函数或者有排序时,这些排序可能在内存中进行,也可能在物理磁盘上进行。由于物理磁盘自身结构的原因,其读写速度远远慢于内存读写,因此一个优化的原则是尽可能减少物理磁盘排序操作。

  2、影响Oracle性能的因素

  影响Oracle数据性能的因素有很多,比如:操作系统,CPU 性能,内存分配不合理,Oracle 配置,I/O 冲突,网络速度低以及SQL使用常见错误等等都会影响数据库的性能。

  1)操作系统:Oracle 数据库服务器很大程度上依赖于运行服务器的操作系统,操作系统配置不合理会直接降低Oracle性能;

   2)CPU占用过高:CPU 是服务器中一个重要的资源 ,CPU 资源被其它应用占用或被某个数据库事务占用,会导致其它数据库事务运行停滞,而使数据库响应迟钝,比如:空闲时,CPU占用率超过90%,则说明 Oracle服务器CPU资源不足,低效率的 SQL 语句、锁冲突、SQL 语句的重解析等原因都会引起 CPU 资源不足;

  3)I/O 冲突:由于磁盘在同一时刻只能满足一个进程的需要,当多个进程同时访问同一个磁盘时,会引起读写盘冲突,进而降低整个系统的速度;

  4)Oracle 配置:每一个 Oracle 实例都是由一组 Oracle 后台进程和系统全局区的一个内存区所组成的, 正确调整 Oracle 配置将会对系统性能产生重大的影响;

  5)内存分配不合理:内存分配不合理将会减少 Oracle 用于存放最近访问过的数据的缓冲区空间,并导致操作系统频繁进行页面或内存交换,从而导致计算机系统额外的 I/O 开销;

  6)网络速度低:网络的带宽会在一定程度上影响系统的整体性能,网络速度过低会增加网络 I/O 负荷量,从而降低数据库系统的吞吐量并延长用户响应时间;

  7)SQL使用常见错误:配置和数据迁移的错误,大量递归 SQL 语句的存在,长时间的全表扫描,一些数据库结构的设置不合理,重做日志文件的不合理设置,I/O 设备的不合理的规划,非标准参数的使用,执行效率很差的 SQL 语句,游标和共享池的错误使用,低效率的数据库连接。

3、性能优化优化与调整技术

  3.1 调整优化数据库

  1)最常见的调优方法是在数据库中增加索引,索引(index)是常见的数据库对象,充分利用索引来减少表扫描的 I/O 次数,使用索引可以避免不必要的大表全表扫描,索引设置的位置要视 where 子句中索引列所应用的查询条件而定,通过索引对表的数据进行检索比起直接全表扫描所引起的I/O操作要小得多,索引可增加查询速度;

  2)若某种业务的数据量增长非常快,可以使用分区表技术将数据进行分散,将不同表空间分布到不同的磁盘当中,使得硬盘之间 I/O 负载均衡,在一定程度上缓解了数据量过大引起的负面影响,并且会缩短查询时间;

  3)使用存储过程完成数据库中频繁执行的应用逻辑,使代码编程与数据库的操作分离,可以降低网络传输量,提高数据请求的执行效率,执行存储过程时,用户只需要发出执行命令,而不再进行SQL语句提交,节省了系统的SQL语法分析,充分利用了SQL共享池;

  4)使用Oracle优化器执行直接提交的查询SQL 语句,可以大大提高语句的执行效率;

  5)使用触发器自动执行的SQL语句,可以降低网络 I/O及系统资源的消耗,如需要对所有访问数据库的程序自动实施一定规则或检查,则使用触发器可以大大提高效率。

  3.2 调整优化内存

  Oracle的信息存储在内存和磁盘上,由于访问内存比访问磁盘快得多,在大量并发用户数下,如果Oracle 内存尺寸不够会降低程序的处理效率,延缓数据库的响应时间,提高数据库性能需要设置合适的内存尺寸,Oracle 内存包括系统全局区 (SGA)和程序全局区 (PGA)。

  3.2.1 调整SGA的大小

  根据数据库运行状况重新调整SGA的大小,对每个节点修改SGA大小的方法如下:

SQL>alter system set sga_target=200m scope =both sid=’RACDB1’;
SQL>alter system set sga_target=200m scope =both sid=’RACDB2’;

  3.2.2 提高共享池性能

  共享池主要是用来存放最近使用过的 SQL语句,共享池内存分配算法保证了数据字典数据比库缓冲区数据在内存停留时间更长,命中率更高,应优先调整库缓冲区。

  1)通过调整参数SHARED_POOL_SIZE的值,可以根据实际情况对每个节点共享池的大小进行调整;

  2)为了提高共享池命中率,可以使用代码重用方法;

  3)对于比较大的对象,如自定义的过程与包,在载入共享池以及硬解析的过程中需要共享池付出很大的代价, 把重要的大对象保持在内存中,可以大大提高共享池性能。

  3.2.3 优化数据缓冲区高速缓存性能

  为减少系统磁盘 I/O 开销,应调整数据缓冲区的尺寸,使服务器进程尽量在缓冲区中找到所需的数据,尽量减少等待数据块或空闲缓冲区的时间。

  1)加大Buffer Cache的大小

  可以通过调整DB_CACHE_SIZE参数的值增大Buffer Cache。

  2)使用多个缓冲池

  Keep池中数据倾向于一直保存,Recycle池中的数据倾向于即时老化,而Default池则存放未指定存储池的数据,通过使用多个缓冲池提高Buffer Cache的命中率。

3.2.4 尽量减少全表扫描

  通过索引的正确使用可以避免不必要的全表扫描,发生的全表扫描越少,Database Buffer Cache命中率将越高,但对于一些表比较小且需要表中的大多数数据时,这时使用全表扫描响应时间可能就会优于不使用全表扫描,通常,当该表的结果集和表 中记录总数的比值大于20%时,就应该要使用全表扫描。

  3.3 调整优化磁盘I/O

  1)经常使用的对象产生 I/O 争用的机会较多,应将访问量较大的数据文件放在独立磁盘上,同一个表空间的多个数据文件应尽可能地放在不同的磁盘上,为索引创建单独的表空间,并将表和索引分开在不同的表空间;

  2)在内存中修改过的数据不是直接写入数据文件,而是先写入重做日志文件中,重做日志文件要足够大,要与数据文件存放在不同的磁盘上,减少对磁盘的竞争,重做日志文件分为几个组,写满一组时切换至下一组,最后一组写完后再返回至第一组,按顺序循环写入;

  3)Oracle 的文件和操作系统的其他文件应尽可能地放在不同的磁盘上,这样可以减小 I/O争用的概率;

  4)最好使用目前较流行的廉价磁盘冗余阵列(raid),它能自动分离不同类型、访问频率的数据库文件,减小I/O进程之间的竞争,优化数据库性能;

  5)创建回滚段及其专用的表空间,回滚段是为了从系统操作的失败中得到数据的恢复,从而减小I/O进程之间的竞争,防止空间竞争影响事务的完成;

  6)单独创建用户数据表空间,且要与系统表空间(system)分开磁盘存放,创建临时表空间用于排序操作,尽可能防止数据库碎片存在于多个表空间中。

  3.4 SQL优化

  SQL 语句本身的执行效率直接影响Oracle 数据库执行效率,它消耗了数据库系统 70%~90%的资源,对SQL语句进行合理设计可以使其更高效地执行,以提高系统对资源的利用率,好的SQL语句可以加快执行速度,减少网络传输,从而 最大限度地发挥数据库的性能。

  1)尽量减少对数据库的查询次数,对几个表查询时 FROM 子句的顺序,按照由内及外的访问顺序应把可筛选出较少记录的表放在前面,执行时最先查找出这个表的几个记录,再和其他表的记录相连接;

  2)为了充分利用库缓冲区的 SQL 解析信息,对于经常运行条件子句变量值不同的 SQL 语句,应将这些变量改为统一的绑定变量;

  3)调整 SQL 的关键是使数据库寻找数据的路径最简化,限制动态SQL的使用,优化操作符,如in或not in,is null 或 is not null,like ,union 等操作符,应尽量少用;

  4)避免不带任何where条件的SQL语句的执行,使用order by、group by、union 等条件的 SQL 语句会对查询完的数据进行排序,增大了 PGA 或 TEMP 的负担,优化这些语句时可在使用这些条件的列上加上有序索引;

  5)对SQL 语句的索引进行优化,如:在索引列使用 is null 和 is not null,或进行了显式或隐式的运算时索引不被使用,采用函数处理的字段也不能利用索引等;

  6)避免相关子查询,查询嵌套层次越多,效率越低,为了加速查询速度,可以使用临时表;

  7)在系统不繁忙或在大量对象更改后定时或及时统计数据库信息,选择适当的方法进行优化,包括几种常用方法:基于代价的优化(CBO),基于规则的优化(RBO), 对于需要经常进行查询的表,可以通过建立索引或嵌入内存区以提高查询效率。

  4、数据库优化实验

  选取约为5Gbyte左右的信贷管理系统作为数据库优化实例,该数据库运行在HP ProLiant BL490c G7(603599-B21)服务器上,使用UNIX操作系统,优化结果如表1所示。

  从表1可以看出,数据库经过调整优化数据库、调整与优化内存、调整与优化I/O和SOL优化后,响应时间变得越来越短,系统性能得到逐步提高。

  5、结束语

  随着Oracle数据库规模的扩大,用户数量的增加,Oracle数据库性能问题越来越突出,Oracle 数据库的性能优化涉及的方面很广,优化与调整是一个需要通过不断摸索、总结的过程,在实践中,必须先了解影响数据库系统性能的因素,针对这些不同的因素选 择合理的优化调整策略予以调整,同时也需要采取更加先进的技术来对数据库进行调优,使得数据库系统获得最优性能。

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

Select—没你想的那么复杂

  Select语句的基本结构如下:

Select  [All | Distinct]  select_list
[Into [new_table-name]]
Form {table_name | view_name}
[,{table_name2 | view_name2}
….,{table_name10|view_name10}]
[Where search_conditions]
[Group By group_by_list]
[Having search_conditions]
[Order By order_list [ASC| DESC]]

  第一行语句中select_list表示需要检查的字段的列表,字段名称间用逗号分隔

  All 指明查询结果中可以显示值相同的列,且为系统默认 *

  Distinct 指明查询结果中如有值相同的列,则只显示其中的一列 唯一值

  第二行语句中Into子句用于把查询结果存放到一个新建的表中 as 。。。。

  new_table-name 指明新建表的名称

  第三行语句中Form 子句指定需要查询的表注:只要Select中又要查询的列就必须使用From子句

  table_name / view_name 指明Select 语句要用到的表,视图等数据源,该列表中的数据表名和视图名之间使用逗号分隔

  第四行语句中 Where子句是制定数据检索的条件,以限制返回的数据行

  第五行语句中Group By 子句指定查询结果的分组条件

  第六行语句中 Having 子句指定分组搜索条件,通常与Group By子句一起使用,它与Where语句类似只是其作用对象不同,Where子句作用于表和视图,Having子句作用于组。

  最后一行语句Order By 子句指定查询结果的排序方式,ASC是升序(系统默认),DESC 降序

  下面具体介绍一下Group By 子句

  ALL:表示返回所有可能的查询结果组合,即使此组合中没有任何满足Where子句的数据,分组的统计列如果不满足查询条件,则将由null值构成其数据

  Cube:除了返回由Group By子句指定的列外,还返回按组统计的行,返回的结果按分组的第一个条件列排序显示,以此类推。统计行包括了Group By子句指定的列的各种组合的数

  据统计

  Rollup:只返回第一个分组条件指定的列的统计行,改变列的顺序会使返回的结果发生变化

  举例:按所属部门分类,找出工资大于来2000的所有员工

  下面两个图即分别是为Cube的返回结果和Rollup的返回结果

  如何提高Select语句的效率

  1、使用exists关键字检查结果集:不要用count(*)来检查结果集中是否包含行

  2、使用标准连接代替嵌套查询:在执行嵌套查询时,SQL Server将执行内部的子查询,然后将查询结果返回给外部查询作为检索的数据源,最后执行外部的主查询。而在执行包含标准联接的查询时,SQL Server将要查询的仅仅是一个查询

  3、有效避免整表扫描:使用索引,除了缺失索引外,可能导致整表扫描的另一种情况是在like子句的匹配条件的开始使用了%,如果这样将会调用整表扫描。

posted @ 2012-07-17 10:32 顺其自然EVO 阅读(218) | 评论 (0)编辑 收藏

敏捷测试之实践篇

最近一直在想敏捷测试如何实施的事情,敏捷测试在敏捷开发中贯穿始末,涉及到了多种角色的参与:客户、开发、设计、专职测试等等,每个角色承担着不同的测试任务,客户与设计可以进行验证需求实现的测试,而开发进行单元测试,专职测试人员进行详细测试。

  我们这里主要是来谈谈专职测试人员如何开展敏捷测试,其实这个问题也是很多软件公司在研究的问题,我们公司也在摸索之中,今天就来介绍一下目前的一些情况。

  首先介绍我们公司的情况,我们自己开发产品,大致主要有二条产品线,一条用敏捷方式,另外一条还是用传统的瀑布方式,今天当然是介绍敏捷那条产品线。

  在敏捷中,测试是从头到尾一直参与的,而对于专职测试人员该从何时开始介入测试呢?各个公司都有自己的想法,对于我们公司而言,当一个功能已经设计好并且决定在这个迭代周期中开发时,测试人员就应该开始介入了。

  怎么介入呢?

  1、先从设计文档着手,参考客户需求看看设计文档是否已经实现客户的要求,对有疑问的地方与设计人员沟通清楚。当搞清楚整个设计思路以后,用脑中已经存在着的这个概念功能来写测试用例

  这个测试用例需要共享给设计人员与开发,特别是给开发人员,因为他们开发的时候就能参照到这些测试点,避免出现未考虑到的地方。

   2、当开发人员开发完成后,测试人员开始测试前或者测试中,需要进行讨论会,讨论什么呢,讨论这个功能的测试覆盖点。之前测试用例已经写完了,但是这个 测试用例是基于一个想象中的功能的,实际的功能怎么样子,谁都不知道。而现在实际功能做出来了,对于一个测试人员而言,就能得到基本的测试点了。而开讨论 会的目的就是尽可能全的把测试点覆盖,毕竟一个人的思维总是有局限性的,众人拾柴火焰高。

  不过,在敏捷中,功能是不定时做完的,可能今天做完2个,明天又做完3个,后天可能一个都没有,所以这种讨论会不是固定间隔的,一般情况下,累积几个功能以后开一个讨论会。

  开讨论会之前必须做好准备工作,也就是参与者需要提前看过这个会议中需要讨论的功能,可以会前给大家一个小时或者半个小时研究一下。而在会议中,功能的实际测试者需要将大家对于这个功能的讨论测试点记下来,之后更新之前写好的测试用例。

  通过这个讨论会的方式,可以有效地提高测试覆盖面,从而提高产品质量。

  当一个功能开发完成以后,测试人员就可以开始按照设计完成的测试用例来进行测试了。在测试过程中,我们也需要注意很多地方:

  1、首先,虽然测试可以根据测试用例来测,但是一个产品如果需要覆盖很多环境,比如数据库,浏览器,操作系统等, 你要全部覆盖到,我相信几个Sprint都没法测完,所以怎么解决的呢?我们是按照迭代测试的方式来解决,简单而言,就是把一个功能的测试分成几轮,第一 轮可能在SQL+IE+Win7上测,第二轮呢,则在Oracle+Firefox+W2008上测,第三轮。。。。。。这个方法相对于我们现在的人力资 源来说比较合适,因为理论上你要测试全的话,测试的组合个数就是各个环境个数乘在一起,DB(SQL+Oracle+Access)×浏览器 (IE+Firefox+Chrome)×操作系统(Win7+W2008+W2003)=27,这个是穷尽测试,的确可以测得很全,但是耗费的资源太 多,一般都不太可能采用。我们实际测的时候,只需要考虑三个组合: SQL+IE+Win7,Oracle+Firefox+W2008, Access+Chrome+W2003,这种方式有个好处就是既覆盖了所有测试点,又兼顾了时间与人力资源。

  2、既然只有三个组合,那为什么还要分成不同的轮次测同一个功能呢?这个里是很有考虑的,首先,我们测试第一轮的时候,必然会发现Bug, 开发修Bug可能会导致其他Bug产生,这些需要我们再做回归测试;第二,敏捷欢迎变更,功能的变更是家常便饭,所以一旦一个已经做完的功能发生变更,就 需要我们重新测试过;第三,对于一个功能的测试,我们知道每个人总是有思维定式,如果能有不同人来测试同一个功能,可能会发现很多不一样的Bug。基于这 些方面的考虑,我们设计了一个功能需要经过起码三轮的测试,第一轮是最主要的测试,测试完毕这个功能就应该是基本可用了,后面两轮属于回归测试,确保修复 Bug和做过变更过的功能依然可靠,并且用不同人的角度来测试同一个功能。

  3、分成三轮,其实还有另外一个也很重要的考虑,由于是敏捷 方式,所以对于时间的把握很重要,我们希望每个Sprint都能产生一个可用的产品,可以让客户来体验新做的功能,而测试往往是个拦路虎,因为既然要测, 我们就像测得仔细,覆盖很多地方,那这个就需要时间,时间是敏捷的敌人,所以我们就在想,既要能快速得到Build,让客户去看,又要保证质量,只能采用 分步的方式来做,先在最常用的环境里进行测试,保证基本功能正常,可以给客户评估测试,然后接下来再通过几轮测试保证这个功能的质量。

   采用了这种方式来进行敏捷测试,其实给整个测试团队带来了很大的压力,我们需要更快的反应速度,更高的责任感,更强的掌控能力,一旦某一环失控,之后都是 一个连环失控的局面,比如这个Sprint有功能来不及测完,下一个Sprint已经开始,新的功能又开始过来,你得先测完上个Sprint的,因为有客 户等着看,但是这个Sprint又在大量累计功能,最后越堆越多,而且在测试理论上,Bug如果在早期发现,修复成本最低,一旦早期没有发现,之后又在 Bug的基础上做了其他功能,最后导致了连环Bug,修复成本会高得离谱。所以如果更高的要求能带来产品更好的质量,当然是很值得的,而且对于员工个人能 力的提高也非常有帮助。

  敏捷测试的实践其实很多公司都在研究,但是真正能成功的可能还不多,其实我们已经试验过很多方法,这次也是一个经验总结后的继续尝试,相信很快能找到敏捷测试的真谛。

posted @ 2012-07-17 10:23 顺其自然EVO 阅读(126) | 评论 (0)编辑 收藏

性能测试在软件企业的应用

随着软件行业的不断发展,越来越多的企业更加重视产品的质量。性能测试已经成为软件质量保障的一个重要因素。一个软件性能的优劣很有可能直接决定一个软件的成败,甚至一个企业的兴衰。每个软件企业都有各自不同的应用领域,有着不同的实际情况,这样必然要求每个企业量体裁衣,选择适合自己的应用策略。

  大型企业、大型项目的应用策略

  大型企业应用的软件系统,业务比较复杂、用户数很多、存在并发情况、业务的响应时间、操作的实时性、稳定性、安全性、可恢复性等都要求很高。

  象银行、电信、铁路等大型企业一般通过CMMI、 ISO等认证,企业拥有先进的管理模式、人员储备丰富、实力雄厚,在涉足的领域基本处于不可撼动的地位。这些行业对性能的要求很高。在此仅举一个铁路售票 系统的例子:每逢春节、五一、十一,相信坐火车回家探亲或度假的朋友一定身有体会。在火车站、车票零售点,人海茫茫,一望无际,此时火车售票系统正在经受 着巨大的性能考验。全市几百个售票网点同时紧张忙碌工作。售票过程一般分为两步,首先根据购票者提供的要出行的日期、车次和目的地进行相关查询,然后在有票的情况下,收取现金,打印出相应的车票交付给购票者。一个看起来简单的两个步骤,但当成百上千的终端同时执行时,情况就复杂了。如此众多的交易同时发生,对应用程序本身、操作系统、中心数据库服务器、中间件服务器、网络设备的承受力都是一个严峻的考验。由这些行业的性质决定了决策者不可能在发生问题后才考虑系统的承受力, 预见并发承受力, 是这些行业应该考虑的一个很重要的问题。

  鉴于大型企业资金雄厚、管理规范、人员分工明确,笔者认为主要可以有两种方式解决大型企业的性能测试问题。

  解决方案一:构建自己的性能测试团队

  组建由性能测试专家、数据库专家、网络专家和系统软件管理员以及资深的程序员(有的公司还有业务专家)构成的性能测试团队。性能测试团队是一个独立的部门,在进行性能测试时,需要制定详细的性能测试计划、测试设计、测试用例,而后依据测试用例执行性能测试、分析性能测试结果,提出性能调整建议、书写性能测试总结报告。在工具的选用方面,建议选择商业性能测试工具,强大的功能、丰富的统计分析项、而且象Mercury LoadRunnerIBM Rational Performance Tester等工具还提供了专门的插件可以集成到IDE中,做粒度很细的工作,如看某个算法的执行时间、某个存储过程的执行时间、甚至某个语句的执行时间等。这些优势无疑为专家们定位系统问题提供了很好的依据。

  解决方案二:专业性能测试机构为系统测试

  如果企业没有自己的性能测试部门,请专业的性能测试机构为系统做测试也不失为一个好办法。专业软件测试机 构具有成熟的测试流程和测试方法,由有丰富的工作经验的性能测试工程师进行测试并提交专业的性能分析报告,可极大地提高测试有效性,同时企业不需为维护性 能测试而保留的由各方面专家组成的部门人员的高额费用(这种情况在很少进行性能测试的企业尤为重要)。还可保证测试的独立性、公正性,避免了部门之间产生 矛盾或磨擦。

  中型企业、中型项目的应用策略

  中型应用的软件系统,业务比较复杂、用户数较多、存在并发情况,对业务的响应时间、稳定性等都有一定的要求。

   中型企业一般通过ISO认证,企业拥有比较先进的管理模式、有一定的人员储备、较强实力,在涉足的领域有比较有名气,对性能的要求比较高。在此仅举一个 汽车配件查询系统的例子:该系统提供近千家的汽车配件信息,通常有50-120人在线。用户操作的最多的就是查询厂家及其配件信息的操作。这是一个典型的 中型项目。用户并发数量不是很大,涉及到频繁的查询操作,对系统的响应时间和系统的稳定性要求比较高。

  鉴于中型企业有较强实力、管理较规范、有一定的人员储备,笔者认为主要可以有三种方式解决中型企业的性能测试问题。

  解决方案一:临时组建性能测试团队

   在测试部门和开发部门临时组建由资深的程序员、资深的测试员、数据库专家、网络专家和系统软件管理员构成的性能测试团队。性能测试团队不是一个独立的部 门,分别由隶属于开发、测试等部门的专家构成。在进行性能测试时,需要制定详细的性能测试计划、测试用例,而后依据测试用例执行性能测试、分析性能测试结 果,提出性能调整建议、书写性能测试总结报告。在工具的选用方面,建议选择商业性能测试工具,购买单协议的Mercury LoadRunner、IBM Rational Performance Tester等工具。也可以选择开源的性能测试工具,如:Jmeter 、 OpenSTA等。还可以选择免费的性能测试工具,如:Microsoft Web Application Stress Tool 或 Microsoft Application Center Test 。但是无论是开源工具还是免费的测试工具,因为这些工具为非商业工具,它们使用的熟悉过程时间长、统计分析项不是十分丰富以及产品的后期升级和技术支持没 有保证都应该成为企业考虑的内容。

解决方案二:自行编写测试程序

  对于特定的模块或者插件也可以进行针对性进行代码编写,进行相关性能测试。在此我仅举一个例子,记得在开发一个汽车定损行业管理软件时,系统需 要以FTP方式传送汽车损坏情况照片,决定采用第三方提供的FTP服务器组件。需要对该FTP服务组件进行系统稳定性和并发性测试。经过项目组协商决定采 用自行编写多线程程序模拟多个客户端进行不间断的持续FTP上传和下载操作。自行编写测试程序也不失为另一种性能测试的方法,但是在您进行程序编写的时候 一定要注意您所应用的组件是否是线程安全的,如果线程不安全将会出现问题。

  解决方案三:专业性能测试机构为系统测试

  如果在时间紧、任务重以及在企业条件允许的情况下,请专业的性能测试机构为系统做测试也不失为一个办法,其优势不再赘述。

  小型企业、小型项目的应用策略

  小型应用的软件系统,业务比较简单、用户数也不是很多、存在并发情况,对业务的响应时间、稳定性等都有一定的要求。

  小型企业一般管理不是很规范、人员储备不太充足、有一定的经济实力,在涉足的领域有些名气,对性能有一定的要求。在此仅举一个进销存管理系统的 例子:该系统为一个大型商场对日常进销存业务的管理,通常有10-30人应用此系统。用户操作的最多的就是查询与销售商品的操作。这是一个典型的中、小型 项目。用户并发数量不大,涉及到频繁的查询和出库操作,对系统的响应时间和系统的稳定性有一定要求。

  鉴于小型企业有一定的经济实力、管理不是很规范、人员储备也不是很充足,笔者认为主要可以有两种方式解决小型企业的性能测试问题。

  解决方案一:临时组建性能测试团队

  临时组建由资深的程序员、数据库专家、网络专家和系统软件管理员构成的性能测试团队,有的公司可能存在上述提及人员不完整的情况,那么可以针对 项目的重要程度,适当增加相应的专家人员,必要时应该外聘一些专职或者兼职的专家。性能测试团队不是一个独立的部门,分别由隶属于开发等部门的专家构成。 在进行性能测试时,需要制定详细的性能测试计划、测试用例,而后依据测试用例执行性能测试、分析性能测试结果,提出性能调整建议、书写性能测试总结报告。 在工具的选用方面,可以考虑选择商业性能测试工具,购买单协议的Mercury LoadRunner、IBM Rational Performance Tester等工具、或者购买具有一个月或者几个月许可协议的商业性能测试工具。也可以选择适合项目的开源、免费性能测试工具。

  解决方案二:专业性能测试机构为系统测试

  如果在时间紧、任务重或者软件性能测试要求较高以及在企业条件允许的情况下,请专业的性能测试机构为系统做测试也不失为一个办法,其优势不再赘述。

posted @ 2012-07-17 10:20 顺其自然EVO 阅读(164) | 评论 (0)编辑 收藏

可扩展性数据库的架构设计

  扩展性与硬件

  随着系统的膨胀,硬件的可扩展性体现在增加资源,提高性能的能力上,如添加更多的处理器、内存等。

  扩展性与软件

  扩展性要求软件能够有效地利用硬件的能力,软件的设计应该支持并行计算。对于数据库引擎,这意味着服务器组件必须支持多线程计算,允许操作系统在所有处理器核心上执行并行任务调度。不仅如此,数据库引擎必须提供有效的方法,以在多核上分解工作负荷。举个例子,如果数据库只使用四个线程,那么它在四核处理器和八核处理器上允许,并不能体现出性能差异。

  分布式设计

  数据库引擎分割工作流,以充分利用硬件的能力并非易事,不是所有的数据库管理系统都能很好地支持并行计算。不仅仅是数据库引擎,数据库和其它系统资源都必须进行分割,以解决相互依赖性关系。因此,整个系统需要一个分布式设计。

  例如,大多数数据库以B树架构存储索引。B树使得索引可以快速地定位数据,高效地插入、删除数据,但这需要保持“平衡”,即B树的树架构必须具有相同层级的叶节点。一个简单的插入或删除操作都可能打破这种平衡。这导致在多核、多线程之间B树的管理与共享非常困难。多个线程会频繁抢夺B树的根节点,这会导致性能瓶颈。

  最小化共享资源

  最小化共享资源的数量是扩展性的重要话题。最小化共享资源可以使不同的线程运行在不同的核心之上,而无需等待其它线程释放共享资源。如果线程缺乏独立性,即便增加处理器,性能也会大打折扣。

  这个概念可以通过数据库管理系统RDM予以体现。RDM对分布式数据库有非常智能的支持,允许应用在不同的硬件之上进行数据的分布式计算,并能在不同的线程、进程之间尽可能地减少竞争。

  多版本并发控制与同时访问

  对同一数据的并发读写访问非常重要,多版本并发控制(MVCC)允许对同一数据进行并发读写访问,而不必阻塞线程或进程。MVCC可以让读进程在写进程访问数据之前访问数据的镜像,通过这种方式,保证了读写进程的并行操作。

  数据复制:高效的分布式技术

  数据复制通过将主数据库复制为多个只读副本,成为了一种提高扩展性的有效途径。这样,远程服务器的处理器也可以读取和本地数据一致的副本,非常有助于降低访问主数据库的并发进程数目。

  总结

  简而言之,一个高度扩展性的分布式数据库架构应具备如下特性:

  1、轻量级服务器的进程不应占用过多的CPU时间,而应通过我们的多个处理器并行运行多个实例。

  2、客户端应用可连接多台服务器并从中提取数据。

  3、通过数据复制技术,客户端应用可以从主数据库或从数据库中检索数据。

posted @ 2012-07-16 11:19 顺其自然EVO 阅读(410) | 评论 (0)编辑 收藏

软件质量的分层控制方法

  一、质量的相对概念

  1、多数比较上进的程序员,都希望自己的代码作品是优雅的、高质量的、别人看到能赞赏不已的。但事实上,紧迫的进度压力使程序员没有太多时间思考,匆忙赶出功能后,赶快测试发布赶快交付给客户。因此有人提出需要重构,有人提出各种测试方法,计算“每千行代码缺陷率”,以追求“零缺陷”为目标。总之多数技术人员认为“质量越高越好”。这里有个典型例子《养成重构的习惯有多重要》,很有代表性。

  2、现在我们假设一种场景,筷子的质量。

  首先你到了五星级酒店,它的筷子必须是如象牙般优雅,笔直而对称,没有任何瑕疵斑点,有合适的重量手感,等等,也就是说五星级酒店对筷子的质量要求是很高的,否则客户会发飚。

  然后你到了一家路边的快餐店,顺手拿过来一双“一次性筷子”,拆开后发现毛刺很多容易扎手,甚至筷子有点弯曲,但你还是凑合着用了,或者实在无法忍受就扔掉再拿一把,因为这是在路边快餐店,用户对筷子的要求是低的。

  如果你把快餐店的筷子卖到酒店里会发生什么情况?质量太低客人无法接受。如果五星级酒店的筷子卖到快餐店会发生什么情况?用户不需要那么好,也不愿意付那么多钱。所以同样做一个筷子,却对质量有不同要求。

  所以说:质量是相对的。

  3、基于第2点,所以一味追求“高质量代码”,把“高质量目标”凌驾于“企业赢利目标”之上,是多数技术人员所犯的错误。

  二、对质量目标进行逐级分解和控制

  多数成熟度不高的软件公司会有一定的质量控制方法,但将其用于所有的项目和所有的软件层面。我认为这是一种资源浪费。适度降低对外围层次、用户需求弱相关、使用频度低模块的质量控制,会给项目带来进度和成本上的收益。

  比如下面这个案例。这是一个比较成功的网游公司中,项目代码分层控制情况

  大家特别注意每个层次的质量要求,从“不使程序崩溃、逻辑正确不使程序崩溃即可”,到“技术总监亲自开发测试,不许别人碰里面代码”分级管理,越是核心部分对代码质量要求越高,从开发人员的级别/背景/资历/审核人员级别/测试方法上可以体现出来。而4和5两层比较外围的代码, 只要实现功能就可以了, 我阅读了这些代码并在其中开发过一小段时间,里面到处充斥着“坏味道”的代码,程序员都是边改边骂,但这并不影响这个游戏有60万的活跃用户和300万以上的注册用户,给公司带来强劲的现金流。而这套对质量进行分级控制的方法,则是技术总监传授讲解给我的。

  (表格中代码开放度仅供参考,小公司是输不起的,看看pudn.com上那些把老东家代码拿出来开源的人渣就知道了)

  大家知道项目的时间-质量-成本铁三角, 如果把上面5层代码的铁三角列个表格出来,大致如此(我们假设在每个软件层面投入的成本是一致的)

  越是核心层(1层), 其需要修改的代码越少,但是对代码执行的时间和空间开销越小, 稳定性要求越高. 越外围的代码(5层), 针对需求而开发和改动的代码量越大。选取上表中的1层、5层、平均画图来表示是这样的:

  因此,精益求精、重构只适用于靠近核心的代码层;而对于外围代码层, 由于赶工而导致代码质量低、放松测试条件,则是完全合理的。

  三、结论

  所以,在做软件工程的质量控制时,应该把握软件的关键层面,抓住质量控制的瓶颈。横向而言,就是开发框架、引擎、核心功能之类的层级;纵向而言,就是用户使用频率最高的模块、和竞争对手做差异化竞争的功能等。对于外围代码和次要模块代码,前者一般不容易出错得太离谱(被开发框架限制住),后者使用频度低,则可以适当牺牲质量以求开发速度。

  因此,处于外围代码开发的兄弟们就不要成天抱怨、不要提出各种重构要求了。我也曾经在“坏味道”的代码,确切地说是“粪坑”中扑腾,深知其中感受。但就像魔兽世界里组队打某些副本BOSS,有的人职责是拉住BOSS的仇恨(拉住客户),有的人职责是砍BOSS(解决核心模块),有的人则需要群杀不断刷出来的小怪(快速开发外围逻辑)。如果不是这样的配合,那就会团灭;如果不是这样的配合,下个月的工资可能就发不出来,不是吗?

posted @ 2012-07-16 11:04 顺其自然EVO 阅读(161) | 评论 (0)编辑 收藏

Code Review代码审查的思路

  1、关于Code Review

  1.1 Code Review的目的

  Code Review主要用来在软件工程过程中改进代码质量,通过Code Review可以达到如下目的目的:

  (1)在项目早期就能够发现代码中的BUG

  (2)帮助初级开发人员学习高级开发人员的经验,达到知识共享

  (3)避免开发人员犯一些很常见,很普通的错误

  (4)保证项目组人员的良好沟通

  (5)项目或产品的代码更容易维护

  1.2 Code Review的前提

  进入Code Review需要检查的条件如下:

  (1)Code Review人员是否理解了Code Review的概念和Code Review将做什么

  如果做Code Review的人员不能理解Code Review对项目成败和代码质量的重要程度,他们的做法可能就会是应付了事。

  (2)代码是否已经正确的build,build的目的使得代码已经不存在基本语法错误

  我们总不希望高级开发人员或是主管将时间浪费在检查连编译都通不过的代码上吧。

  (3)代码执行时功能是否正确

  Code Review人员也不负责检查代码的功能是否正确,也就是说,需要复查的代码必须由开发人员或质量人员负责该代码的功能的正确性。

  (4)Review人员是否理解了代码

  做复查的人员需要对该代码有一个基本的了解,其功能是什么,是拿一方面的代码,涉及到数据库或是通讯,这样才能采取针对性的检查

  (5)开发人员是否对代码做了单元测试

  这一点也是为了保证Code Review前一些语法和功能问题已经得到解决,Code Review人员可以将精力集中在代码的质量上。

  1.3 Code Review需要做什么

  Code Review主要检查代码中是否存在以下方面问题:

  代码的一致性、编码风格、代码的安全问题、代码冗余、是否正确设计以满足需求(性能、功能)等等

  1.3.1 完整性检查(Completeness)

  代码是否完全实现了设计文档中提出的功能需求

  代码是否已按照设计文档进行了集成和Debug

  代码是否已创建了需要的数据库,包括正确的初始化数据

  代码中是否存在任何没有定义或没有引用到的变量、常数或数据类型

  1.3.2 一致性检查(Consistency)

  代码的逻辑是否符合设计文档

  代码中使用的格式、符号、结构等风格是否保持一致

  1.3.3 正确性检查(Correctness)

  代码是否符合制定的标准

  所有的变量都被正确定义和使用

  所有的注释都是准确的

  所有的程序调用都使用了正确的参数个数

  1.3.4 可修改性检查(Modifiability)

  代码涉及到的常量是否易于修改(如使用配置、定义为类常量、使用专门的常量类等)

  代码中是否包含了交叉说明或数据字典,以描述程序是如何对变量和常量进行访问的

  代码是否只有一个出口和一个入口(严重的异常处理除外)

  1.3.5 可预测性检查(Predictability)

  代码所用的开发语言是否具有定义良好的语法和语义

  是否代码避免了依赖于开发语言缺省提供的功能

  代码是否无意中陷入了死循环

  代码是否是否避免了无穷递归

  1.3.6 健壮性检查(Robustness)

  代码是否采取措施避免运行时错误(如数组边界溢出、被零除、值越界、堆栈溢出等)

  1.3.7 结构性检查(Structuredness)

  程序的每个功能是否都作为一个可辩识的代码块存在

  循环是否只有一个入口

  1.3.8 可追溯性检查(Traceability)

  代码是否对每个程序进行了唯一标识

  是否有一个交叉引用的框架可以用来在代码和开发文档之间相互对应

  代码是否包括一个修订历史记录,记录中对代码的修改和原因都有记录

  是否所有的安全功能都有标识

  1.3.9 可理解性检查(Understandability)

  注释是否足够清晰的描述每个子程序

  是否使用到不明确或不必要的复杂代码,它们是否被清楚的注释

  使用一些统一的格式化技巧(如缩进、空白等)用来增强代码的清晰度

  是否在定义命名规则时采用了便于记忆,反映类型等方法

  每个变量都定义了合法的取值范围

  代码中的算法是否符合开发文档中描述的数学模型

  1.3.10 可验证性检查(Verifiability)

  代码中的实现技术是否便于测试

  1.4 Code Review的步骤

  这些是我在平时工作中的经验总结,目前也是按照这个步骤在做。

  (1)代码编写者和代码审核者坐在一起,由代码编写者按照UC依次讲解自己负责的代码和相关逻辑,从Web层->DAO层;

  (2)代码审核者在此过程中可以随时提出自己的疑问,同时积极发现隐藏的bug;对这些bug记录在案。

  (3)代码讲解完毕后,代码审核者给自己安排几个小时再对代码审核一遍。

  代码需要一行一行静下心看。同时代码又要全面的看,以确保代码整体上设计优良。

  (4)代码审核者根据审核的结果编写“代码审核报告”,“审核报告”中记录发现的问题及修改建议,然后把“审核报告”发送给相关人员。

  (5)代码编写者根据“代码审核报告”给出的修改意见,修改好代码,有不清楚的地方可积极向代码审核者提出。

  (6)代码编写者 bug fix完毕之后给出反馈。

  (7)代码审核者把Code Review中发现的有价值的问题更新到“代码审核规范”的文档中,对于特别值得提醒的问题可群发email给所有技术人员。

  提示

  Code Review必备的文档:

  “代码审核规范”文档:记录代码应该遵循的标准。

  代码审核者根据这些标准来Code Review代码,同时在Code Review过程中不断完善该文档。

  2、Code Reivew的执行

  一个标准的Code Reivew活动应该分为三个阶段:

  2.1 事前准备阶段

  在一次CR前,对以下内容进行充分准备。

  2.1.1 CR的对象

  在准备CR代码对象时,我们要注意代码的数量,如果代码量比较大,要对代码进行必要的分解,确定其中的关键代码,对关键代码进行CR,可以达到举一反三的目的。

  2.1.2 CR的内容

  我们对代码的审查内容很多,如代码的编写是否规范(注释的书写格式、命名规范等)、技术处理规范(异常处理、日志处理、代码组织结构等)、业务实现等。我们不能希望通过一次CR活动,完成所有这些内容的审查,因此我们必须设定本次CR活动内容界限,确定审查重点;

  2.1.3 评审规范和标准

  在CR前设计确定评审规范和标准是必要,通过规范和标准我们在审查过程中可以有据可依,有理可循,而且还可以做到标准统一。

  2.1.4 选择CR活动的参与者

  在CR开始前,必须把本次CR活动的对象、审查内容以及审查的规范和标准通报给所有的参与者。

  2.1.5 选择CR活动的实施方式。

  CR活动有很多形式可供我们选择,我们可以根据实际情况选择桌面式CR、演示讲解式CR、一对一的座位CR等等。

  2.2 实施阶段

  充分的事前准备,只是做好CR活动的前提,在CR实施过程中,我们要做好以下工作。

  2.2.1 准确记录

  对于CR过程发现的问题,我们必须清晰准确的记录,可以使用问题点记录单,明确记录的项目和内容。

  2.2.2 讲解与提问

  CR过程中,要采用代码作者讲解和审查者提问方式。审查者不能只在发现问题时提问,同时也要根据本次审查的内容要求代码作者对某个特定问题的讲解。

  2.2.3 逐项审查

  对事前确定的审查内容,要逐项审查,不能因为时间不足等因素一扫而过。

  2.2.4 注意气氛

  实施审查时,要营造一个讨论问题、解决问题的氛围,不能把审查会搞成批判会,这样会影响相关人员的积极性。

  2.3 事后跟踪跟踪。

  2.3.1 确认发现的问题

  CR结束后,对发现的问题,首先需要确定以下内容。

  1)问题点的难易程度以及影响的范围;

  2)解决问题的责任者和问题点修正结果的确认者;

  3)解决问题点的时限。

  2.3.2 修正问题责任者

  对于修正问题责任者,在问题点的修正过程中,要三方面内容的记录。

  1)问题点的原因;

  2)解决问题点的对策;

  3)修正的内容。

  2.3.3 修正结果确认者

  做为修正结果的确认者,必须按照事前约定的时限及时的对修正结果进行全面的确认

  3、注意事项

  3.1 经常进行Code Review

  (1)要Review的代码越多,那么要重构,重写的代码就会越多。而越不被程序作者接受的建议也会越多,唾沫口水战也会越多。

  (2)程序员代码写得时候越长,程序员就会在代码中加入越来越多的个人的东西。

  (3)越接近软件发布的最终期限,代码也就不能改得太多。

  3.2 Code Review不要太正式,而且要短

  忘了那个代码评审的Checklist吧,走到你的同事座位跟前,像请师父一样请他坐到你的电脑面前,然后,花5分钟给他讲讲你的代码,给他另外一个5分钟让他给你的代码提提意见,这比什么都好。而如果你用了一个Checklist,让这个事情表现得很正式的话,下面两件事中必有一件事会发生:

  (1)只有在Checklist上存在的东西才会被Review。

  (2)Code Reviews 变成了一种礼节性的东西,你的同事会装做很关心你的代码,但其实他心里想着尽快地离开你。

  只有不正式的Code Review才会让你和评审者放轻松,人只有放松了,才会表现得很真实,很真诚。记住Review只不过是一种形式,而只有在相互信任中通过相互的讨论得到了有意义和有建设性的建议和意见,那才是最实在的。不然,作者和评审者的关系就会变成小偷和警察的关系。

  3.3 尽可能的让不同的人Reivew你的代码

  如果可能的话,不要总是只找一个人来Review你的代码,不同的人有不同的思考方式,有不同的见解,所以,不同的人可以全面的从各个方面评论你的代码。

  但不要太多了,人多嘴杂反而适得其反,基本上来说,不要超过3个人,这是因为,这是一个可以围在一起讨论的最大人员尺寸。

  下面是几个优点:

  (1)从不同的方向评审代码总是好的。

  (2)会有更多的人帮你在日后维护你的代码。

  (3)这也是一个增加团队凝聚力的方法。

  3.4 保持积极的正面的态度

  程序员最大的问题就是“自负”,尤其当我们Reivew别人的代码的时候,我已经见过无数的场面,程序员在Code Review的时候,开始抨击别人的代码,质疑别人的能力。太可笑了,我分析了一下,这类的程序员其实并没有什么本事,因为他们指责对方的目的是想告诉大家自己有多么的牛,靠这种手段来表现自己的程序员,其实是就是传说中所说的“半瓶水”。

  所以,无论是代码作者,还是评审者,都需要一种积极向上的正面的态度,作者需要能够虚心接受别人的建议,因为别人的建议是为了让你做得更好;评审者也需要以一种积极的正面的态度向作者提意见,因为那是和你在一个战壕里的战友。记住,你不是一段代码,你是一个人!

  3.5 学会享受Code Reivew

  这可能是最重要的一个提示了,如果你到了一个人人都喜欢Code Reivew的团阿,那么,你会进入到一个生机勃勃的地方,在那里,每个人都能写出质量非常好的代码,在那里,你不需要经理的管理,团队会自适应一切变化,他们相互学习,相互帮助,不仅仅是写出好的代码,而且团队和其中的每个人都会自动进化,最关键的是,这个是一个团队。





posted @ 2012-07-16 10:43 顺其自然EVO 阅读(883) | 评论 (0)编辑 收藏

漫谈测试工具的开发实践

TCon论坛上公直给大家带来的《漫谈测试工具的开发实践》得到了许多同行的肯定,作为测试工作者,需要同时关注测试框架和测试工具。精典的测试框架为数不多,而不同的业务场景需求会带来不同的测试工具需求。因此,我们会常常面临选择合适的测试工具或者开发合适的测试工具。公直提到,公司的发展与基因有关,工具的基因也会决定工具的发展。

  常见的测试框架设计思想:非结构化的测试框架,模块化测试模式,数据驱动的测试框架,关键字驱动的测试框架等。

  一淘的测试层次包括单元测试功能测试,回归测试,性能测试,冒烟测试和流量测试。在测试宗旨的交流上,公直分享了google测试的一些主张:对于质量来说,预防问题比发现问题本身更重要。质量更多是开发人员的问题,而不是测试人员的。通过把测试工作融入到开发过程中,我们能降低那些富产Bug的人的出错机会,不仅可以避免了大量最终用户的使用问题,而丐还可以极大地降低测试人员报无效Bug的数量(节选自谷歌如何测试第三篇)。

  除了测试工具本身,公直还分享了自动化测试调动工具, -TOAST(Toast Open Automation System Test),其主要功能包括持续集成测试,分布式测试,报表,openAPI。TOAST支持多类自动化测试框架。

posted @ 2012-07-16 10:40 顺其自然EVO 阅读(249) | 评论 (0)编辑 收藏

软件测试的魅力何在?

问题:软件测试的魅力何在?您为什么选择测试一行而不做开发?

  精彩回答:

  陈甫鸼:

  虽然我现在换到开发去了,不过毕竟也在这一行做了六年,貌似还是有机会在这里发言的吧。最初我接触测试纯粹是出于偶然,微软到我们学校的面试只有做测试的肯要我啊。不过后来做了一阵子之后慢慢就喜欢上这个位置了。说说我过去的一些经验吧。

  正如我之前在很多回复中说的,测试和开发是两个关注点不一样的工作。开发的目标是实现功能,测试的目标是确定功能是否能够正常运作。那么它的乐趣在哪里?简单地说是两个关键词:“发现”和“分析”。

  一两句话很难说清楚,举一个例子吧。

  假定你打算写一个VOIP程序,请问怎么测试它的效果?没有经验的测试可能会告诉你我连上两台机器确定电话可以打通就可以了,而有经验的测试可能会给你列出一大堆的组合:

  1、你的场景支持笔记本和耳机么?你支持什么耳机?蓝牙还是3.5mm插口耳机?

  2、你的场景支持使用笔记本麦克风么?还是只支持配麦克风的耳机?

  3、你的场景支持使用手机设备么?Android还是iOS?

  为什么要列出这么多东西?有人可能会对此嗤之以鼻:只是为了保证什么都能测到而已。但是其实这里每一个场景都是有意义的:

  1、蓝牙耳机普遍都有硬件支持的回声消除模块(Acrostic Echo Cancellation),而普通3.5mm耳机则通常由于结构简单而没有。对于没有回声消除的普通耳机,我们必须自己提供软件的回声消除避免影响接听效果。

  2、我们不能使用完全相同的逻辑处理耳机和笔记本麦克风的语音输入。因为耳机麦克风的定向性比笔记本麦克风强很多,它只能取到声源凑得很近时发出的声音,而笔记本麦克风的设计则是用来在屏幕前相当大的范围内取声的。如果对笔记本麦克风使用耳机麦克风的声音检测算法则会由于灵敏度过高而将大量周边杂音收入,影响通话效果。而且有些场景是笔记本麦克风特有的,比如用户的打字音和风扇噪音。

  3、Android和iOS都有内建的通话模块。iOS甚至提供了非常高效的回声消除和增益控制模块,但是没有静音检测模块。所以如果桌面程序移植到手机上时可以很好地利用这些功能简化自己的代码。而Android的回声消除模块则表现非常不稳定,需要很多调整才能得到较好的效果。

  这就是所谓的“发现”,发现开发没注意的地方,发现项目经理没定义的场景,并提出相应的测试场景。这需要宽广的知识面才能做到。没有经验的测试更倾向于对所有测试的平台做全排列,但求不忽略任何一个场景。这在资源无限的情况下当然没问题,但真实项目中,测试的资源经常是最有限的,所以我们得学会怎么做最有效的测试,而不是闭着眼睛搞全面铺开。

  那么什么是“分析”?举例来说:如果一个内测客户投诉你的VOIP程序实际使用中声音断断续续,你怎么分辨问题的原因?声音断断续续的情况有很多种,有由于网络延迟导致的,有由于操作系统处理过于繁忙导致程序执行时间被高优先级程序抢走而导致的处理中断产生的。我们怎么去分析哪些原因呢?没经验的测试可能会直接要求跑客户现场看看,但如果用户的环境不是每次都重现该怎么样?有经验的测试会提出:我们可以给客户一个调试用的版本,这个版本要求把数据包的收取时间点和每个数据段的开始处理时间点和CPU占用率纪录下来。通过前一个我们可以测量用户的网络情况,后一个数据段可以用来发现是否是操作系统换出导致的。反过来,对产品不熟悉的人,这些数据可能看不出什么用途。

  有人说,这些都可以让开发来做,用不着测试。完全正确。可问题是:开发有时间做这些么?在微软这样级别的公司里,所有的项目都有严格的开发进度,开发部门忙于实现功能的时候,我想没几个产品经理会同意频频打断开发的进度要求停下来做bug分析。

  另一点是我们不需要把开发和测试的界限分得那么清楚。事实上大部分如今的跨国IT公司都很少分开发和测试这两个职位(大约只有微软还严格地分两个职位吧,即使是这样,搜索那边也开始探索改变了),但是要做的工作还是那么多,只是顶着的头衔换了换,所以没必要纠结。

  === 我是转换话题的分割线 ===

  另一个问题是关于测试的工作方式的。就像开发一样,有经验和没有经验的测试在团队起到的作用是很不一样的。从测试中遇到问题采取的行动来看,我观察到的测试人员能达到的层次大概有这么几个级别:

  1、开一个bug;

  2、查找一些额外的资料如设计文档和历史,确定这是一个问题,然后给出详细的bug重现步骤;

  3、对重现步骤做一些精炼,确定能够重现bug的最少步骤;可能的话,将重现步骤做自动化;

  4、尝试通过研究代码确认问题所在;

  5、尝试给出一个fix;

  6、对错误的原因进行分析,提出一些标准化的方法来检测出类似的问题,比如stress,fuzzing等等;

  7、能够对标准化的测试流程定义对应的数据分析方法,可以保证开发和项目主管都能从中得到需要的信息来掌控质量状况。

  那么作为一个测试人员,我们的目标是什么?我对自己的目标是能对我控管的所有的bug从1做到4,在至少两个例子中我甚至能做到级别6。我在微软六年多,在很多部门都见到过可以见到可以总是做到级别7的测试,能做到这个状态的测试,没有人敢说他们技术不行。对于开发人员来说,如果你身边有一位能对大部分bug做到级别4的测试,我相信开发的工作也会轻松很多。

  即使是抓bug也分很多种。抓一群猴子来随便在键盘上胡点两下也算是测试,认认真真地一步步通过各种技术手段(代码覆盖、压力测试、安全分析等等)来步步推进也是测试。作为技术人员,你信任哪一种?我想多数人都会选择后者,但我要说的是在实践中很多测试团队都会不知不觉地变成前一种。为什么?因为测试对产品的设计不了解,所以本能地会选择最容易做的,可问起他们:你们测了多少?信心多高?他们就都傻掉了。我不是说猴子测试没意义:恰恰相反,它可以抓到我们思维上的许多盲点。但如果你的整个团队完全靠猴子测试过日子,那绝对不可能给你一个可信任的结果。

  那么看官们必然会问,这种大牛测试和大牛团队有多少?很不幸,就我个人的经验来说,事实是在我遇到的测试人员中,最多只能做到级别1的测试人员并不罕见,能做到3的测试人员就被很多人认为相当不错了,至于团队中存在多个大牛测试的队伍则真的很少见(微软总部的比例高很多)。是的,别惊讶,这就是我工作中遇到的情况。但是请注意,这不是说公司在花钱养废物,而是说在没有专业测试教育的情况下在入行初期必然会导致的现状。我们所有人都是从这个状态开始的,也都需要时间来让自己进步。

  也许还会有人问:这不是跟开发抢活儿干么?是的,没错。但为什么不能抢呢?我们的目的是什么?是开bug还是做更好的产品?如果你的全部目的只是多开bug,那真的很简单。真实的例子,我曾经见过将测试自动化代码的bug开成产品bug的。我知道要求一个同事干这个干那个很不礼貌,但这种什么都不做就先开了bug再说的做事风格是在耽误所有同事的工作。作为团队的一分子,测试在产品上多花一分时间,有时候能省下开发几天的工作量,因为测试是最熟悉这个bug的人,而开发则需要从头开始分析。

  ——当然,反过来开发也应该尽量将测试带入开发过程,让大家都知道各种功能进度的细节。这种合作同样能大大减少测试在产品设计变更时重新设计用例的时间。

  有人可能还要问:我的时间也很宝贵,为什么要替开发省时间?嗯,好问题。但我想谁都知道该怎么回答这种“问题”。

  现在知道我为什么要做六年测试了么?

 朱杉:

  和软件测试遭遇是个偶然,故事有点长,有空且看看作消遣吧。之前在一国企做金融类软件开发,开vi写C偶尔还客串VB,终于不堪一年200工作日以上的出差在外和出差期间彻夜加班且无双休待遇之折磨,一怒之下转而重回学校作个调整。大学同学所在公司招收实习生,本着赚点学费生活费的需要,抱着没做过的事情试试无妨的心态,邂逅了软件测试。研究生期间,学校先后开设了两门软件测试的课程,由于有实践在先,发现学习起来颇有心得。由于老师要求严格,第二学期选课人颇少,于是一门大课变成了给少数几个人开小灶,时间和资源瞬间变得充裕,让我受益匪浅。而自身的一些观察、分析、理解、想象能力上的优势逐渐在这个学习+实践的过程中体现出来。同时,在实习公司那边,我开始跟进一个至今说起来都让大家望而却步的新功能开发,遇到了开始做测试以来最大的一个挑战,那绝对是一段痛苦不堪的日子,但也正是这段时间让我飞速地成长起来,并获得了大家的认同。毕业后,自然也就留在了这家公司,正式加入了软件测试的大部队,似乎也不存在选择的问题。

  软件测试的魅力嘛,其实在你这个问题之前,我也没有刻意地去想过,况且一百个人眼里一百个哈姆雷特,大家的痒处也未必在同一处。于是就临时想到的说上一说,个人色彩浓,可能不太切题了:

  首先,我喜欢玩解谜类的益智游戏,而且发现我对这类的游戏通常上手较快。虽然我说不好这个跟测试具体有什么关联,不过有一些感觉是一样的,观察、推演、尝试、归纳、发现,一个妙趣横生的过程。测试本身也是对这方面能力的一个综合考验,拿到一个难题的时候那种又担心又手痒的感觉实在是和玩游戏很像。测试的过程又是一个学习和思维进一步发散的过程,一直引领人往前探索,很有吸引力。

  其次,新鲜感。我做功能测试和可访问性测试,新功能的探索和发现,是我个人一直爱接新功能胜过做回归的主要原因。新工具新技术的发现和学习是个有趣的过程。测试其实是个目的驱动的事情,基于这一点,没人会要求你从头造轮子,能拿来用的现成都得学会捡,不然什么都要从main写起,黄花菜都凉了。囤新奇工具、学新鲜技术,都是有趣的事情。

  再者,成就感吧。作为某应用的QA owner和一个dev团队长期合作,虽然大家也会有争论,时间紧张的时候也会互有抱怨,但合作非常顺畅。只有Dev和QA把发布一个健康的产品当做共同目标而密切合作的时候,才是一个良性的开发生态环境,一个成功发布的产品是大家共同努力的成果,既是dev team的骄傲,也是QA的骄傲,即使走向前台接受赞誉的更多是Dev,你也能因你所做出的贡献而自信满满,成就满满。想想,在参与设计讨论时指出可能存在的设计缺陷,在功能开发之前提供建议避免功能误读和错误风险评估,一个描述清晰、根源挖掘准确充分的defect送到dev处被干净利落地斩草除根,当support team来征询产品功能的相关问题时,当用户来寻求解决方案时,是不是都有一种叫成就感的东东在心里撒了欢地奔走呢。

  最后,当跟你吵架吵得最凶的开发背着你对别人夸你是最好的QA的时候,那种感动,一辈子都不会忘记的。


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

仅列出标题
共394页: First 上一页 306 307 308 309 310 311 312 313 314 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜