关于作者

用户名:lu632
笔名:lu632
地区:
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



访问统计:
文章个数:11
评论个数:9
留言条数:0




Powered by BlogDriver 2.1

lu632的博客

 

欢迎访问lu632的博客

文章

会话
会话:
在一个RDBMS服务器和一个访问它的用户间的通信期间内发生的一切事情都是发生在一个会
话(session)环境中。当一个客户端应用程序建立了一个到RDBMS服务器的连接时,就说他打开
了一个会话。这个会话就成为了这个应用程序的专有通信通道。这个应用程序的用户可以改变
这个会话环境中的某些参数(如默认的语言或日期格式),这些设置只会影响这个会话环境,
且进在这个会话期间保持可用。
日期显示格式的改变:
SQL> select sysdate from dual;
SYSDATE
--------
2005/6/1
SQL> alter session set nls_date_format = 'dd-mon-yyyy hh24:mi:ss';
セッションが変更されました。
SQL> select sysdate from dual;
SYSDATE
--------------------
2005/6/1 9:18
SQL> alter session set nls_date_format = 'dd-mon-yy';
セッションが変更されました。
SQL> select sysdate from dual;
SYSDATE
---------
1-Jun-05
设置SQL*Plus会话参数:
SET选项:说明:
AUTO[COMMIT] {ON | OFF | IMMEDIATE}这个命令为数据库中要进行的数据改变设置
默认的行为。把它设置为OFF(默认值)要求
用户手工提交改变,发出COMMIT语句。
[LIN] ESIZE n这个选项设置SQL*Plus可以在一行中显示的
最大字符数;范围从1到由系统决定的最大值。
NULL <text>这个选项设置当包含NULL的数据被返回时
希望显示的文本。
[PAGES] IZE n为显示一个查询的结果设置每页最大的行数。
[WRA] P(WRA) {ON | OFF}这个命令句定了输出数据如何被显示:ON使
得一个必当前行设置更长的返回行可以被换
行到下一行,OFF会把它截取到行的尺寸。
以上可用下面语句在SQL*Plus环境中设置:
SET <OPTION> [<VALUE>]
对于所有待决的事务,当情况为自愿终止时,一个隐式提交将被发出,如果这个会话是异常终止
的话,则会回滚。当一个客户端应用程序突然终止,而没有能力终止它打开到RDBMS服务器的
会话时,孤立会话便会出现。如果这个会话是活动的(即RDBMS正在处理一些命令),则它将自动
探测到客户的缺席并终止这个会话。如果这个会话时不活动的,正在等待來自客戶的命令,則這
樣的一個會話会继续对服务器的使用,因此应该被清除,通常这种工作某一时间间隔后被自动
执行,也可由DBA手工解除。

- 作者: lu632 2005年06月2日, 星期四 12:35  回复(0) |  引用(0) 加入博采

约束
引用完整性约束可选子句:
SQL99在FOREIGN KEY和REFERENCES约束的创建上采用了一个可选子句,指定了如果一行有
一个引用关系,而被引用的行被从父表中删除或被引用的行为发生了某些改变,在这种情况下,
这个行为会发生什么事情。Oracle没有on update子句。
[on delete {no action | cascade  | set null } ]
[on update {no action | cascade  | set null } ]
no action是默认行为,意味着如果试图删除被其他表引用的行(或更新主键值),
则会产生一个错误。
cascade表现为当改变在父行或父表上发生时,同样的改变也将在外键上发生,如果父行被
删除了,则所有引用它的子行也将被删除。如果附表的逐渐被更新了,则所有引用
它的子行的外键也将被同样的值更新。
set null意味着如果父行被删除或它的主键被改变,则所有子表的引用外键值键被设置为null。
set default类似于set null,但子表的列时被设置为它们的默认值,假定列的默认值是存在的。
可延迟约束:
SQL> create table ex(
  2  id number not null,
  3  name varchar2(10) not null,
  4  sex char(1) default 'm',check(sex in('m','f')) deferrable initially deferred
  5  );
表が作成されました。
SQL> insert into ex values(101,'lili','a');
1行が作成されました。
SQL> commit;
commit
*
行1でエラーが発生しました。:
ORA-02091: トランザクションがロールバックされました。
ORA-02290: チェック制約(FAM03.SYS_C001444386)に違反しました
SQL> update ex
  2  set sex = 'f'
  3  where sex = 'a';
0行が更新されました。
SQL> select * from ex;
レコードが選択されませんでした。
SQL> insert into ex values(101,'lili','a');
1行が作成されました。
SQL> update ex
  2  set sex = 'f'
  3  where sex = 'a';
1行が更新されました。
SQL> commit;
コミットが完了しました。
SQL> select * from ex;
        ID NAME       S
---------- ---------- -
       101 lili       f

- 作者: lu632 2005年06月2日, 星期四 12:33  回复(0) |  引用(0) 加入博采

黑盒测试的测试用例设计方法

黑盒测试的测试用例设计方法

黑盒测试的测试用例设计方法
·等价类划分方法
·边界值分析方法
·错误推测方法
·因果图方法
·判定表驱动分析方法
·正交实验设计方法
·功能图分析方法
等价类划分:
是把所有可能的输入数据,即程序的输入域划分成若干部分(子集),然后从每一个子集中选取少数具有代表性的数据作为测试用例.该方法是一种重要的,常用的黑盒测试用例设计方法
.
1)
划分等价类: 等价类是指某个输入域的子集合.在该子集合中,各个输入数据对于揭露程序中的错误都是等效的.并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据.取得较好的测试结果.等价类划分可有两种不同的情况:有效等价类和无效等价类
.
有效等价类:是指对于程序的规格说明来说是合理的,有意义的输入数据构成的集合.利用有效等价类可检验程序是否实现了规格说明中所规定的功能和性能
.
无效等价类:与有效等价类的定义恰巧相反
.
设计测试用例时,要同时考虑这两种等价类.因为,软件不仅要能接收合理的数据,也要能经受意外的考验.这样的测试才能确保软件具有更高的可靠性.

2)划分等价类的方法:下面给出六条确定等价类的原则.
①在输入条件规定了取值范围或值的个数的情况下,则可以确立一个有效等价类和两个无效等价类
.
②在输入条件规定了输入值的集合或者规定了“必须如何”的条件的情况下,可确立一个有效等价类和一个无效等价类
.
③在输入条件是一个布尔量的情况下,可确定一个有效等价类和一个无效等价类
.
④在规定了输入数据的一组值(假定n个),并且程序要对每一个输入值分别处理的情况下,可确立n个有效等价类和一个无效等价类
.
⑤在规定了输入数据必须遵守的规则的情况下,可确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)
.
⑥在确知已划分的等价类中各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步的划分为更小的等价类.

3)设计测试用例:在确立了等价类后,可建立等价类表,列出所有划分出的等价类:
输入条件 有效等价类 无效等价类

... ... ...
... ... ...
然后从划分出的等价类中按以下三个原则设计测试用例:
①为每一个等价类规定一个唯一的编号
.
②设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖地有效等价类,重复这一步.直到所有的有效等价类都被覆盖为止
.
③设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步.直到所有的无效等价类都被覆盖为止
.
边界值分析法

边界值分析方法是对等价类划分方法的补充.
1)边界值分析方法的考虑
:
长期的测试工作经验告诉我们,大量的错误是发生在输入或输出范围的边界上,而不是发生在输入输出范围的内部.因此针对各种边界情况设计测试用例,可以查出更多的错误
.
使用边界值分析方法设计测试用例,首先应确定边界情况.通常输入和输出等价类的边界,就是应着重测试的边界情况.应当选取正好等于,刚刚大于或刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值作为测试数据
.
2)基于边界值分析方法选择测试用例的原则
:
1
)如果输入条件规定了值的范围,则应取刚达到这个范围的边界的值,以及刚刚超越这个范围边界的值作为测试输入数据
.
2
)如果输入条件规定了值的个数,则用最大个数,最小个数,比最小个数少一,比最大个数多一的数作为测试数据
.
3
)根据规格说明的每个输出条件,使用前面的原则1
.
4
)根据规格说明的每个输出条件,应用前面的原则2
.
5
)如果程序的规格说明给出的输入域或输出域是有序集合,则应选取集合的第一个元素和最后一个元素作为测试用例
.
6
)如果程序中使用了一个内部数据结构,则应当选择这个内部数据结构的边界上的值作为测试用例
.
7
)分析规格说明,找出其它可能的边界条件
.
错误推测法

错误推测法: 基于经验和直觉推测程序中所有可能存在的各种错误, 从而有针对性的设计测试用例的方法.
错误推测方法的基本思想: 列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据他们选择测试用例. 例如, 在单元测试时曾列出的许多在模块中常见的错误. 以前产品测试中曾经发现的错误等, 这些就是经验的总结. 还有, 输入数据和输出数据为0的情况. 输入表格为空格或输入表格只有一行. 这些都是容易发生错误的情况. 可选择这些情况下的例子作为测试用例
.
因果图方法

前面介绍的等价类划分方法和边界值分析方法,都是着重考虑输入条件,但未考虑输入条件之间的联系, 相互组合等. 考虑输入条件之间的相互组合,可能会产生一些新的情况. 但要检查输入条件的组合不是一件容易的事情, 即使把所有输入条件划分成等价类,他们之间的组合情况也相当多. 因此必须考虑采用一种适合于描述对于多种条件的组合,相应产生多个动作的形式来考虑设计测试用例. 这就需要利用因果图(逻辑模型).
因果图方法最终生成的就是判定表. 它适合于检查程序输入条件的各种组合情况
.
利用因果图生成测试用例的基本步骤
:
(1)
分析软件规格说明描述中, 那些是原因(即输入条件或输入条件的等价类),那些是结果(即输出条件), 并给每个原因和结果赋予一个标识符
.
(2)
分析软件规格说明描述中的语义.找出原因与结果之间, 原因与原因之间对应的关系. 根据这些关系,画出因果图
.
(3)
由于语法或环境限制, 有些原因与原因之间,原因与结果之间的组合情况不不可能出现. 为表明这些特殊情况, 在因果图上用一些记号表明约束或限制条件
.
(4)
把因果图转换为判定表
.
(5)
把判定表的每一列拿出来作为依据,设计测试用例
.
从因果图生成的测试用例(局部,组合关系下的)包括了所有输入数据的取TRUE与取FALSE的情况,构成的测试用例数目达到最少,且测试用例数目随输入数据数目的增加而线性地增加
.
前面因果图方法中已经用到了判定表.判定表(Decision Table)是分析和表达多逻辑条件下执行不同操作的情况下的工具.在程序设计发展的初期,判定表就已被当作编写程序的辅助工具了.由于它可以把复杂的逻辑关系和多种条件组合的情况表达得既具体又明确
.
判定表通常由四个部分组成
.
条件桩(Condition Stub:列出了问题得所有条件.通常认为列出得条件的次序无关紧要
.
动作桩(Action Stub:列出了问题规定可能采取的操作.这些操作的排列顺序没有约束
.
条件项(Condition Entry:列出针对它左列条件的取值.在所有可能情况下的真假值
.
动作项(Action Entry:列出在条件项的各种取值情况下应该采取的动作
.
规则:任何一个条件组合的特定取值及其相应要执行的操作.在判定表中贯穿条件项和动作项的一列就是一条规则.显然,判定表中列出多少组条件取值,也就有多少条规则,既条件项和动作项有多少列
.
判定表的建立步骤:(根据软件规格说明)

①确定规则的个数.假如有n个条件.每个条件有两个取值(0,1,故有 种规则.
②列出所有的条件桩和动作桩
.
③填入条件项
.
④填入动作项.等到初始判定表
.
⑤简化.合并相似规则(相同动作)
.
B. Beizer
指出了适合使用判定表设计测试用例的条件
:
①规格说明以判定表形式给出,或很容易转换成判定表
.
②条件的排列顺序不会也不影响执行哪些操作
.
③规则的排列顺序不会也不影响执行哪些操作
.
④每当某一规则的条件已经满足,并确定要执行的操作后,不必检验别的规则
.
⑤如果某一规则得到满足要执行多个操作,这些操作的执行顺序无关紧要.

 

- 作者: lu632 2005年06月2日, 星期四 12:31  回复(0) |  引用(0) 加入博采

数据库设计说明书

 

 

数据库设计说明书


1 引言
1
1编写目的
  说明编写这份数据库设计说明书的目的,指出预期的读者。
1
2背景
  说明:
  a.说明待开发的数据库的名称和使用此数据库的软件系统的名称;
  b.列出该软件系统开发项目的任务提出者、用户以及将安装该软件和这个数据库的计算站(中心)。
1
3定义
  列出本文件中用到的专门术语的定义、外文首字母组词的原词组。
1
4参考资料
  列出有关的参考资料:
  a.本项目的经核准的计划任务书或合同、上级机关批文;
  b.属于本项目的其他已发表的文件;
  c.本文件中各处引用到的文件资料,包括所要用到的软件开发标准。
  列出这些文件的标题、文件编号、发表日期和出版单位,说明能够取得这些文件的来源。
2 外部设计
2
1标识符和状态
  联系用途,详细说明用于唯一地标识该数据库的代码、名称或标识符,附加的描述性信息亦要给出。如果该数据库属于尚在实验中、尚在测试中或是暂时使用的,则要说明这一特点及其有效时间范围。
2
2使用它的程序
  列出将要使用或访问此数据库的所有应用程序,对于这些应用程序的每一个,给出它的名称和版本号。
2
3约定
  陈述一个程序员或一个系统分析员为了能使用此数据库而需要了解的建立标号、标识的约定,例如 用于标识数据库的不同版本的约定和用于标识库内各个文卷、、记录、数据项的命名约定等。
2
4专门指导
  向准备从事此数据库的生成、从事此数据库的测试、维护人员提供专门的指导,例如将被送入数据 库的数据的格式和标准、送入数据库的操作规程和步骤,用于产生、修改、更新或使用这些数据文卷的操 作指导。 如果这些指导的内容篇幅很长,列出可参阅的文件资料的名称和章条。
2
5支持软件
  简单介绍同此数据库直接有关的支持软件,如数据库管理系统、存储定位程序和用于装入、生成、修 改、更新数据库的程序等。说明这些软件的名称、版本号和主要功能特性,如所用数据模型的类型、允许 的数据容量等。列出这些支持软件的技术文件的标题、编号及来源。
3
 结构设计
3
1概念结构设计
  说明本数据库将反映的现实世界中的实体、属性和它们之间的关系等的原始数据形式,包括各数据项、记录、系、文卷的标识符、定义、类型、度量单位和值域,建立本数据库的每一幅用户视图。
3
2逻辑结构设计
  说明把上述原始数据进行分解、合并后重新组织起来的数据库全局逻辑结构,包括所确定的关键字和属性、重新确定的记录结构和文卷结构、所建立的各个文卷之间的相互关系,形成本数据库的数据库管理员视图。
3
3物理结构设计
  建立系统程序员视图,包括:
  a.数据在内存中的安排,包括对索引区、缓冲区的设计;
  b.所使用的外存设备及外存空间的组织,包括索引区、数据块的组织与划分;
  c.访问数据的方式方法。
4 运用设计
4
1数据字典设计
  对数据库设计中涉及到的各种项目,如数据项、记录、系、文卷、模式、子模式等一般要建立起数据字典,以说明它们的标识符、同义名及有关信息。在本节中要说明对此数据字典设计的基本考虑。
4
2安全保密设计
  说明在数据库的设计中,将如何通过区分不同的访问者、不同的访问类型和不同的数据对象,进行分别对待而获得的数据库安全保密的设计考虑。

 

 

- 作者: lu632 2005年06月2日, 星期四 12:29  回复(1) |  引用(0) 加入博采

软件需求说明书

 

 

软件需求说明书


  软件需求说明书的编制是为了使用户和软件开发者双方对该软件的初始规定有一个共同的理解, 使之成为整个开发工作的基础。编制软件需求说明书的内容要求如下:
1 引言
1
1编写目的
  说明编写这份软件需求说明书的目的,指出预期的读者。
1
2背景
  说明:
  a.待开发的软件系统的名称;
  b.本项目的任务提出者、开发者、用户及实现该软件的计算中心或计算机网络;
  C.该软件系统同其他系统或其他机构的基本的相互来往关系。
1
3定义
  列出本文件中用到的专门术语的定义和外文首字母组词的原词组。
1
4参考资料
  列出用得着的参考资料,如:
  a.本项目的经核准的计划任务书或合同、上级机关的批文;
  b.属于本项目的其他已发表的文件;
  c.本文件中各处引用的文件、资料、包括所要用到的软件开发标准。 列出这些文件资料的标题、文件编号、发表日期和出版单位,说明能够得到这些文件资料的来源。
2 任务概述
2
1目标
  叙述该项软件开发的意图、应用目标、作用范围以及其他应向读者说明的有关该软件开发的背景材料。解释被开发软件与其他有关软件之间的关系。如果本软件产品是一项独立的软件,而且全部内容自含,则说明这一点。如果所定义的产品是一个更大的系统的一个组成部分,则应说明本产品与该系统中其他各组成部分之间的关系,为此可使用一张方框图来说明该系统的组成和本产品同其他各部分的联系和接口。|
2
2用户的特点
  列出本软件的最终用户的特点,充分说明操作人员、维护人员的教育水平和技术专长,以及本软件的预期使甩频度。这些是软件设计工作的重要约束
2
3假定和约束
  列出进行本软件开发工作的假定和约束,例如经费限制、开发期限等。
3 需求规定
3
1对功能的规定
  用列表的方式(例如IPO表即输入、处理、输出表的形式),逐项定量和定性地叙述对软件所提出的功能要求,说明输入什么量、经怎样的处理、得到什么输出,说明软件应支持的终端数和应支持的并行操作的用户数。
3
2对性能的规定
3
21精度
  说明对该软件的输入、输出数据精度的要求,可能包括传输过程中的精度。
3
22时间特性要求
  说明对于该软件的时间特性要求,如对:
  a.响应时间;
  b.更新处理时间;
  c.数据的转换和传送时间;
  d.解题时间; 等的要求。
3
23灵活性
  说明对该软件的灵活性的要求,即当需求发生某些变化时,该软件对这些变化的适应能力,如:
  a.操作方式上的变化;
  b.运行环境的变化;
  c.同其他软件的接口的变化;
  d.精度和有效时限的变化;
  e.计划的变化或改进。
  对于为了提供这些灵活性而进行的专门设计的部分应该加以标明。
3
3输人输出要求
  解释各输入输出数据类型,并逐项说明其媒体、格式、数值范围、精度等。对软件的数据输出及必须标明的控制输出量进行解释并举例,包括对硬拷贝报告(正常结果输出、状态输出及异常输出)以及图形或显示报告的描述。
3
4数据管理能力要求
  说明需要管理的文卷和记录的个数、表和文卷的大小规模,要按可预见的增长对数据及其分量的存储要求作出估算。
3
5故障处理要求
  列出可能的软件、硬件故障以及对各项性能而言所产生的后果和对故障处理的要求。
3
6其他专门要求
  如用户单位对安全保密的要求,对使用方便的要求,对可维护性、可补充性、易读性、可靠性、运行环境可转换性的特殊要求等。
4
 运行环境规定
4
1设备
  列出运行该软件所需要的硬设备。说明其中的新型设备及其专门功能,包括:
  a.处理器型号及内存容量;
  b.外存容量、联机或脱机、媒体及其存储格式,设备的型号及数量;
  c.输入及输出设备的型号和数量,联机或脱机;
  d.数据通信设备的型号和数量;
  e.功能键及其他专用硬件
4
2支持软件
  列出支持软件,包括要用到的操作系统、编译(或汇编)程序、测试支持软件等。
4
3 接口
  说明该软件同其他软件之间的接口、数据通信协议等。
4
4控制
  说明控制该软件的运行的方法和控制信号,并说明这些控制信号的来源。

 

 

- 作者: lu632 2005年06月2日, 星期四 12:28  回复(2) |  引用(0) 加入博采

错误处理规范

错误处理规范

〇、概念澄清

概念

解释

错误

  • 是指:导致系统不能按照用户意图工作的一切原因、事件
  • 不是指:java.lang.Error及其子类

异常

  • 是指:特定编程语言、开发平台提供的一种错误表现机制
  • 不是指但包括:java.lang.Error及其子类,java.lang.Exception及其子类,System.Exception及其子类

一、整体规范

  1. 按照错误类型,通常的处理方式如下:

错误类型

范围

处理方式

操作员错误

与人机界面交互时不满足输入规则、输入范围等发生的错误

  • 校验用户输入
  • 提示正确规则
  • 强制其改正

运行时错误

与外部资源交互时发生的错误,如网络、文件系统、数据库、其它业务应用系统等

  • 记录并抛出异常
  • 其它详见“异常处理规范”

程序员错误

与客户模块交互时不满足前置条件后置条件发生的错误,如类库被其他程序员调用时参数超出范围等

  • 使用断言

  1. 按照调用类型,通常的处理方式如下:

调用类型

处理方式

同步调用

  • 对有能力处理的异常,捕获并处理之
  • 对原始信息过于技术化的异常,捕获并包装之,重新抛出
  • 在调用的中间层,对未知异常保持沉默
  • 在调用的最高层,必须捕获所有异常,避免本身进程或宿主进程崩溃
  • 其它详见“异常处理规范”

异步调用

  • 异步调用一般不应有任何返回值
  • 服务方最好以同样的方式返回正常信息和错误信息,即正常信息是通过通知的方式返回的话,错误信息也应该通过通知的方式返回;正常信息是通过主动查询得到的话,错误信息也应该通过主动查询得到

  1. 按照展现方式,通常的分类如下:

展现方式

涉及模块

界面提示

  • 只有表示层需要显示界面提示
  • 表示层必须捕获所有错误,避免本身进程或宿主进程崩溃

记录日志

  • 所有模块都应记录错误日志

二、异常处理规范

1.      原则

  • 异常应该是分层的
  • 异常应该集中处理

2.      异常定义

  • 每个模块应该有自己的应用程序异常类型层次,从本模块主动抛出的应用程序异常都应该属于该异常类型层次,客户代码可以只捕捉该层次的基类(?)
  • 应用程序的所有自定义异常都应该从开发平台提供的“应用程序异常基类”派生
  • 中间件等平台程序的运行时异常都应该从开发平台提供的“运行时异常基类”派生(?)
  • 中间件等平台程序的运行时错误都应该从开发平台提供的“错误基类”派生(?)

3.      异常捕获

  • 对有能力处理的异常,捕获并处理之
  • 在调用的中间层,对未知异常保持沉默
  • 在调用的最高层,必须捕获所有异常,避免本身进程或宿主进程崩溃
  • 记录捕获到的每个原始异常的信息

4.      异常抛出

  • 每个模块应使用本模块所能得知的最精确的错误原因报告异常信息
  • 如果有原始异常,在重新抛出的自定义异常中附加原始异常的信息

三、几点说明

1.      错误处理与日志系统

  • 错误处理不等同于日志系统,日志系统只是错误信息的一种记录手段
  • 错误信息的输出应全部调用日志系统来完成

2.      程序员错误与运行时错误

  • 接口函数的前置条件,应该是一种规范,是客户程序员必须遵守的约定;客户程序员违反了约定,程序将产生异常或不可预知的错误;对于这类约定,不应该需要有运行时的代码检查 ;比如如果你的接口函数的一个参数不能为null,而你在函数开始部分程序里写:

if(xxx == null){

    throw new someException();

}

你的代码实际上允许该参数为null,因为你对null的情况进行了运行时处理;尽管你在文档里声明该参数不能为null,但如果客户程序员遵守了约定,那么你这段检查代码就是冗余的

  • 当你对参数没有任何检查就进行了使用,而非法的参数值导致了错误,此时有两种情况: 如果你在接口函数说明里列出了参数不允许的非法取值,那么客户程序员应该修改程序避免传入非法值,该类错误称为程序员错误;如果你没有说明,那么你应该修改函数,处理非法参数
  • 不是所有的限制条件在文档里说明一下,就可以把责任扔给客户程序员了,有一些错误必须处理:特别是客户程序员不需要import你的package就可以和你的接口交互的情况,如socket服务器 ,你必须在socket服务程序内部检查所有接收到的数据,拒绝错误的请求,否则极易遭到攻击

3.      错误代码与异常

  • 不应该使用bool值来返回成功与否,bool返回值只应用在真正查询bool状态的操作中,如 bool IsDirty()bool hasNext()
  • 整形或bool型的错误代码返回值强迫客户程序员检查每一次调用,应用异常取代之

四、附录

A.     Anders HejlsbergC#异常设计

译者注:在写一段程序时,如果没有用try-catch捕捉异常或者显式的抛出异常,而希望程序自动抛出,一些语言的编译器不会允许编译通过,如Java就是这样。这就是Checked Exceptions最基本的意思。该特性的目的是保证程序的安全性和健壮性。Zee&Snakey(MVP)对此有一段很形象的话,可以参见http://www.blogcn.com/user2/zee/main.aspBruce Eckel 也有相关的一篇文章:Does Java need Checked Exceptions》,参见http://www.mindview.net/Etc/Discussions/CheckedExceptions

  • Checked Exceptions特性持保留态度

Bruce Eckel

C#没有Checked Exceptions,你是怎么决定是否在C#中放置这种特性的么?

Anders Hejlsberg

我发现Checked Exceptions在两个方面有比较大的问题:扩展性和版本控制。我知道你也写了一些关于Checked Exceptions的东西,并且倾向于我们对这个问题的看法。

 

 

Bruce Eckel

我一直认为Checked Exceptions是非常重要的。

Anders Hejlsberg

是的,老实说,它看起来的确相当重要,这个观点并没有错。我也十分赞许Checked Exceptions特性的美妙。但它某些方面的实现会带来一些问题。例如,从JavaChecked Exceptions的实现途径来看,我认为它在解决一系列既有问题的同时,付出了带来一系列新问题的代价。这样一来,我就搞不清楚Checked Exceptions特性是否可以真的让我们的生活变得更美妙一些。对此你或许有不同看法。

 

 

Bruce Eckel

C#设计小组对Checked Exceptions特性是否有过大量的争论?

Anders Hejlsberg

不,在这个问题上,我们有着广泛的共识。C#目前在Checked Exceptions上是保持缄默的。一旦有公认的更好的解决方案,我们会重新考虑,并在适当的地方采用的。我有一个人生信条,那就是——如果你对该问题不具有发言权,也没办法推进其解决进程,那么最好保持沉默和中立,而不应该摆出一个非此即彼的架势。

假设你让一个新手去编一个日历控件,他们通常会这样想:“哦,我会写出世界上最好的日历控件!我要让它有各种各样的日历外观。它有显示部分,有这个,有那个……”他们将所有这些构想都放到控件中去,然后花两天时间写了一个很蹩脚的日历程序。他们想:“在程序的下一个版本中,我将实现更多更好的功能。”

但是,一旦他们开始考虑如何将脑海中那么多抽象的念头具体实现出来时,就会发现他们原来的设计是完全错误的。现在,他们正蹲在一个角落里痛苦万状呢,他们发现必须将原来的设计全盘抛弃。这种情况我不是看到一次两次了。我是一个最低纲领主义者。对于影响全局的问题,在没有实际解决方案前,千万不要将它带入到整个框架中去,否则你将不知道这个框架在将来会变成什么样子。

 

 

Bruce Eckel

极限编程(The Extreme Programmers)上说:“用最简单的办法来完成工作。”

Anders Hejlsberg

对呀,爱因斯坦也说过:“尽可能简单行事。”对于Checked Excpetions特性,我最关心的是它可能给程序员带来哪些问题。试想一下,当程序员调用一些新编写的有自己特定的异常抛出句法的API时,程序将变得多么纷乱和冗长。这时候你会明白Checked Exceptions不是在帮助程序员,反而是在添麻烦。正确的做法是,API的设计者告诉你如何去处理异常而不是让你自己想破脑袋。

  • Checked Exceptions的版本相关性

Bill Venners

你提到过Checked Exceptions的扩展性和版本相关性这两个问题。现在能具体解释一下它们的意思么?

Anders Hejlsberg

让我首先谈谈版本相关性,这个问题更容易理解。假设我创建了一个方法foo,并声明它可能抛出ABC三个异常。在新版的foo中,我要增加一些功能,由此可能需要抛出异常D。这将产生了一个极具破坏性的改变,因为原来调用此方法时几乎不可能处理过D异常。

    也就是说,在新版本中增加抛出的异常时,给用户的代码带来了破坏。在接口中使用方法时也有类似的问题。一个实现特定功能的接口一经发布,就是不可改变的,新功能只能在新版的接口中增加。换句话说,就是只能创建新的接口。在新版本中,你只有两种选择,要么建立一个新的方法foo2foo2可以抛出更多的异常,要么在新的foo中捕获异常D,并转化为原来的异常AB或者C

 

 

Bill Venners

但即使在没有Checked Exceptions特性的语言中,(增加新的异常)不是同样会对程序造成破坏么?假如新版foo抛出了需要用户处理的新的异常,难道仅仅因为用户不希望这个异常发生,他写代码时就可以置之不理吗?

Anders Hejlsberg

不,因为在很多情况下,用户根本就不关心(异常)。他们不会处理任何异常。其实消息循环中存在一个最终的异常处理者,它会显示一个对话框提示你程序运行出错。程序员在任何地方都可以使用try finally来保护自己的代码,即使运行时发生了异常,程序依然可以正确运行。对于异常本身的处理,事实上,程序员是不关心的。

很多语言的throws语法(如Java),没必要地强迫你去处理异常,也就是逼迫你搞清楚每一个异常的来源。它们要求你要么捕获声明的异常,要么将它们放入throws语句。程序员为了达到这个要求,做了很多荒谬可笑的事情。例如他们在声明每个方法时,都必须加上修饰语:“throws Exception”。这完全是在搧这个特性的耳光,它不过是要求程序员多作些官样文章,对谁都没有好处

 

 

Bill Venners

如此说来,你认为不要求程序员明确的处理每个异常的做法,在现实中要适用得多了?

Anders Hejlsberg

人们为什么认为(显式的)异常处理非常重要呢?这太可笑了。它根本就不重要。在我印象中,一个写得非常好的程序里,try finallytry catch语句数目大概是101。在C#中,也可以使用和类似try finallyusing语句(来处理异常)

 

 

Bill Venners

finally到底干了些什么?

Anders Hejlsberg

finally保证你不被异常干扰,但它不直接处理异常。异常处理应该放在别的什么地方。实际上,在任何一个事件驱动的(如现代图形界面)程序中,在主消息循环里,都有一个缺省的异常处理过程,程序员只需要处理那些没被缺省处理的异常。但你必须确保任何异常情况下,原来分配的资源都能被销毁。这样一来,你的程序就是可持续运行的。你肯定不希望写程序时,在100个地方都要处理异常并弹出对话框吧。如果那样的话,你作修改时就要倒大霉了。异常应该集中处理,并在异常来临处保护好你的代码

  • Checked Exceptions的扩展性

Bill Venners

那么Checked Exceptions的扩展性又是如何呢?

Anders Hejlsberg

扩展性有时候和版本性是相关的。 在一个小程序里,Checked Exceptions显得蛮迷人的。你可以捕捉FileNotFoundException异常并显示出来,是不是很有趣?这在调用单个的API时也挺美妙的。但是在开发大系统时,灾难就降临了。你计划包含45个子系统,每个子系统抛出410个异常。但是(实际开发时),你每在系统集成的梯子上爬一级,必须被处理的新异常都将呈指数增长。最后,可能每个子系统需要抛出40个异常。将两个子系统集成时,你将必须写80throw语句。最后,可能你都无法控制了。

很多时候,Checked Exceptions都会激怒程序员,于是程序员就想办法绕过这个特性。他要么在到处都是写“throws Exception”,要么——我都不知道自己看到多少回了——写“try, da da da da da(译者注:意思是飞快的写一段代码), catch curly curly(译者注:即‘{ })”,然后说:“哦,我会回头来处理这些空的异常处理语句的。”实际上,理所当然的没有任何人会回头干这些事情。这时候,Checked Exceptions已经造成系统质量的极大下降。

所以,你可能很重视这些问题,但是在我们决定是否将Checked Exceptions的一些机制放入C#时,却是颇费了一番思量的。当然,知道什么异常可能在程序中抛出还是有相当价值的,有一些工具也可以作这方面的检查。我不认为我们可以建立一套足够严格而严谨的规则(来完成异常检查),因为(异常)还可能是编译器的错误引起的呢。但是我认为可以在(程序)分析工具上下些功夫,检测是否有可疑代码,是否有未捕获的异常,并将这些隐藏的漏洞给你指出来

 

- 作者: lu632 2005年06月2日, 星期四 12:27  回复(0) |  引用(0) 加入博采

错误处理规范

错误处理规范

〇、概念澄清

概念

解释

错误

  • 是指:导致系统不能按照用户意图工作的一切原因、事件
  • 不是指:java.lang.Error及其子类

异常

  • 是指:特定编程语言、开发平台提供的一种错误表现机制
  • 不是指但包括:java.lang.Error及其子类,java.lang.Exception及其子类,System.Exception及其子类

一、整体规范

  1. 按照错误类型,通常的处理方式如下:

错误类型

范围

处理方式

操作员错误

与人机界面交互时不满足输入规则、输入范围等发生的错误

  • 校验用户输入
  • 提示正确规则
  • 强制其改正

运行时错误

与外部资源交互时发生的错误,如网络、文件系统、数据库、其它业务应用系统等

  • 记录并抛出异常
  • 其它详见“异常处理规范”

程序员错误

与客户模块交互时不满足前置条件后置条件发生的错误,如类库被其他程序员调用时参数超出范围等

  • 使用断言

  1. 按照调用类型,通常的处理方式如下:

调用类型

处理方式

同步调用

  • 对有能力处理的异常,捕获并处理之
  • 对原始信息过于技术化的异常,捕获并包装之,重新抛出
  • 在调用的中间层,对未知异常保持沉默
  • 在调用的最高层,必须捕获所有异常,避免本身进程或宿主进程崩溃
  • 其它详见“异常处理规范”

异步调用

  • 异步调用一般不应有任何返回值
  • 服务方最好以同样的方式返回正常信息和错误信息,即正常信息是通过通知的方式返回的话,错误信息也应该通过通知的方式返回;正常信息是通过主动查询得到的话,错误信息也应该通过主动查询得到

  1. 按照展现方式,通常的分类如下:

展现方式

涉及模块

界面提示

  • 只有表示层需要显示界面提示
  • 表示层必须捕获所有错误,避免本身进程或宿主进程崩溃

记录日志

  • 所有模块都应记录错误日志

二、异常处理规范

1.      原则

  • 异常应该是分层的
  • 异常应该集中处理

2.      异常定义

  • 每个模块应该有自己的应用程序异常类型层次,从本模块主动抛出的应用程序异常都应该属于该异常类型层次,客户代码可以只捕捉该层次的基类(?)
  • 应用程序的所有自定义异常都应该从开发平台提供的“应用程序异常基类”派生
  • 中间件等平台程序的运行时异常都应该从开发平台提供的“运行时异常基类”派生(?)
  • 中间件等平台程序的运行时错误都应该从开发平台提供的“错误基类”派生(?)

3.      异常捕获

  • 对有能力处理的异常,捕获并处理之
  • 在调用的中间层,对未知异常保持沉默
  • 在调用的最高层,必须捕获所有异常,避免本身进程或宿主进程崩溃
  • 记录捕获到的每个原始异常的信息

4.      异常抛出

  • 每个模块应使用本模块所能得知的最精确的错误原因报告异常信息
  • 如果有原始异常,在重新抛出的自定义异常中附加原始异常的信息

三、几点说明

1.      错误处理与日志系统

  • 错误处理不等同于日志系统,日志系统只是错误信息的一种记录手段
  • 错误信息的输出应全部调用日志系统来完成

2.      程序员错误与运行时错误

  • 接口函数的前置条件,应该是一种规范,是客户程序员必须遵守的约定;客户程序员违反了约定,程序将产生异常或不可预知的错误;对于这类约定,不应该需要有运行时的代码检查 ;比如如果你的接口函数的一个参数不能为null,而你在函数开始部分程序里写:

if(xxx == null){

    throw new someException();

}

你的代码实际上允许该参数为null,因为你对null的情况进行了运行时处理;尽管你在文档里声明该参数不能为null,但如果客户程序员遵守了约定,那么你这段检查代码就是冗余的

  • 当你对参数没有任何检查就进行了使用,而非法的参数值导致了错误,此时有两种情况: 如果你在接口函数说明里列出了参数不允许的非法取值,那么客户程序员应该修改程序避免传入非法值,该类错误称为程序员错误;如果你没有说明,那么你应该修改函数,处理非法参数
  • 不是所有的限制条件在文档里说明一下,就可以把责任扔给客户程序员了,有一些错误必须处理:特别是客户程序员不需要import你的package就可以和你的接口交互的情况,如socket服务器 ,你必须在socket服务程序内部检查所有接收到的数据,拒绝错误的请求,否则极易遭到攻击

3.      错误代码与异常

  • 不应该使用bool值来返回成功与否,bool返回值只应用在真正查询bool状态的操作中,如 bool IsDirty()bool hasNext()
  • 整形或bool型的错误代码返回值强迫客户程序员检查每一次调用,应用异常取代之

四、附录

A.     Anders HejlsbergC#异常设计

译者注:在写一段程序时,如果没有用try-catch捕捉异常或者显式的抛出异常,而希望程序自动抛出,一些语言的编译器不会允许编译通过,如Java就是这样。这就是Checked Exceptions最基本的意思。该特性的目的是保证程序的安全性和健壮性。Zee&Snakey(MVP)对此有一段很形象的话,可以参见http://www.blogcn.com/user2/zee/main.aspBruce Eckel 也有相关的一篇文章:Does Java need Checked Exceptions》,参见http://www.mindview.net/Etc/Discussions/CheckedExceptions

  • Checked Exceptions特性持保留态度

Bruce Eckel

C#没有Checked Exceptions,你是怎么决定是否在C#中放置这种特性的么?

Anders Hejlsberg

我发现Checked Exceptions在两个方面有比较大的问题:扩展性和版本控制。我知道你也写了一些关于Checked Exceptions的东西,并且倾向于我们对这个问题的看法。

 

 

Bruce Eckel

我一直认为Checked Exceptions是非常重要的。

Anders Hejlsberg

是的,老实说,它看起来的确相当重要,这个观点并没有错。我也十分赞许Checked Exceptions特性的美妙。但它某些方面的实现会带来一些问题。例如,从JavaChecked Exceptions的实现途径来看,我认为它在解决一系列既有问题的同时,付出了带来一系列新问题的代价。这样一来,我就搞不清楚Checked Exceptions特性是否可以真的让我们的生活变得更美妙一些。对此你或许有不同看法。

 

 

Bruce Eckel

C#设计小组对Checked Exceptions特性是否有过大量的争论?

Anders Hejlsberg

不,在这个问题上,我们有着广泛的共识。C#目前在Checked Exceptions上是保持缄默的。一旦有公认的更好的解决方案,我们会重新考虑,并在适当的地方采用的。我有一个人生信条,那就是——如果你对该问题不具有发言权,也没办法推进其解决进程,那么最好保持沉默和中立,而不应该摆出一个非此即彼的架势。

假设你让一个新手去编一个日历控件,他们通常会这样想:“哦,我会写出世界上最好的日历控件!我要让它有各种各样的日历外观。它有显示部分,有这个,有那个……”他们将所有这些构想都放到控件中去,然后花两天时间写了一个很蹩脚的日历程序。他们想:“在程序的下一个版本中,我将实现更多更好的功能。”

但是,一旦他们开始考虑如何将脑海中那么多抽象的念头具体实现出来时,就会发现他们原来的设计是完全错误的。现在,他们正蹲在一个角落里痛苦万状呢,他们发现必须将原来的设计全盘抛弃。这种情况我不是看到一次两次了。我是一个最低纲领主义者。对于影响全局的问题,在没有实际解决方案前,千万不要将它带入到整个框架中去,否则你将不知道这个框架在将来会变成什么样子。

 

 

Bruce Eckel

极限编程(The Extreme Programmers)上说:“用最简单的办法来完成工作。”

Anders Hejlsberg

对呀,爱因斯坦也说过:“尽可能简单行事。”对于Checked Excpetions特性,我最关心的是它可能给程序员带来哪些问题。试想一下,当程序员调用一些新编写的有自己特定的异常抛出句法的API时,程序将变得多么纷乱和冗长。这时候你会明白Checked Exceptions不是在帮助程序员,反而是在添麻烦。正确的做法是,API的设计者告诉你如何去处理异常而不是让你自己想破脑袋。

  • Checked Exceptions的版本相关性

Bill Venners

你提到过Checked Exceptions的扩展性和版本相关性这两个问题。现在能具体解释一下它们的意思么?

Anders Hejlsberg

让我首先谈谈版本相关性,这个问题更容易理解。假设我创建了一个方法foo,并声明它可能抛出ABC三个异常。在新版的foo中,我要增加一些功能,由此可能需要抛出异常D。这将产生了一个极具破坏性的改变,因为原来调用此方法时几乎不可能处理过D异常。

    也就是说,在新版本中增加抛出的异常时,给用户的代码带来了破坏。在接口中使用方法时也有类似的问题。一个实现特定功能的接口一经发布,就是不可改变的,新功能只能在新版的接口中增加。换句话说,就是只能创建新的接口。在新版本中,你只有两种选择,要么建立一个新的方法foo2foo2可以抛出更多的异常,要么在新的foo中捕获异常D,并转化为原来的异常AB或者C

 

 

Bill Venners

但即使在没有Checked Exceptions特性的语言中,(增加新的异常)不是同样会对程序造成破坏么?假如新版foo抛出了需要用户处理的新的异常,难道仅仅因为用户不希望这个异常发生,他写代码时就可以置之不理吗?

Anders Hejlsberg

不,因为在很多情况下,用户根本就不关心(异常)。他们不会处理任何异常。其实消息循环中存在一个最终的异常处理者,它会显示一个对话框提示你程序运行出错。程序员在任何地方都可以使用try finally来保护自己的代码,即使运行时发生了异常,程序依然可以正确运行。对于异常本身的处理,事实上,程序员是不关心的。

很多语言的throws语法(如Java),没必要地强迫你去处理异常,也就是逼迫你搞清楚每一个异常的来源。它们要求你要么捕获声明的异常,要么将它们放入throws语句。程序员为了达到这个要求,做了很多荒谬可笑的事情。例如他们在声明每个方法时,都必须加上修饰语:“throws Exception”。这完全是在搧这个特性的耳光,它不过是要求程序员多作些官样文章,对谁都没有好处

 

 

Bill Venners

如此说来,你认为不要求程序员明确的处理每个异常的做法,在现实中要适用得多了?

Anders Hejlsberg

人们为什么认为(显式的)异常处理非常重要呢?这太可笑了。它根本就不重要。在我印象中,一个写得非常好的程序里,try finallytry catch语句数目大概是101。在C#中,也可以使用和类似try finallyusing语句(来处理异常)

 

 

Bill Venners

finally到底干了些什么?

Anders Hejlsberg

finally保证你不被异常干扰,但它不直接处理异常。异常处理应该放在别的什么地方。实际上,在任何一个事件驱动的(如现代图形界面)程序中,在主消息循环里,都有一个缺省的异常处理过程,程序员只需要处理那些没被缺省处理的异常。但你必须确保任何异常情况下,原来分配的资源都能被销毁。这样一来,你的程序就是可持续运行的。你肯定不希望写程序时,在100个地方都要处理异常并弹出对话框吧。如果那样的话,你作修改时就要倒大霉了。异常应该集中处理,并在异常来临处保护好你的代码

  • Checked Exceptions的扩展性

Bill Venners

那么Checked Exceptions的扩展性又是如何呢?

Anders Hejlsberg

扩展性有时候和版本性是相关的。 在一个小程序里,Checked Exceptions显得蛮迷人的。你可以捕捉FileNotFoundException异常并显示出来,是不是很有趣?这在调用单个的API时也挺美妙的。但是在开发大系统时,灾难就降临了。你计划包含45个子系统,每个子系统抛出410个异常。但是(实际开发时),你每在系统集成的梯子上爬一级,必须被处理的新异常都将呈指数增长。最后,可能每个子系统需要抛出40个异常。将两个子系统集成时,你将必须写80throw语句。最后,可能你都无法控制了。

很多时候,Checked Exceptions都会激怒程序员,于是程序员就想办法绕过这个特性。他要么在到处都是写“throws Exception”,要么——我都不知道自己看到多少回了——写“try, da da da da da(译者注:意思是飞快的写一段代码), catch curly curly(译者注:即‘{ })”,然后说:“哦,我会回头来处理这些空的异常处理语句的。”实际上,理所当然的没有任何人会回头干这些事情。这时候,Checked Exceptions已经造成系统质量的极大下降。

所以,你可能很重视这些问题,但是在我们决定是否将Checked Exceptions的一些机制放入C#时,却是颇费了一番思量的。当然,知道什么异常可能在程序中抛出还是有相当价值的,有一些工具也可以作这方面的检查。我不认为我们可以建立一套足够严格而严谨的规则(来完成异常检查),因为(异常)还可能是编译器的错误引起的呢。但是我认为可以在(程序)分析工具上下些功夫,检测是否有可疑代码,是否有未捕获的异常,并将这些隐藏的漏洞给你指出来

 

- 作者: lu632 2005年06月2日, 星期四 12:27  回复(0) |  引用(0) 加入博采

系统测试设计的层次

系统测试设计的层次

随着国内软件行业的不断发展,国内软件公司也越来越注重于软件的质量,越来越关注软件的可靠性,因此,做为质量保证的重要手段,软件测试过程的实施与管理成为一个热点,其中系统测试是整个测试活动的一个重要的阶段,系统测试的设计也就成为了关注点之一。以下是本人从事系统测试工作中的一些体会。
1
、系统测试的定义:

系统测试是针对整个产品系统进行的测试,目的是验证系统是否满足了需求规格的定义,找