软件测试整理

软件测试考点整理

一、软件测试介绍

软件缺陷的概念

从产品内部看,软件缺陷是产品开发或维护过程中所存在的错误、毛病等各种问题。

从产品外部看,软件缺陷是系统所需要实现的某种功能的失效或者违背。

软件测试的一个重要功能

verification(验证)and validation(确认)

  • verification:验证我们是不是正确的做了这个产品,也就是产品要符合他的目标
  • validation:确认我们是不是做了正确的产品,也就是产品是用户真正想要的

软件测试的目的

  • 软件测试是为了发现错误而执行程序的过程。

  • 一个好的测试能过在第一时间发现程序中存在的错误。

  • 一个好的测试是发现了至今尚未发现的错误。

  • 减小软件不能正常工作的风险

软件测试的分类

  • C1:按照测试生成的来源

  • C2:按照生命周期的阶段

  • C3:按照测试活动的目的

  • C4:按被测对象的特征

  • C5:按测试过程的模型

软件测试V模型

img

软件测试用例

输入以测试系统和预测这些系统的输出,如果系统根据其规范运作。

二、黑盒测试

等价类

(Equivalence Partitioning)

分为有效类和无效类,两者不能有重叠的部分

例子:写出 NextDate Function( 1812≤year≤2015 )的等价类

有效等价类

M1 = {month:1≤month≤12}

D1 = {date:1≤date≤31}

Y1 = {year:1812≤year≤2015}

无效等价类

M2 = {month:month<1}

M3 = {month:month>12}

D2 = {date:date<1}

D3 = {date:date>31}

Y2 = {year:year<1812}

Y3 = {year:year>2015}

再例如:有一个报表处理系统,要求用户输入处理报表的日期。假如日期限制在2000年1月至2020年12月,即系统只能对该段时期内的报表进行处理。如果用户输入的日期不在这个范围内,则显示“错误信息”。并且此系统规定日期由年月的6位数字组成,前四位代表年,后两位代表月。要求划分日期的等价类。

等价类:

img

测试用例:

img

边界值分析法

(Boundary Value Analysis)

基本原理

边界值分析法是单一错误原则(Single fault),每个测试用例只有一个变量取边界值!

举例:

三角形问题,输入a、b、c

1 ≤ a ≤ 200

1 ≤ b ≤ 200

1 ≤ c ≤ 200

所以a,b,c的取值是

a = {1,2,100,199,200}

b = {1,2,100,199,200}

c = {1,2,100,199,200}

3403753-65d425801fdf9bde

测试用例如下

小结总结

  • 等价类测试的弱形式不如强形式测试全面

  • 无效值会引起运行错误的时候(实现语言是强类型),则没有必要做健壮形式的测试。

  • 错误条件很重要的时候,健壮测试很重要。

  • 边界值测试是等价类测试的一种补充,两者结合可以加强测试效果。

  • 决策表技术可以解决变量之间的依赖问题。

  • 要进行多次尝试,确认最合适的等价类划分

正交测试

(Orthogonal Array Testing)

使用正交试验法,为下面的基本信息查询选取测试用例。

姓 名: 1-不填 0-填写

身份证: 1-不填 0-填写

手机号: 1-不填 0-填写

正交表

image.png

第一步:

计算出需要的测试用例个数

n= ∑(每列的水平数-1)+1

=(2-1)+(2-1)+(2-1)+1

=3×(2-1)+1

=4

需要4次实验即可

第二步:

根据实验的水平数,和因子个数选择合适的正交表,我们选择第一个

第三步:

根据正交表写出测试用例。正交表的每一列对应一个因子(变量),每个取值对应的水平值,即变量的取值。

image.png

决策表

(Decision Table)

决策表有四个部分

Stub portion、Entry portion、Condition portion、Action portion
image

从问题决策到结果,Y代表条件满足,N代表条件不满足,–代表忽略这个条件

练习:

某货运站收费标准如下:如果收件地点在本省,则快件每公斤5元,慢件每公斤3元;如果收件地点在省外,则在20公斤以内(含20公斤)快件每公斤7元,慢件每公斤5元,而超过20公斤时,快件每公斤9元,慢件每公斤7元。请用决策表方法解决此问题。

第一步:确定规则的数目。

条件:

(1)收件地在本省?

(2)是快件?

(3)重量不超过20公斤?

根据公式计算2的3次方=8

所以应有8条规则。

第二步:列出所有的条件桩和行动桩。

第三步:填入条件条目

第四步:填入行动条目

img

第五步:化简决策表(一定要合并简化)

img

因果图

(Cause-Effect Graphing)

因果图法产生的背景

等价类划分法和边界值分析方法都是着重考虑输入条件,但没有考虑输入条件的各种组合、输入条件之间的相互制约关系。这样虽然各种输入条件可能出错的情况已经测试到了,但多个输入条件组合起来可能出错的情况却被忽视了。

如果在测试时必须考虑输入条件的各种组合,则可能的组合数目将是天文数字,因此必须考虑采用一种适合于描述多种条件的组合、相应产生多个动作的形式来进行测试用例的设计,这就需要利用因果图(逻辑模型)。

因果图概念介绍

因果图(Cause-EffectGraphing)提供了一个把规格转化为判定表的系统化方法,从该图中可以产生测试数据。其中原因是表示输入条件,结果是对输入执行的一系列计算后得到的输出。因果图方法最终生成的就是判定表,它适合于检查程序输入条件的各种组合情况。

因果图中基本符号介绍(这里可以看PPT,不全部列出)

  1. 等价 implication
    if C1 is 1,then E1 is 1 also,else E1 is 0.
    image.png

  2. 非 not
    if C1 is 1,then E1is 0,else E1 is 1.
    image.png

  3. 或 or
    if C1or C2 or C3 is 1,then E1 is 1,else E1is 0;“Or” may have arbitrary number of inputs.
    image.png

  4. 与 and
    if both C1 and C2 are 1,then E1is1,else E1is 0;“And” may have arbitrary number of input.
    image.png

  5. 异 exclusive
    either C1 or C2
    image.png

  6. 唯一 one and only one
    one, and only one, of C1 and C2
    image.png

  7. 要求 require
    C1 requires C2
    image.png

  8. 强制 masking
    E1 masks E2
    image.png

因果图分析步骤
第一步,找出Cause(原因)

Cause(原因)

c1— the first character is #

c2 —the first character is *

c3 —the second character is number

第二步,找出Effect(结果)

e1— give the information N

e2— modify the document

e3— give the information M

第三步,分析出中间节点

然后画出因果图,如图

image

再举个例子

某公司对客户有一定的折扣政策,公司软件的一个模块的需求说明书中描述“……当交易额小于等于5万元时折扣为0,当交易额大于5万元时才有折扣,如果交易的客户在三个月内无欠款,则折扣为15%;如果交易用户在三个月内有欠款,若该用户是三年以上的老客户,则折扣为10%;若该客户不是三年以上的老客户,则折扣为5%。”

原因(对立的就不要再写了,比如写了是小于五万就不用写大于等于五万了):

C1:交易额大于5万元

C2:三个月无欠款

C3:三年以上老客户

结果(注意对立的就不要再写了):

E1:无折扣

E2:折扣=5%

E3:折扣=10%

E4:折扣=15%

因果图**

从这个图中你就能找出导出上边说的四种结果的逻辑

img

三、白盒测试

白盒测试(white-box testing)也叫structural testing, clear box testing, and glass box testing.

白盒测试分为静态测试动态测试

白盒静态测试:Code inspection, Static structure analysis, Static quality metric method

白盒动态测试:主要基于覆盖,包括logic coverage, loop coverage, basis path coverage, etc.

白盒测试主要应用于单元测试

we can’t use exhaustive(详尽的) testing

动态测试之逻辑覆盖

白盒测试用例设计的一个很重要的评估标准就是对代码的覆盖度。一说到覆盖,大家都感觉非常熟悉,但是常见的覆盖都有哪些?各自有什么优缺点?在白盒测试的用例设计中我们应该如何自如地运用呢?为大家总结了一下几种常见的覆盖以及各自的优缺点。

白盒测试中常见的覆盖有六种:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖和路径覆盖。下面我们就分别看看这几种不同的覆盖究竟是什么鬼。

语句覆盖

(Statement Coverage)

语句覆盖,顾名思义就是针对代码语句的嘛。它的含义是我们设计出来的测试用例要保证程序中的每一个语句至少被执行一次。通常语句覆盖被认为是“最弱的覆盖”,原因是它仅仅考虑对代码中的执行语句进行覆盖而没有考虑各种条件和分支,因此在实际运用中语句覆盖很难发现代码中的问题。举个非常简单的例子:

1
2
3
4
5
6
7
public int foo(int a,int b)

{

return a/b;

}

这是一个求两数之商的函数。如果我们设计如下的测试用例:

TestCase: a = 2, b = 1

这时候我们会发现,该函数的代码覆盖率达到了100%,并且设计的case可以顺利通过测试。

但是显然该函数有一个很明显的bug:当 b=0 时,会抛出异常。

再来看这个例子:

img

主要特点:语句覆盖是最起码的结构覆盖要求,语句覆盖要求设计足够多的测试用例,使得程序中每条语句至少被执行一次。

用例设计:(如果此时将A路径上的语句1->T去掉,那么用例如下

img

优点:可以很直观地从源代码得到测试用例,无须细分每条判定表达式。

缺点:由于这种测试方法仅仅针对程序逻辑中显式存在的语句,但对于隐藏的条件和可能到达的隐式逻辑分支,是无法测试的。在本例中去掉了语句1—〉T去掉,那么就少了一条测试路径。在if结构中若源代码没有给出else后面的执行分支,那么语句覆盖测试就不会考虑这种情况。但是我们不能排除这种以外的分支不会被执行,而往往这种错误会经常出现。再如,在Do-While结构中,语句覆盖执行其中某一个条件分支。那么显然,语句覆盖对于多分支的逻辑运算是无法全面反映的,它只在乎运行一次,而不考虑其他情况。

判定覆盖

(Decision Coverage)

判定覆盖也被成为分支覆盖(Branch Coverage),也就是说设计的测试用例要保证让被测试程序中的每一个分支都至少执行一次。举个例子,有如下流程图:

img

针对该图我们想要做到判定覆盖,可以设计如下case:

TestCase1: a=1, b=1 (路径:ab)

TestCase2: a=-1, b=-1 (路径:acd)

TestCase3: a=2, b=-1 (路径:ace)

判定覆盖比语句覆盖强一些,能发现一些语句覆盖无法发现的问题。但是往往一些判定条件都是由多个逻辑条件组合而成的,进行分支判断时相当于对整个组合的最终结果进行判断,这样就会忽略每个条件的取值情况,导致遗漏部分测试路径。

用例设计

img

优点:判定覆盖比语句覆盖要多几乎一倍的测试路径,当然也就具有比语句覆盖更强的测试能力。同样判定覆盖也具有和语句覆盖一样的简单性,无须细分每个判定就可以得到测试用例。

缺点:往往大部分的判定语句是由多个逻辑条件组合(也就是可能if(a==b&&c==d)这种的逻辑组合)而成(如,判定语句中包含AND、OR、CASE),若仅仅判断其整个最终结果,而忽略每个条件的取值情况,必然会遗漏部分测试路径。

条件覆盖

(Condition Coverage)

条件覆盖于分支覆盖不同,条件覆盖要求所设计的测试用例能使每个判定中的每一个条件都获得可能的取值,即每个条件至少有一次真值、有一次假值

仍然以上面流程图2作为例子来说明。上图中涉及到的条件一共有4个:

1
a>0, a<0, b>0, b<0

为了达到条件覆盖的目的,我们设计的用例需要在 a 点有:

1
a>0, a<=0, b>0, b>=0,

这些情况出现,并且在 c 点有:

1
a<0, a>=0, b<0, b>=0

这些情况出现。现在可以设计如下用例:

1
2
3
4
5
6
7
TestCase1: a=1, b=1  (路径:ab)

TestCase1: a=-1, b=-1  (路径:acd)

TestCase1: a=-1, b=0  (路径:ace)

TestCase1: a=1, b=-1  (路径:ace)

通常而言条件覆盖比判定覆盖强,因为条件覆盖使得判定中的每一个条件都取到了不同的结果,这一点判定覆盖则无法保证。但条件覆盖也有缺陷,因为它只能保证每个条件都取到了不同结果,但没有考虑到判定结果,因此有时候条件覆盖并不能保证判定覆盖。

优点:显然条件覆盖比判定覆盖,增加了对符合判定情况的测试,增加了测试路径。

缺点:要达到条件覆盖,需要足够多的测试用例,但条件覆盖并不能保证判定覆盖。条件覆盖只能保证每个条件至少有一次为真,而不考虑所有的判定结果。

判定条件覆盖

(Decision/Condition Coverage)

针对流程图1的测试用例

主要特点:设计足够多的测试用例,使得判定中每个条件的所有可能结果至少出现一次,每个判定本身所有可能结果也至少出现一次。

img

优点:判定/条件覆盖满足判定覆盖准则和条件覆盖准则,弥补了二者的不足。

缺点:判定/条件覆盖准则的缺点是未考虑条件的组合情况。

组合覆盖

(Branch Condition Combination Coverage)

组合覆盖也叫做条件组合覆盖。意思是说我们设计的测试用例应该使得每个判定中的各个条件的各种可能组合都至少出现一次。显然,满足条件组合覆盖的测试用例一定是满足判定覆盖、条件覆盖和判定条件覆盖的。

主要特点:要求设计足够多的测试用例,使得每个判定中条件结果的所有可能组合至少出现一次。

针对前文提到的流程图2,做条件组合覆盖时我们可以设计如下用例:

TestCase1: a=1, b=1  (路径:ab)

TestCase1: a=-1, b=-1  (路径:acd)

TestCase1: a=-1, b=0  (路径:ace)

TestCase1: a=1, b=-1  (路径:ace)

针对流程图1的测试用例

img

优点:多重条件覆盖准则满足判定覆盖、条件覆盖和判定/条件覆盖准则。更改的判定/条件覆盖要求设计足够多的测试用例,使得判定中每个条件的所有可能结果至少出现一次,每个判定本身的所有可能结果也至少出现一次。并且每个条件都显示能单独影响判定结果。

缺点:线性地增加了测试用例的数量。

路径覆盖

路径覆盖,意思是说我们设计的测试用例可以覆盖程序中所有可能的执行路径。这种覆盖方法可以对程序进行彻底的测试用例覆盖,比前面讲的五种方法覆盖度都要高。那么这种方法是不是就一定最好呢?当然不能讲得这么绝对,它的缺点也是显而易见的:由于需要对所有可能的路径全部进行覆盖,那么我们需要设计数量非常巨大的而且较为复杂的测试用例,用例数量将呈现指数级的增长。所以理论上来讲路径覆盖是最彻底的测试用例覆盖,但实际上很多时候路径覆盖的可操作性不强。

针对流程图1

img

优点:这种测试方法可以对程序进行彻底的测试,比前面五种的覆盖面都广。

缺点:由于路径覆盖需要对所有可能的路径进行测试(包括循环、条件组合、分支选择等),那么需要设计大量、复杂的测试用例,使得工作量呈指数级增长。而在有些情况下,一些执行路径是不可能被执行的

总结

以上简单描述了几种不用的逻辑覆盖方法的原则和优劣。在实际的操作中,要正确使用白盒测试的代码覆盖方法,就要从代码分析和代码调研入手,根据调研的结果,可以选择上述方法中的某一种,或者好几种方法的结合,设计出高效的测试用例,尽可能全面地覆盖到代码中的每一个逻辑路径。

控制流程图和圈复杂度

常见控制流图

img

img

将上述程序转为控制流图

img

公式:圈复杂度(独立路径数)= 闭合区域数目= 二值判定节点数+1 = 边数-节点数+2

注:闭合区域指将平面分成的区域,即包括外面无限大的部分

例子

计算下图的圈复杂度

标识它的独立路径

img

独立路径是指程序中至少引进一个新的处理语句集合,采用流图的术语,即独立路径必须至少包含一条在定义路径之前不曾用到的边。

圈复杂度(独立路径数)=判定节点数(5)+1= 6

独立路径数= 闭合区域个数= 6

独立路径数= e – n + 2 = 13 – 9 + 2 = 6 (e为边数,n为结点数 )

独立路径

ABCFG

ABCDFG

ABDFG

ABEFG

ABEDFG

ABEFGABEFG

再比如

img

复杂度=闭合区域数=4

=二值判定节点数+1=3+1=4

=e-n+2=11-9+2=4

独立路径

1-11

1-2-3-4-5-10-1-11

1-2-3-6-8-9-10-11

1-2-3-6-7-9-10-1-11

为了覆盖所有程序语句,必须设计至少4个测试用例使程序运行于这4条路径

循环测试

路径覆盖法是一种将程序中循环结构简化成选择结构的测试方法。

循环简化的目的是限制循环次数,无论循环的形式和循环体实际执行的次数,简化后的循环测试只考虑循环一次或者零次两种情况。

在这种情况下,循环与判定分支的效果是一样的,即循环要么执行,要么跳过。

采用较复杂的循环测试策略测试循环,可采用下面测试集:

跳过整个循环;

只循环一次;

只循环两次;

循环m次,m

数据流测试

突变测试

(Mutation Testing)

突变测试(mutation testing) , 或称作突变分析、程序突变,它是用于衡量软件测试的质量。突变测试通常对程序的源代码或者目标代码做小的改动,并把截然不同的错误行为(或者怪异行为)作为预期。如果测试代码没有觉察到这种小改动带来的错误,就说明这个测试是有问题的。

突变测试目的

  • Help testers design high quality tests 设计高质量测试
  • Evaluate the quality of existing tests 评估现有测试质量

突变测试范围

unit level、integration level、specification level

单元级、集成级、规范级

下面用一个例子来解释什么是变异测试,考虑以下代码片段:

1
2
3
if(a && b)  c = 1;

else c = 0;

条件运算符如果用||来替换&&,就会产生以下变异:

1
2
3
if(a || b) c = 1;

else c = 0;

为了防止这种突变,测试需要满足以下条件:

  1. 测试数据必须对突变和原始程序引起的不同状态覆盖。如:a=1,b=0可以达到目的。
  2. c的值应该传播到程序输出,并被测试检查。

弱突变覆盖需满足1,强突变覆盖需满足1、2。

四、单元测试

(Unit Testing)

单元测试是最小的测试部分测试模块是独立于其他模块的一般情况下,被测单元能够实现一个特定的功能,并与其他单元有明确的接口定义,这样才可以与其他单元隔离开来。

In Java, a unit is a class or a class method.

In C, a unit is a function or sub processes.

目标:确保模块被正确的编码

依据:系统详细的规格说明

过程:经过设计、脚本开发、执行、调试和分析结果一个过程

执行者:由程序开发人员和测试人员共同完成

方法:以白盒测试方法为主,辅以黑盒测试方法

如何进行评估:通过所有单元测试用例,代码没有严重缺陷

单元测试过程

  1. 在详细设计阶段完成单元测试计划
  2. 建立单元测试环境,完成测试设计和开发
  3. 执行单元测试用例,并且详细记录测试结果
  4. 判定单元测试是否通过
  5. 提交单元测试报告

img

单元测试优点

  1. 单独进行,一起进行,降低软件质量成本,缩短开发周期;
  2. 便于跟踪错误;
  3. 集成后错误会放大,集成后复杂性高,很难发现问题;
  4. 无需而外的设备和人员。

单元测试分为静态测试和动态测试

静态测试

代码评审:代码走查和正式会议审查。

代码走查:代码互查应用最多,代码走查是相对比较正式的评审过程,项目组部分成员通过阅读代码,向其他成员提出问题并对有关技术、风格、可能错误是否违背开发标准和规范等进行评论。

正式会议审查:是一种正式的检查和评估方法,最早由IBM提出,经实践证明,有一种有效的检查办法,从而得到软件工程界的普遍认同。它使用逐步检查源代码中有无逻辑或语法错误的办法来检验故障。

img

五、集成测试

(Integration Testing)

(集成测试、组装测试、联合测试、子系统测试、部件测试)

优点:早点发现错误,早点修正错误,早点获得测试反馈,调度修正错误灵活

分为增量式测试非增量式测试

测试模式

**大爆炸集成 **

(Big bang integration)

优点:完成速度快、能够并行

缺点:错误发生时很难找出他的位置和改变以及很多问题得在系统测试才能发现

适用范围:

Existing system with only minor modifications

Small systems with adequate unit testing

System made from certified high quality reusable components

自顶向下集成

(Top-down integration)

分为广度和深度集成测试

优点

  • 早期显示控制和判断要点。
  • 采用深度优先装配,可以首先实现和验证完整的软件功能。
  • 最多只需要一个驱动程序模块。 支持故障隔离。

缺点

  • 开发和维护存根的成本都较高。
  • 底层组件需求无法预测可能导致对顶层组件的许多修改。

自顶向上集成

(Bottom-up integration)

优点

  • 允许对底层模块进行早期认证,任何叶子节点都可以进行集成测试。
  • 减少剩余部分开发的工作量
  • 支持故障隔离

缺点

  • 驱动模块开发工作量比较大。
  • 高级验证被推迟到结束,无法及时发现设计错误。
  • 底盖异常坚硬。

三明治集成

Sandwich integration

优点

结合自上而下策略和自下而上策略的优势。

缺点

在集成测试之前,中间层测试是不够的。

范围

它被大多数软件开发项目使用。

分层集成

Layers integration

高频集成

(High-frequency integration)

基于事件集成

(Event-based integration)

六、系统测试

目的:测试可安装性、可用性、兼容性、可维护性等等

七、性能测试

性能是量度系统或组件在一定约束条件下,是否达到功能设计的指标:如响应速度,计算的精度,内存利用率。

性能是系统外部的质量属性基于用户的需求和用户的系统操作性的看法。

同时性能特别应用于对实时系统的评价当中,就是它的行为在指定的期限内完成正确的操作。

评估指标为时间效率,空间效率,I∕O性能,数据库性能,内存性能,初始化∕退出时间和资源利用率****延时,事务处理时间,最大事务处理时间,事务操作时间,数据库性能,最大消耗的内存量,高峰内存时间,资源消耗。

下图描述了web应用的页面响应时间的分解。

img

页面响应时间分解为网络传输时间(N1+N2+N3+N4)和应用延迟时间(A1+A2+A3),

而应用延迟时间又可分为数据库延迟时间(A2)和应用服务器延迟时间(A1+A3)。

延迟:一个指令控制器发出数据请求的一瞬间和数据传送的一瞬间之间的时间间隔;是请求和完成操作之间拖延的时间差。

事务处理时间:是指完成一项事务所需要的运行时间,用于评价事务处理效率。通常,事务处理的时间越短,则效率越高。

并发用户数,一般分两种情况:

严格意义的并发,即所有用户在同一时间做同一件事情或者操作。

广义范围的并发,多个用户对系统发出了请求或进行了操作,但这些操作可以是相同的,也可以是不同的。

吞吐量:是指在一次性能测试过程中网络上传输数据量的总和。

一般来说,吞吐量用请求数/秒或页面数/秒来衡量。

吞吐量指标有如下两个作用:

1、协助设计性能测试场景,衡量性能测试场景是否达到了预期的设计目标。

在设计性能测试场景时,根据估算吞吐量数据测试场景事物发生频率。

2、协助分析性能测试瓶颈。

性能测试比较关注业务并发用户数,从业务的角度设置多少并发数合理。

下面给出估算并发用户数的公式:C=nL/T

C —平均的并发用户数

n —登录会话的数量

L —登录会话的平均长度

T —考察的时间段长度

img

img

例题

一个软件系统每天约有400个用户访问。用户在一天之内有8小时内使用该系统,从登录到退出的平均时间为4小时,请计算该系统的并发用户数和并发用户的峰值各是多少?

分析:根据公式C=400×4/8=200

img

负载测试是模拟实际软件系统所承受的负载条件的系统负荷,通过不断加载(不断增加模拟用户数量)或其他加载方式来观察不同负载下系统响应时间和数据吞吐量,系统资源占有率(cpu和内存)等性能指标,以检验系统的行为和特性,发现系统可能存在的性能瓶颈、内存泄露和不能实现同步等问题。

高低突变加载:某个时间用户数量很大,突然降到很低,过一段时间,又突然加到很高,反复几次。借助这种负载方式的测试,容易发现资源的释放和内存泄漏的问题。

随机加载方式:由随机算法自动生成某个数量范围内变化的、动态的负载,这种方式可能是和实际情况最为接近的一种负载方式。虽然不容易模拟系统运行出现的瞬间高峰期,但可以模拟系统长时间的运行过程的状态。

压力测试用于判定应用处理大量数据的能力。

压力测试可以成功的测试服务器满负载的情况。

除了在服务器上增加运行的应用结合客户端测试是一种额外的形式的压力测试。

性能测试过程:计划,记录,修改,执行,分析