2009年3月11日星期三
2009年3月10日星期二
Essbase - 简单介绍
维(Dimensions)和成员(Members)是商业智能中重要概念,理解了维和成员,将有助于理解多维数据库的威力。维代表了你的商业计划组件的 核心,一般和部门的功能相关,有代表性的维时间、帐目,产品线、市场和部门等等。维一般是静态的,一旦定义好数据库的维后,在应用的生命周期里一般都不会 改变。
成员是一个维的单独的组件,例如ProductA、Product B、Product C是Product的成员。每个成员有一个独一无二的名字,一个维可以包括无限多个成员。多维性是OLAP的关键属性,系统必须提供对数据分析的多维视图 和分析,包括对层次维和多重层次维和完全支持,事实上,多维分析是分析企业数据最有效的方法,是OLAP的灵魂。
(1)在层次结构(Hicrarchies)里安排维所有的Essbase database应用都以定义一个database outline开始。
一个database outline:
·在一个Essbase database里定义成员之间的结构关系。
·组织在数据库里的数据。
·在成员之间定义聚合及数学关系。
Essbase用成员表示数据的层次关系。每一个维包括许多成员,顺序地,成员也可以包括许多成员。例如时间维包括四个季度,每个季度又包括三个月。
Essbase不限制每个维的成员的数目,可以定义很少的成员,也可以定义成百上千的成员一切都根据需要。
(2)成员关系(Member Relationships),代(Gencrlations)和层(Levels)
Essbase用层次,家族来描述一个Outline里成员的角色和关系描述梅一个成员的位置通过以下几个途径:
·父亲(Parents)、孩子(Chileren)和兄弟(Sibling)。父亲是一个有分支的成员,如Marging是Soles和cost of goods Scld的父亲。一个孩子是一个有父亲的成员,如sales,costof goods scld是Margin的孩子。一个兄弟是指一个和其它成员在同一个分支里的孩子成员,如sales和cost of goods scld是兄弟。
·子孙(Descendants)和祖先(Ancestors):子孙是在父亲下的所有成员,例如Profit、Invenory、Ratos是 Measures的子孙,它们的孩子也是Measures的子孙。祖先是一个分支里在一个成员上面的所有成员,例如Magin和Profit是Sales 的祖先。
·根(Root) 和叶(Leaves) :根是指在一个分支里的第一个成员,例如Measures是Prodift、Inventory它们的根。叶成员是没有孩子的成员,如Adcitions是叶结点。
·层(Levels)和代(Generlations):代是从根节点到叶节点;层是从叶节点开始一直到根。
(3)多维数据的执行动作:有上钻、下转、切片、切块、旋转等。
Essbase的基础结构原理
3.1 稀硫维(Sparse Dimensions)和密集维(Dense Dimensions)
大多数多维数据应用集有以下特征:
·数据不是平滑的而是随机分布;
·数据有可能不存在多数成员组合中,如有所有的产品不一定在国家的每一地区都销售。
Essbase将应用的维分为两种:衡疏维和密集维,通过这样,Essbase可以取得最优化的性能,存取空间最小,速度最快。
稀疏维是指一个具有很低的数据填允率的维如市场维和产品选择稀疏维,因为不是每一样产品在所有的市场都销售一个密集维是指一个具有很高的数据填充率的维。如Measures维选择为稠密维,因为Accounts里几乎填满了数据。
3.2 数据块(Data Block)和索引系统(Index System)
Essbase用两种内在的结构来存储和访问数据:数据块和索引。
Essbase为稀疏维(至少包括一个数据值)成员的独一无二的联合建立一个数据块,数据决也描述了所有密集维的成员。
Essbase为每一个数据块建立一个索引入口。
每一个独一无二的数据值在数据块里以一个数据格子的形式存在。当Essbase搜寻一个数据值时,它用索引定位数据块,用数据值定位格子。索引入口提供了一个数据块的指针,索引处理稀疏维特别有效,因为它仅仅是已存在的数据块的一个指针而已。
每一个数据块都是一个多维数组,它包括了固定的、有序的定位,为密集维成员之间的可能的联合,它不通过索引搜寻数据,它的存取和访问速度几乎是瞬间的。Essbase在数据块里定义数据格的顺序是通过你的outline database里密集的成员的顺序。
在定义outlined atabase是选择一个维是稀疏维还是密集维时,要根据需要来定。当全为稀疏维时索引多,查找慢;全为密集维时定义了许多空的数据格子,浪费资源,要根据情况而定。
HW - DELL OptiPlex 755 存储系统配置
1、Q35概述
该型号PC采用了 Intel Q35 Express 芯片组。
2、ICH9(Intel I/O Control HUB 9)
ICH9的技术细节及其参数请参考
http://download.intel.com/design/chipsets/datashts/31697202.pdf
ICH9 提供四个版本
• Intel® 82801IB ICH9 (ICH9)
• Intel® 82801IR ICH9 RAID (ICH9R)
• Intel® 82801IH ICH9 Digital Home (ICH9DH)
• Intel® 82801IO ICH9 Digital Office (ICH9DO)
存储控制功能就是所谓的ICH9R (I/O Control Hub 9) 提供。
ICHR9 提供最多6个SATA借口,支持AHCI,并支持多种RAID.
AHCI Operation (Advanced Host Controller Interface (AHCI)串行ATA高级主控接口
AHCI 模式
AHCI通过包含一个PCI BAR(基址寄存器),来实现原生SATA功能。由于AHCI统一接口的研发成功,使得支持串行ATA产品的开发工作大为简化,操作系统和设备制造商省去 了单独开发接口的工作,取而代之的是直接在统一接口上进行操作,可以实现包括NCQ(Native Command Queuing)在内的诸多功能。
一直以来SCSI硬盘在多任务负载下的表现能力为人称道,其根本的原因除了SCSI接口惊人的接口速率外,便是它的指令排序功能。以往的 PATA、SATA硬盘也正是因为缺少一种指令优化执行功能而在性能上落后于SCSI硬盘。针对这一困境,Intel的AHCI 1.0规范首次引入的NCQ(Native Command Qu),它的应用能够大幅度减少硬盘无用的寻道次数和数据查找时间,这样就能显著增强多任务情况下硬盘的性能。
AHCI defines transactions between the SATA controller and software and enables
advanced performance and usability with SATA. Platforms supporting AHCI may take
advantage of performance features such as no master/slave designation for SATA
devices—each device is treated as a master—and hardware assisted native command
queuing. AHCI also provides usability enhancements such as Hot-Plug. AHCI requires
appropriate software support (e.g., an AHCI driver) and for some features, hardware
support in the SATA device or additional platform hardware.
ATA模式
将SATA硬盘映射到系统的IDE通道上,故又称兼容模式
如果是ICH9R芯片组,启用RAID后,还可以支持下列模式
RAID AHCI 模式
RAID ATA 模式
Comment:
AHCI,RAID 需要软件的支持。vista, CentOS/Redhat 5.1等版本已经内置支持。其他系统需要安装驱动程序。
如果客户没有最新的XP光盘(已集成SATA AHCI驱动), 但是却想使用硬盘AHCI的功能怎么办?
support1.ap.dell.com/cn/zh/forum/thread.asp
J2EE - Ioc模式(又称DI:Dependency Injection 依赖注射)
分离关注( Separation of Concerns : SOC)是Ioc模式和AOP产生最原始动力,通过功能分解可得到关注点,这些关注可以是 组件Components, 方面Aspects或服务Services。
从GoF设计模式中,我们已经习惯一种思维编程方式:Interface Driven Design 接口驱动,接口驱动有很多好处,可以提供不同灵活的子类实现,增加代码稳定和健壮性等等,但是接口一定是需要实现的,也就是如下语句迟早要执行:
AInterface a = new AInterfaceImp();
AInterfaceImp是接口AInterface的一个子类,Ioc模式可以延缓接口的实现,根据需要实现,有个比喻:接口如同空的模型套,在必要时,需要向模型套注射石膏,这样才能成为一个模型实体,因此,我们将人为控制接口的实现成为“注射”。
Ioc英文为 Inversion of Control,即反转模式,这里有著名的好莱坞理论:你呆着别动,到时我会找你。后被Martin Fowler改名为 Dependency Injection 依赖注射,也就是将类之间的关系通过第三方进行注射,不需要类自己去解决调用关系。
其实Ioc模式也是解决调用者和被调用者之间的一种关系,上述AInterface实现语句表明当前是在调用被调用者AInterfaceImp,由于 被调用者名称写入了调用者的代码中,这产生了一个接口实现的原罪:彼此联系,调用者和被调用者有紧密联系,在UML中是用依赖 Dependency 表示。
但是这种依赖在分离关注的思维下是不可忍耐的,必须切割,实现调用者和被调用者解耦,新的Ioc模式 Dependency Injection 模式由此产生了, Dependency Injection模式是依赖注射的意思,也就是将依赖先剥离,然后在适当时候再注射进入。
Ioc模式(Dependency Injection模式)有三种:
| 第一种类型 | 从JNDI或ServiceManager等获得被调用者,这里类似ServiceLocator模式。 | 1. EJB/J2EE 2. Avalon(Apache的一个复杂使用不多的项目) |
| 第二种类型 | 使用JavaBeans的setter方法 | 1. Spring Framework, 2. WebWork/XWork |
| 第三种类型 | 在构造方法中实现依赖 | 1. PicoContainer, 2. HiveMind |
有过EJB开发经验的人都知道,每个EJB的调用都需要通过JNDI寻找到工厂性质的Home接口,在我的教程EJB是什么章节中,我也是从依赖和工厂模式角度来阐述EJB的使用。
在通常传统情况下,为了实现调用者和被调用者解耦,分离,一般是通过工厂模式实现的,下面将通过比较工厂模式和Ioc模式不同,加深理解Ioc模式。
工厂模式和Ioc
假设有两个类B 和 C:B作为调用者,C是被调用者,在B代码中存在对C的调用:
public class B{ |
实现comp实例有两种途径:单态工厂模式和Ioc。
工厂模式实现如下:
public class B{ public B(){ } |
特点:
- 每次运行时,MyFactory可根据配置文件XML中定义的C子类实现,通过createInstanceOfC()生成C的具体实例。
使用Ioc依赖性注射( Dependency Injection )实现Picocontainer如下,B类如同通常POJO类,如下:
public class B{ |
假设C接口/类有有一个具体实现CImp类。当客户端调用B时,使用下列代码:
public class client{ |
因此,当客户端调用B时,分别使用工厂模式和Ioc有不同的特点和区别:
主要区别体现在B类的代码,如果使用Ioc,在B类代码中将不需要嵌入任何工厂模式等的代码,因为这些工厂模式其实还是与C有些间接的联系,这样,使用Ioc彻底解耦了B和C之间的联系。
使用Ioc带来的代价是:需要在客户端或其它某处进行B和C之间联系的组装。
所以,Ioc并没有消除B和C之间这样的联系,只是转移了这种联系。
这种联系转移实际也是一种分离关注,它的影响巨大,它提供了AOP实现的可能。
Ioc和AOP
AOP我们已经知道是一种面向切面的编程方式,由于Ioc解放自由了B类,而且可以向B类实现注射C类具体实现,如果把B类想像成运行时的横向动作,无疑注入C类子类就是AOP中的一种Advice,如下图:
通过下列代码说明如何使用Picocontainer实现AOP,该例程主要实现是记录logger功能,通过Picocontainer可以使用简单一行,使所有的应用类的记录功能激活。
首先编制一个记录接口:
public interface Logging { public void enableLogging(Log log); } |
有一个LogSwitcher类,主要用来激活具体应用中的记录功能:
| import org.apache.commons.logging.Log; public class LogSwitcher { protected Log m_log; public void enableLogging(Log log) { m_log = log; m_log.info("Logging Enabled"); } } |
一般的普通应用JavaBeans都可以继承这个类,假设PicoUserManager是一个用户管理类,代码如下:
| public class PicoUserManager extends LogSwitcher { ..... //用户管理功能 ..... //业务功能 ..... //业务功能 |
注意LogSwitcher中Log实例是由外界赋予的,也就是说即将被外界注射进入,下面看看使用Picocontainer是如何注射Log的具体实例的。
Logging logging = (Logging) container.getComponentMulticaster(); |
由上代码可见,通过使用简单一行logging.enableLogging()方法使所有的应用类的记录功能激活。这是不是类似AOP的advice实现?
总之,使用Ioc模式,可以不管将来具体实现,完全在一个抽象层次进行描述和技术架构,因此,Ioc模式可以为容器、框架之类的软件实现提供了具体的实现手段,属于架构技术中一种重要的模式应用。J道的Jdon框架使用了Ioc模式,JiveJdon3.0是一个IOC/DI成熟应用。
DW - ETL的主要步骤
zt: ETL的主要步骤
下面是本人对ETL的几个重要步骤理解,和大家分享!
一、ODS区的数据采集: 最主要作用为了尽量减少对业务系统的影响。表结构可以不必和DW一致。根据具体业务需求和数据量情况,将数据源的数据放入ODS有各种不同的方法,比如Oracle的数据库链路,表复制,SQL*LOADER,Teradata的Fastload,Sysbase的BCP等等。
需要解决的问题包括:
a、数据的时间差异性问题
在抽取旧有数据时,要将不同时期的数据定义统一,较早的数据不够完整或不符合新系统的数据规范,一般可以根据规则,在存入中转区的过程中予以更新或补充。
b、数据的平台多样性问题
在抽取旧有数据时,大部分数据都可采用表复制方式直接导入数据中转区集中,再做处理,但有部分数据可能需要转换成文本文件或使用第三方工具如Informatica等装载入数据中转区。这部分数据主要是与数据中转区数据库平台不一致的数据库数据,或非存储于数据库内的文本、excel等数据。
c 、数据的不稳定性问题
对于重要信息的完整历史变更记录,在抽取时可以根据各时期的历史信息,在抽取需要信息等基本属性的旧有数据时,要与相应时段的信息关联得到真实的历史属性。
d 、数据的依赖性问题
旧有业务系统的数据关联一般已有约束保证,代码表和参照表等数据也比较准确,但仍有少量数据不完整,对这部分数据,需根据地税的需求采取清洗策略,保证数据仓库各事实表和维表之间的关联完整有效。
数据仓库各事实表和维表的初始装载顺序有先后关系,要有一个集中的数据装载任务顺序方案,确保初始数据装载的准确。这可以通过操作系统或第三方工具的任务调度机制来保证。
二、数据转换、清洗:
将ODS中的数据,按照数据仓库中数据存储结构进行合理的转换,转换步骤一般还要包含数据清洗的过程。数据清洗主要是针对源数据库中出现二义性、重复、不完整、违反业务或逻辑规则等问题的数据数据进行统一的处理,一般包括如:NULL值处理,日期格式转换,数据类型转换等等。在清洗之前需要进行数据质量分析,以找出存在问题的数据,否则数据清洗将无从谈起。数据装载是通过装载工具或自行编写的SQL程序将抽取、转换后的结果数据加载到目标数据库中。
数据质量问题具体表现在以下几个方面:
a、正确性(Accuracy):数据是否正确的表示了现实或可证实的来源?
b、完整性(Integrity):数据之间的参照完整性是否存在或一致?
c、一致性(Consistency):数据是否被一致的定义或理解?
d、完备性(Completeness):所有需要的数据都存在吗?
e、有效性(Validity):数据是否在企业定义的可接受的范围之内?
f、时效性(Timeliness):数据在需要的时侯是有效的吗?
g、可获取性(Accessibility):数据是否易于获取、易于理解和易于使用?
以下综合说明数据仓库中数据质量要求,包括格式、完整性要求。
a、业务描述统一,对数据模型的不同版本融合、映射为唯一版本。包括:
1、在业务逻辑没有变化的前提下,旧的业务数据映射在新模型上。
2、 遗留系统的人事信息、考核相关信息与业务系统、行政其他模块要一致。
b、信息描述规范、完整。
1、不存在格式违规
数据类型不存在潜在错误。
2 、参照完整性未被破坏
数据不会找不到参照。
3 、不存在交叉系统匹配违规,数据被很好集成
相同的数据存在于多个系统中,数据之间要匹配。
4 、数据在内部一致
同样的纪录字段在同一个表中重复出现,不能有差别。
以下是对主要数据质量问题的清洗策略:
| 主要问题 | 表现形式 | 产生原因 |
清洗策略 |
| 数据完整性问题 | 大量的空值字段的出现 | 原OLTP系统中对很多字段没有做非空限制 | 1. 交由OLTP系统重新录入, 补齐 2. 在数据仓库对应的维表中建立一个新的字段, 将这些空值字段的值统一的赋值 |
| 超出字典表范围 | 填写这些值的时候是直接让用户填写而非下拉框选择 | 1. 交由OLTP系统重新录入, 补齐 2. 在数据仓库对应的维表中建立一个新的字段, 将这些空值字段的值统一的赋值 | |
| 数据一致性问题 | 一个特定的字段在不同的表中内容不同 | 录入, 同步的问题 | 1. 选取最可靠的表中的字段为确定值 |
| 应该成为主键的值不唯一 | 原OLTP系统中未建立有效的主键关系 | 1. 消除错误, 重复的主键 |
三、数据加载:
将转换和清洗完的数据按照数据仓库的结构进行数据加载。需要考虑初始数据装载、数据刷新、加载顺序等等问题。
a、针对数据现状,初始导入有这样一些问题需要考虑:
1、如何解决时间差异性?
2、如何解决平台差异性?
3、如何适应数据的不稳定性?
4、如何解决数据依赖性?
b、数据刷新的策略要根据业务需求和应用系统的承受能力和数据情况决定。主要有这样一些问题需要考虑:1、如何解决时间差异性?
2、如何适应数据的不稳定性?
3、如何解决平台差异性?
4、如何解决数据依赖性?
5、如何减少对业务系统的影响?
c、不同的刷新任务类型,对业务系统的影响不同,刷新任务有以下种归类特性:
1、刷新频率:
实时刷新、每数小时、每日、每周、每月、不定期手动刷新。
2、刷新方式:
数据库表复制、文本文件ftp再装载、物化视图、数据库trigger。
3、数据加工方式:
简单插入更新、增加计算项字段、多表关联更新、汇总、多表关联汇总计算。
并可针对各种异常情况做处理:回滚,重新装载,断点重新装载等等,还可在任务完成后(或失败后)将日志以Email方式发给数据仓库管理人员。
四、汇总层、CUBE加载:
ODS加载进入数据仓库的数据只是底层详细层数据,还需按定义的汇总规则进行汇总,生成数据集市用的汇总表或CUBE。ETL流程是指完成每个维表数据及事实表数据导入的顺序, 其包括两个部分, 初始导入数据时的ETL流程, 及增量导入时的ETL流程。
初始导入数据时的ETL流程
第一步: 自动生成维的数据装载
自动生成维一般来说就是日期,年度月份,年度等时间类维度(年度月份,年度其实都是日期维的一个层次,但某些事实表中没有日期信息,只有月份信息,所以需额外建立此二维度),几乎数据仓库中每个数据模型都需使用时间类维度,在加载其它维度和事实之前,需要先将时间维度生成出来。
第二步: 手工维护维度装载
实际数据仓库开发中,很可能会有些维度的数据在业务系统中无发得到,典型的是一些外部信息指表的类型代码,是由数据仓库开发人员设计的。所以需要手工方式建立这些信息,然后导入数据仓库。
第三步: 缓慢变化维表数据装载
这些维度可以从业务系统中找到来源,但变化比较缓慢。对于初始装载时,需要考虑对缓慢变化维的处理方式要和增量刷新方式一致。
在装载事实表数据之前,需要先装载这些维表。需要注意的是,有些维本身就是事实表,其所依赖的维必须先装载完成。
第四步: 事实表数据装载
然后是初始装载所有的事实表数据。事实表之间也有依赖关系,某些事实表需在其他事实表装载之前装载。(如果ETL程序已保障了数据的完整性,也可以在将关联约束禁用的情况下不考虑先后顺序,但一般不建议)。
第五步:聚合表初始生成
许多数据仓库的前端应用,并非直接使用主题星型模型中的事实表数据,而是聚合表中汇总,运算好的数据。(Oracle OLAP Service所建立的ROLAP 和数据集市实际上也是使用一系列的经过大量预先计算得到的聚合表)
增量导入
第一步: 缓慢变化维表数据装载
每天将所有变化过的维度信息刷新到数据仓库中,维表数据的刷新必须现于事实表。
第二步: 事实表数据装载阶段
每天新增事实数据的导入,如同初始化导入一样,需要考虑任务之间的先后顺序。
第三步: 数据汇总和聚合
根据设定的聚合规则和时间段对数据进行聚合。
第四步: 作业调度和异常情况处理
五、任务调度策略
驱动策略
前导Job驱动:只有满足另外一个JOB成功后,自己才运行。文件驱动:当下传的文件到达,并经过检验准确后JOB才运行。时间驱动:当到达某个时点时,Job便开始运行。事件驱动:如人工参与,导致JOB执行。
通知设计:重要信息(成功/失败)的通知
1、成功退出
分段提交方式,当分段提交的当次任务都正确完成,即Job运行状态临时表中登记的作业状态全部为完成时,退出ETL调度。
自动提交方式,当当期所有的任务都正确完成,即Job运行状态表中登记的作业状态全部为完成时,退出ETL调度。
2、失败退出
关键作业异常,关键作业运行异常时,影响剩下的作业不能运行时,则退出ETL调度。
超过ETL时限,当超过预先设定的ETL?时限时,退出ETL调度。
数据库异常,当不能正常操作数据库时,退出ETL调度。
操作系统异常,当发生操作系统异常,导致程序不能正常运行,如文件系统异常导致读写文件错时,需要退出ETL调度。
3、手工退出,需要人为干预ETL调度的时候,能以手工操作的方式退出ETL调度。作者:
Keith
DW - Introducing Oracle Data Integrator Enterprise Edition
Introducing Oracle Data Integrator Enterprise Edition
By dain.hansen on January 30, 2009 12:19 PM
Oracle has unveiled that it will now include both Oracle Data Integrator and Oracle Warehouse Builder Enterprise ETL, formerly an add-on option to Oracle Database, as the two components of Oracle Data Integrator Enterprise Edition (ODI-EE). Going forward, these products will merge into a single unified data integration technology platform. This strategy fully preserves any existing development investments of all Oracle data integration customers and will provide a seamless, easy upgrade path from the current components to the unified platform. Customers can safely choose either component as the basis for implementations today. More information is available on this Oracle Data Integration Statement of Direction.
You can continue to get fantastic amounts of detailed technical product information about either component of ODI-EE on our OTN pages: Oracle Warehouse Builder Enterprise ETL and here for more information on the Oracle Data Integrator.
I also encourage you to attend an upcoming webinar on February 9th, 9AM PST. Listen in on the cost savings benefits of Data Integration and real-world examples of Oracle Data Integrator Enterprise Edition in action. Register now for this upcoming webinar, tell us what you're doing with Oracle Data Integrator Enterprise Edition and participate in the conversation with us.
Recording to the webinar is now available here.
2009年3月9日星期一
Test Tech - 软件测试常见模型-V,W,H,X
软件测试常见模型-V,W,H,X
V模型
在V模型中,测试过程被加在开发过程的后半部分,如下图所示:
单元测试所检测代码的开发是否符合详细设计的要求。集成测试所检测此前测试过的各组成部分是否能完好地结合到一起。系统测试所检测已集成在一起的产品是否符合系统规格说明书的要求。而验收测试则检测产品是否符合最终用户的需求。
对于测试设计,显而易见的是,V模型的用户往往会把执行测试与测试设计分开对待。在开发文档准备就绪后,就可以开始进行相关的测试设计。如下图所示,相应的测试设计覆盖在了相关的开发过程之上:
将测试设计覆盖了开发过程后的V模型
V模型有着很吸引人的对称外形,并且把很多人都带入了歧途。本文将集中讨论它在单元测试和集成测试中引起的问题。
为了说明的方便,这里专门制作了以下图片,图中包括一个单独的单元,以及一个单元组,称之为子系统(subsystem)。
一个假想的子系统
对于一个单元应该多大才最为合适的问题,已经有过很多的讨论,究竟一个单元仅仅是一个函数,一个类,还是相关的类的集合?这些讨论并不影响我在这里所要阐述的观点。我们权且认为一个单元就是一个最小程度的代码块,开发人员可以对进行独立地讨论。
V模型认为人们首先应该对每一个单元进行测试。当子系统中所有的单元都已经测试完毕,它们将被集中到一起进行测试,以验证它们是否可以构成一个可运行的整体。
那么,如何针对单元进行测试呢?我们会查看在详细设计中对接口的定义,或者查看源代码,或者同时对两者进行查看,找出符合某些测试设计中的有关准则的输入数据来进行输入,然后检查结果,看其是否正确。由于各单元一般来说不能独立地运行,所以我们不得不另外设计桩模块(Stub)和驱动模块(Driver),如下图所示。
单元及其外部的驱动模块和桩模块
图中的箭头代表了测试的执行轨迹。这就是大多数人所说的“单元测试”。这样的方法有时候是一种不好的方法。
同样的输入也可以有同一子系统中的其它单元来提供,这样,其它的单元既扮演了桩模块,又扮演了驱动模块。如下图所示:
子系统内部各单元间的测试执行轨迹
到 底选择哪一种方法,这需要一种折衷和权衡。设计桩模块和驱动模块要付出多少代价?这些模块如何进行维护?子系统是否会由此而掩盖了一些故障?在整个子系统 范围内进行排错的困难程度有多大?如果我们的测试直到集成测试时才真正开始,那么一些bug可能较晚才被发现。由此造成的代价同设计桩模块和驱动模块的代 价如何比较?
V模型没有去考虑这些问题,当单元开发完成后就执行单元测试,而当自系统被集中在一起后就执行集成测试,仅此而已。令我奇怪和沮丧的是,人们从不去做一些权衡,他们已经受制于他们的模型。
因此,一个有用的模型应该允许测试人员考虑节省并推迟测试的可能性。
一 个测试,如果要发现一个特定的单元中的bug,最好是在该单元保持独立的情况下执行,并且在其外部辅以特定的桩模块和驱动模块。而另一种方法则是让它作为 子系统的一部分来进行测试,该测试的设计主要是为了发现集成的问题。由于一个子系统本身也需要桩模块和驱动模块来模拟该子系统和其它子系统的联系,因此, 单元测试和集成测试可能被推迟到至少整个系统已经部分集成的时候。在这种情况下,测试者可能通过产品的外部接口同时进行单元测试、集成测试和系统测试,同样的,其主要目的还是为了减少总体生命周期的成本,对测试成本和延期进行测试及由此造成延期发现bug的代价成本进行权衡。据此而言,"单元测试"、"集成测试"和"系统测试"的区别已经大大削弱了。其结果可参考下图:
新的方法:在部分阶段延迟进行单元测试和集成测试
在上图右边的方块中,最好要改成为“执行某些适当的测试并得到相应的结果”。
图 中的左边会怎样?考虑一下系统测试设计,它的主要根据和信息来源是是规格说明。假设你知道有2个单元处在一个特定的子系统中,它们在运行时相互联系,并且 要执行规格说明中的一个特定的声明。为什么不在该子系统被集成时立即对此规格说明中的声明进行测试,就象是在设计完成后立即开始测试的设计一样呢?如果该 声明的执行和子系统外的子系统没有任何关系,为什么还要等到整个系统完成以后再测试呢?难道越早发现bug成本越低不对吗?
在上一张图片中,我们用了向上指的箭头(更有效,但在时间上有延迟)。这里还可以把箭头往下指(在时间上提前):
新的方法:在不同阶段上提前进行测试设计
在这种情况下,左边的方块中最好被标记为:“在当前信息条件和情况下可以做的任何测试设计”。这样,当测试设计得自于系统中某一个组件的描述时,模型必须允许这样的测试在组件被装配之前被执行。我必须承认我的图片非常难看,这些箭头指得到处都是,对此我有2点说明:
1.我们所讨论的事情不是创造美,而是想要发现尽可能多的严重错误,同时尽可能地降低成本。
2.难看的部分原因也是因为必须按照某些次序来执行的结果,亦即开发人员先提供系统描述文档,然后测试和这些文档进行关联。这些文档就象是坚实的老橡树,而测试设计则象是细细的枝条缠绕在树上。如果我们采用不同的原理来进行组织,图片可能就会变得好看些。但复杂性仍不可避免,因为我们要讨论的问题本身就很复杂。
V模型失败的原因是它把系统开发过程划分为具有固定边界的不同阶段,这使得人们很难跨过这些边界来采集测试所需要的信息。有些测试应该执行得更早些,有些测试则需要延后进行。而且,它也阻碍了你从系统描述的不同阶段中取得信息进行综合。例如,某些组织有时执行这样的做法,即对完成的工作进 行签署。这样的规定也扩展到系统测试的设计。签署表示已经过评估,该测试设计工作已经完成,除非对应的设计文档改变,否则就不会被修订。如果同这些测试相 关的信息后来被重新挖掘和认识,例如,架构设计表明有些测试是多余的,或者,详细设计表明有一个内部的边界可以和已存在的系统测试组合在一起进行测试的 话,那么实际上还需要继续调整原来的系统测试设计。
因此,模型必须允许利用不同来源的综合信息进行个别的测试设计。另外,模型还应该允许在新的信息来源出现后重新进行测试的设计。
上次说到V模型的局限性在于没有明确地说明早期的测试,无法体现“尽早地和不断地进行软件测试”的原则。在V模型中增加软件各开发阶段应同步进行的测试,演化为W模型。在模型中不难看出,开发是“V”,测试是与此并行的“V”。基于“尽早地和不断地进行软件测试”的原则,在软件的需求和设计阶段的测试活动应遵循IEEE1012-1998《软件验证与确认(V&V)》的原则。
V模型
由Evolutif公司提出,相对于V模型,W模型更科学。W模型是V模型的发展,强调的是测试伴随着整个软件开发周期,而且测试的对象不仅仅是程序,需求、功能和设计同样要测试。测试与开发是同步进行的,从而有利于尽早地发现问题。
W模型也有局限性。W模型和V模型都把软件的开发视为需求、设计、编码等一系列串行的活动,无法支持迭代、自发性以及变更调整。
上次提到两个测试过程模型,都没有很好地体现测试流程的完整性。为了解决以上问题,提出了H模型。它将测试活动完全独立出来,形成一个完全独立的流程,将测试准备活动和测试执行活动清晰地体现出来。
软件测试H模型
示意图演示了在整个生产周期中某个层次上的一次测试“微循环”。图中的其他流程图可以是任意开发流程。例如,设计流程和编码流程。也可以是其他非开发流程,例如,SQA流程,甚至是测试流程本身。只要测试条件成熟了,测试准备活动完成了,测试执行活动就可以进行了。
H模型揭示了:
·
软件测试不仅仅指测试的执行,还包括很多其他的活动
·
软件测试是一个独立的流程,贯穿产品整个生命周期,与其他流程并发地进行
·
软件测试要尽早准备,尽早执行
·
软件测试是根据被测物的不同而分层次进行的。不同层次的测试活动可以是按照某个次序先后进行的,但也可能是反复的
在H模型中,软件测试模型是一个独立的流程,贯穿于整个产品周期,与其他流程并发地进行。当某个测试时间点就绪时,软件测试即从测试准备阶段进入测试执行阶段。
X模型的基本思想是由Marick提出的,但首先是Marick不建议要建立一个替代模型。Robin F·Goldsmith引用了一些Marick的想法,并重新经过组织,形成了“X模型”。其实并不是为了和V模型相对应而选择这样的名字,而是由于其它一些原因:X通常代表未知,而Marick也认为他的观点并不足以支撑一个模型的完整描述,但其中已经有一个模型所需要的一些主要内容,其中也包括了象探索性测试(exploratorytesting)这样的亮点。
X模型示意图
Marick对V模型的最主要批评是V模型无法引导项目的全部过程。他认为一个模型必须能处理开发的所有方面,包括交接,频繁重复的集成,以及需求文档的缺乏等等。
Marick认为一个模型不应该规定那些和当前所公认的实践不一致的行为。X模型的左边描述的是针对单独程序片段所进行的相互分离的编码和测试,此后将进行频繁的交接,通过集成最终合成为可执行的程序。(右上半部分),这些可执行程序还需要进行测试。已通过集成测试的成品可以进行封版并提交给用户,也可以作为更大规模和范围内集成的一部分。多根并行的曲线表示变更可以在各个部分发生。
由上图中可见,X模型还定位了探索性测试(右下方)。这是不进行事先计划的特殊类型的测试,诸如“我这么测一下结果会怎么样?”,这一方式往往能帮助有经验的测试人员在测试计划之外发现更多的软件错误。
然而,关注于这样的低级别的行为可能会引起不同的议论。一个模型和一个单独的项目计划有所不同。模型不应该描述每个项目的具体细节,模型应该对项目进行指导和支持。当然,代码的交接也可以简单地认为是一种集成的形式。而V模型也并没有限制各种创建周期的发生次数。
Marick和Graham都一致认同,应该在执行测试之前进行测试设计。Marick建议:“在你掌握相关知识时进行设计,在你手头有交付内容时进行测试。”X模型包含了测试设计的步骤,就象使用不同的测试工具所要包含的步骤一样,而V模型没有这么做。但是,Marick的例子提示,X模型在这层意义上看也并不是一个真的模型,取而代之的是,应该允许在任何时候选择使用测试设计步骤。
Marick对V模型提出质疑,也因为V模型基于一套必须按照一定顺序严格排列的开发步骤,而这很可能并没有反映实际的实践过程。
尽管很多项目缺乏足够的需求,V模型还是从需求处理开始。V模型提示我们要对各开发阶段中已经得到的内容进行测试,但它没有规定我们要取得多少内容。如果没有任何的需求资料,开发人员知道他们要做什么吗?我主张在X模型和其它模型中都需要足够的需求并至少进行一次发布。虽然在没有模型的情况下也必须正常工作,但一个有效的模型,可以鼓励很多好的实践方法的采用。因此,V模型的一个强项是它明确的需求角色的确认,而X模型没有这么做,这大概是X模型的一个不足之处。
Marick也质疑了单元测试和集成测试的区别,因为在某些场合人们可能会跳过单元测试而热衷于直接进行集成测试。Marick担心人们盲目地跟随“学院派的V模型”,按照模型所指导的步骤进行工作,而实际上某些做法并不切合实用。我已经尽自己的努力把Marick的关于需要很多具有可伸缩性的行为的期望结合进了X模型,这样,X模型并不要求在进行作为创建可执行程序(图中右上方)的一个组成部分的集成测试之前,对每一个程序片段都进行单元测试(图中左侧的行为)。但X模型没能提供是否要跳过单元测试的判断准则。
X模型填补了V模型和W模型的缺陷,并可为测试人员和开发人员带来明显的帮助。
这篇文章详细介绍了测试里面所涉及到的模型,并加入自己对模型的看法,解释了模型的优缺点
