jenkins内部参数传递

场景一: Job构建步骤间的变量传递
Jenkins提供了数十种构建方式,我们以最常用的『Execute shell』为例。有时为了使Job中的复杂的构建流程更加清晰我们配置多个构建步骤像下面这样。图中包含两个构建步骤,步骤2需要根据步骤1中的返回值来判断是否执行操作:
[Jenkins]Job中如何传递自定义变量 - 网易杭州QA - 网易杭州 QA Team
执行时jenkins将两个构建步骤生成两个shell文件,然后分别调用。

do_build_step_1

[Jenkins] $ /bin/bash -xe /tmp/hudson1270042613896791809.sh
do_build_step_2

[Jenkins] $ /bin/bash -xe /tmp/hudson5918908417824291692.sh
理论上两个shell之间是无法通信的,step1执行完之后变量$dostep2就会被回收,要注意试图在step1中通过export或者其他脚本方式注入环境变量都是无效的。
解决方案:读写文件
要实现它们之间的变量传递只能通过读写文件的方式。我们有一个真实应用场景是这样的,配置由git push触发编译任务,但是并不是每一次git的提交都需要触发编译,比如说只有前端代码的提交其实并不影响编译的结果,我们只好在step1中加入判断来却确定step2是否真的有必要被执行。
[Jenkins]Job中如何传递自定义变量 - 网易杭州QA - 网易杭州 QA Team
场景二: Job之间的变量传递
现在有两个Project『run_compile』和『run_deploy』,代码编译成功后开始执行环境部署。不需要传递参数的情况下可以选择“Build other projects“的方式。
[Jenkins]Job中如何传递自定义变量 - 网易杭州QA - 网易杭州 QA Team
需要传递参数则需要选择”Trigger parameterized build on other projects”的方式。

[Jenkins]Job中如何传递自定义变量 - 网易杭州QA - 网易杭州 QA Team

Jenkins Parameterized Trigger plugin可以实现Job间参数传递但是有局限性,我们只能选择传递当前build的参数或者环境变量。 (例:$GIT_COMMIT是git plugin提供的一个变量,存着当前build触发时最新的git code.) 如果要传递一个自定义的变量怎么办呢? 构建步骤中的自定义变量在执行结束后都会被回收,我们不可能在”predefined parameters”中取到。
依旧以编译任务为例,前端代码的提交不需要触发编译,没有编译也就不需要执行接下来的『run_ut』单元测试。(泛指后台代码的UT, JS UT这种稀有存在暂不考虑)
如何将编译的状态告诉下游的单元测试呢?
聪明的你想起了场景一的解决办法。对,我们也可以通过读写文件的方式来解决这个问题嘛!
不过这里我不推荐大家采用这种方式,理由有两点:
一,『run_compile』和『run_ut』有可能被部署在不同slave上,如果考虑更加智能的CI配置方式会在构建时动态的选择空闲的slave去执行,这种文件读写的方式就有了很大的局限性;
二,很难确保文件传递的准确性,如果『run_compile』写入文件失败,『run_ut』中读到的就是一个旧值一个不准确的值。
解决方案一:通过properties file的方式传递参数。
首先将变量以”xx=xx”的样式写入到配置文件『propfile.txt』中。
[Jenkins]Job中如何传递自定义变量 - 网易杭州QA - 网易杭州 QA Team
然后在”Trigger parameterized build on other projects”中选择”Parameters from preperties file”,在propfile里写入多个变量就可以传递多个值。
[Jenkins]Job中如何传递自定义变量 - 网易杭州QA - 网易杭州 QA Team

建议勾选”Don’t trigger if any files are missing”和删除旧文件配合使用。

最后在『run_ut』中可以直接获取这个变量来使用了。
[Jenkins]Job中如何传递自定义变量 - 网易杭州QA - 网易杭州 QA Team
解决方案二: 通过EnvInject Plugin插件
EnvInject Plugin可以支持修改、注入和删除环境变量。
我们在构建中增加步骤”Inject environment variables”, 将写在配置文件中的变量${IFUT},注入到环境变量里。
[Jenkins]Job中如何传递自定义变量 - 网易杭州QA - 网易杭州 QA Team
这样在”Trigger parameterized build on other projects”就可以直接选择”predefined parameters”方式直接传递变量了。同样的在Job『run_deploy』里就可以直接访问变量${IFUT}了。
[Jenkins]Job中如何传递自定义变量 - 网易杭州QA - 网易杭州 QA Team

本次要分享的内容就这么多。

最后有一个槽点:
为什么jenkins不支持根据条件判断来决定是否触发下一个Project呢?
实际上我最希望的是当ifut=false的时候就直接不触发『run_ut』,『run_ut』不被触发也就省去了不少无用功。

Jmeter正则表达式提取器的使用方法

下面简单介绍一下Jmeter正则表达式提取器的使用方法。
1、添加Jmeter正则表达式提取器:在具体的Request下添加Jmeter正则表达式提取器(Jmeter正则表达式在“后置处理器”下面)
例1如下:
引用名称: tokenid(自己定义)
正则表达式:
模板:$1$
匹配数字(0代表随机):
缺省值:
例2如下: 在生成的值是在cell中的时候,特别是有很多明细的。
引用名称: partDetailId(自己定义)
正则表达式:(.+?)
模板:$1$
匹配数字(0代表随机):5 (代表是第6个,从0开始算起)
缺省值:
位置1:名称及注释
位置2:正则表达式提取内容的范围。(关于各字段的详细说明请查阅协议的相关说明)
位置3:正则表达式提取的相关设置
引用名称:其他地方引用提取值的变量名称,如填写的是:str,具体的引用方式是${str}
正则表达式:提取内容的正则表达式【稍注意一下:()表示提取,对于你要提前的内容需要用小括号括起来】
模板:用$$引用起来,如果在正则表达式中有多个提取表达式(多个括号括起来的东东),则可以是$1$,$2$等等,表示解析到的第几个值给str,正则表达式的提取模式,值从1开始,值0对应的是整个匹配的表达式 如对于表达式s(.*) 值0对应str,值1对应tr
匹配数字(0代表随机):0代表随机,-1代表所有,其余正整数代表将在已提取的内容中,第几个匹配的内容。
缺省值:正则匹配失败时,取的值
一个符合要求的正则表达式:name = “file” value = “(.+?)”>。
():封装了待返回的匹配字符串。
.:匹配任何字符串。
+:一次或多次。
?:不要太贪婪,在找到第一个匹配项后停止

关于selenium自动化测试过程中汉字出现乱码的解决方式(perl)

最近在使用selenium做WEB自动化测试,但发现了一个比较恼火的问题,就是我们如果在自动化过程中输入内容,或者页面上的标签是汉字的话,在录制完成运行脚本的时候,存在汉字的那行脚本代码会报错。
本人使用的是Perl+selenium RC 来运行的测试脚本。在找了网上是资料后发现几种方式都不行。
先附上:找到的两种解决方式 (进过验证对我的环境都无效,)
方法1:启动selenium RC的时候附上参数
#################################################################################
最开始用 java -jar selenium-server.jar,未加任何参数,结果就出现乱码问题,加上-Dfile.encoding=”Unicode” 参数则问题解决,注意是Unicode,经测试UTF-8也不行,不知是否和我操作系统的字体有关,我是win7操作系统。
解决乱码的完整启动命令行 :
java -jar selenium-server.jar -Dfile.encoding=”Unicode”
################################################################################
方法2:将汉字转换成unicode
#################################################################################
use strict;
use warnings;
use Encode qw/encode decode/;
use Time::HiRes qw(sleep);
use Test::WWW::Selenium;
use Test::More “no_plan”;
use Test::Exception;
#步骤3:创建selenium会话,打开百度主页
our $sel = Test::WWW::Selenium->new(
host => “localhost”,
port => “4444”,
browser => “*chrome”,
browser_url => “http://www.baidu.com”);
$sel->open_ok(“/”);
my $chinese_text = “新 闻”;
my $decode_text = decode(“cp936”,$chinese_text);//此处转换为啥是CP936?,一直不明白
$sel->click_ok(“link=$decode_text”);
################################################################################
经IE查看页面编码格式是unicode(utf-8),多次尝试最后将上面两中方式结合,将输入内容转换为utf-8
终于成功通过脚本的运行
====================================================================
use strict;
use warnings;
use Time::HiRes qw(sleep);
use Test::WWW::Selenium;
use Test::More “no_plan”;
use Test::Exception;
use Encode;//使用encode 进行格式转码
my $sel = Test::WWW::Selenium->new( host => “localhost”,
port => 4444,
browser => “*chrome”,
browser_url => “http://192.168.1.93:8888/EIMSAdmin/Home/Login” );
$sel->open_ok(“/EIMSAdmin/Home/Login”);
my $logincalss= “管理员登陆”;
$logincalss = decode(“utf-8”,$logincalss);//将汉字强制转换成utf-8格式的放到变量$logincalss中
$sel->select_ok(“id=type”, “label=$logincalss”);
$sel->type_ok(“id=UserName”, “liuhubo”);
$sel->type_ok(“id=Password”, “123456”);
$sel->click_ok(“css=input.userLoginBtn”);
$sel->wait_for_page_to_load_ok(“30000”);

mysql读书笔记

闲来无事对MYSQL的读书笔记进行了一下整理,记录下来。难道真的是人老了,记性越来越差了。
数据库的基本概念
data 数据
database 数据库
DBMS 数据库管理系统
DBS 数据库系统
sql 是结构化查询语言
##########################################################################################################################
数据类型种类
整形: 可以有十进制和十六进制表示
符点形: 浮点数由一个数字加一个小数点再加上一个数字组成。两个数字序列不能同时为空。
字符串: 由单引号或者双引号括起来的字符或者数字,字符串中要用转义字符才能表示的特殊符号。
NUUL值: 是一种无类型的值,表示“空,什么也没有”。
日期和时间的值:列如 2005-05-30 12:30:25 日期是按年-月-日
_##########################################################################################################################
数值类型
TINYTIN 非常小的整数 BIGINT 大整数
SMALLINT 较小的整数 FLOAT 单精度浮点数
MEDIUMINT 中等大小的整数 DOUBLE 双精度浮点数
INT 标准整数 DECIMAL 一个串的浮点数
CHAR 定长字符串 VARCHAR 可变长字符串
TINYBLOB 非常小的BLOB BLOB 小BLOB
MEDIUMBLOB中等BOLB LONGBLOB 大BLOB
TINYTEXT 非常小的文本串 TEXT 小文本串
MEDIUMTEXT中等文本 LONGTEXT 大文本串
ENUM 枚举:列可赋予某个枚举成员
SET 集合:列可赋予多个集合成员
##########################################################################################################################
not null 非空 primary key 主键 auto_increment 自增
常见的完整性约束
primary key 主码约束(主键) 主码就是主关键字,能唯一标示字段属性
unique 唯一约束 在一个字段或者一组字段里数据与表中其它行的数据相比是唯一的
not null 非空值约束
auto_increment 整数列自增1
default_value 默认值约束
##########################################################################################################################
mysql -h主机名 -u用户名 -p密码 //mysql登陆运行命令
######mysql输入一个语句结尾时,末尾要有;号。->意为本语句没有输完 等待继续输入。c用来取消输入。
auto_increment 自动标识列
对于想使用此属性的列应该定义为NOT NULL,并定义为PRIMARY KEY 或者定义为UNIQUE键。
unsigned无符号,此属性禁用负值,是将数值的取值范围从零开始,即前移了取值范围而已.
##########################################################################################################################
DML数据操作语言
select 查询
insert 插入
update 修改
delete 删除
##########################################################################################################################
DCL数据控制语言
grant 控制存取许可
revoke 存取权限
##########################################################################################################################
ddl数据定义语言
create table 创建数据表
create database 创建库名
drop table 数据库对象
alter table 定义其列
##########################################################################################################################
use 库名 选择使用数据库 例如:use book;
##########################################################################################################################
创建数据库
create database 库名; 创建一个指定名称的数据库
例如:create database book; 创建了一个名为book的数据库
##########################################################################################################################
删除数据库或表操作
drop table 表名 删除表 drop table if exists badbird;加if exists 删除不存在表名不会出错
drop database 库名 删除库 同上加if exists不会出错
##########################################################################################################################
显示结构操作
database 表名
desc 表名
##########################################################################################################################
show用法
show tables或show tables from database_name like; — 显示当前数据库中所有表的名称。
show databases; — 显示mysql中所有数据库的名称。
show columns from table_name from database_name;
show columns from database_name.table_name; — 显示表中列名称。
show grants for user_name; — 显示一个用户的权限,显示结果类似于grant 命令。
show index from table_name; — 显示表的索引。
show status; — 显示一些系统特定资源的信息,例如,正在运行的线程数量。
show variables; — 显示系统变量的名称和值。
show processlist; — 显示系统中正在运行的所有进程,也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查看所有人的进程,包括密码。
show table status; — 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间。
show privileges; — 显示服务器所支持的不同权限。
show create database database_name;– 显示create database 语句是否能够创建指定的数据库。
show create table table_name; — 显示create database 语句是否能够创建指定的数据库。
show engies; — 显示安装以后可用的存储引擎和默认引擎。
show innodb status; — 显示innoDB存储引擎的状态。
show logs; — 显示BDB存储引擎的日志。
show warnings; — 显示最后一个执行的语句所产生的错误、警告和通知。
show errors; — 只显示最后一个执行语句所产生的错误。
show [storage] engines; –显示安装后的可用存储引擎和默认引擎。
##########################################################################################################################
select用法
select prod_uame from products; –查询从products表中检索出名字为prod_nume的列(无序排列)
select prod_uame,user, password from products; –查询从products表中检索出名字为prod_nume,user, password的列
select * from products; –查询从products表中检索出全部列(*表示匹配所有的)
select distinct prod_id from products; –查询从products表中检索出名字为prod_id的列(只返回唯一的prod_id行)
select prod_uame from products limit 5; –查询从products表中检索出名字为prod_nume的列不超过5行(无序排列)
select prod_uame from products limit 5,6; –查询从products表中检索出名字为prod_nume从行5开始共6列(行从0开始计算)
select prod_uame from products limit 6 offset 5; –查询从products表中检索出名字为prod_nume从行5开始共显示6列(行从0开始计算)
select products.prod_uame from database.products; –查询从database库中products表中检索出名字为prod_nume的列(无序排列)
select prod_price from products order by prod_price DESC limit1; –查询从products表中检索出名字为prod_price的列最大的值(无序排列)
select prod_price from products where prod_price=2; –查询从products表中检索出名字为prod_price的列中值为2的列(无序排列)
##########################################################################################################################
更改表结构操作
语法:alter table 表名 action;
说明:action 可以是如下语句:
add 列名 <建表语句> [first | after 列名]
add primary key (列名)为表添加一个主键,如果主键已经存在,则出现错误
alter 列名 set default 默认值 可以更改指定列默认值
———————————————————-
later table 表名 add 插如列的名 varchar(属性) first(之前)|after(之后) 增加列名
change 旧列名 新列名 <建表语句> [first | after 列名]
可以更改列类型和列名称,如果原列的名字和新列的名字相同,则change和modify的作用相同
———————————————————–
modify 列名 <建表语句> [first | after 列名]
更改列属性:alter table badbird(表名) badtitle(列) modif varchar(属性);
更改列名:alter table badbird(表名) change badtitle(列) bad_sad(改的名) varchar(属性) not null(no 空);
drop 列名 //可以删除一列
drop primary key //可以删除主键
drop index index_name; //可以删除索引
删除列:alter table badbird(表名) drop badtitle;
rename as 新表名 //可以将表名更改
更改表名:alter table badbird(表名) rename badwolf(表名);
##########################################################################################################################
插入记录操作
语法:
insert into 表名(字段名,字段名, … ) values(字段值,字段值,…);
例如:insert into badwolf (bad_id,bad_name) values(3,’badbird’); 插入
如果表名后面没写字段名,则默认是向所有的字段添加值,另外字符串值应该用‘ ’或“ ”引号括起来
多条添加:insert into badwolf values(1,’badbird’),(2,’badbird’),(4,’badbird’);
更改记录操作
语法:
update 表名 set 列名=数据值 where 子句;
例如:update badwolf(表名) set bad_name(列名)=’badwolf’;
——————————————————————
where 子句是判断语句,用来设定条件,限制只更新匹配的行,如果不带where子句,则更新所有行数据
删除记录操作 语法: delete from 表名 where子句;
例如:delete from badwolf(表明) where bad_id=2; 判断删除所有id=2的值 判断条件可以附加
null和not null
缺省为null(空)即插入值时没有在此字段插入值,默认为NULL值.
如果指定了NOT NULL,则必须在插入值时在此字段添入值,不允许插入NULL值。
default 通过此属性来指定缺省值,如果没有添加值则默认此值。
zerofill 前导零填充数值类型以达到列的显示宽度。
例如:create table badbird(
bad int,
bad unsigned,(无符号,将数值的取值范围从零开始)
bad unsigned zerofill,(无符号,将数值的取值范围从零开始|前导零填充数值类型以达到列的显示宽度)
bad unsigned zerofill,(无符号,将数值的取值范围从零开始|前导零填充数值类型以达到列的显示宽度)
insert into badbird values(10,10,10,10);
结果:10,10,0000000010,0000000010。 整形获取值为10,从零开始获取也是10,从零开始以0做填充
insetr into badbird values(-10,-10,-10,-10);
结果:-10,0,0000000000,0000000000。整形获取值为10,从零开始,从零开始以0做填充
insert into badbird values(2147483647,2147483647,2147483647,2147483647)
结果:2147483647,2147483647,2147483647,2147483647。整形获取值为10,从零开始获取也是10,从零开始以0做填充 无填充
insert into badbird values(3004005006,3004005006,3004005006,3004005006);
结果:2147483647,3004005006,3004005006,3004005006。int标准整形最大值
字符串列类型的属性
binary
使用此属性可以使列值作为二进制串处理,即比较和排序时区分大小写。
NOT 和NOT NULL
同数值型功能相同
default
同数值型功能相同
日期和时间列表
date YYYY-MM-DD 格式表示日期值 3字节
time hh:mm:ss 格式表示时间值 3字节
datetime 时间-日期 8字节
timestamp 时间戳 4字节 时间戳=mysql的时间戳是1970年到至今的豪秒数
tyar YYYY年份 1字节
now() 函数自动获取本地时间
mysql算术运算符
+加 -减 -负 *乘 /除 %取余
如果第一位是数字的字符串被用于一个算数运算中,那么它被转换为这个数字的值。
如果一个包含字符和数字混合的字符串不能被正确的转换为数字,那么它被转换成0。
##########################################################################################################################
mysql比较运算符
and 并且
or 或
= 两个操作数相等 为true
!=|<> 两个操作数不等 为true
< <= > >= 不用解释你要不知道我也没办法
in 如果a为b1,b2中的任何一个 为true
between 如果A的值 在b1与b2之间包括等于b1b2 为true b1必须比b2大
like 模式匹对 如果a匹对b 为true
notlike 模式匹对 如果a不匹对b 为true
regexp 同like
not regexp 同notlike
<=> a<=>b 如果两者操作数相同 即使null 为true
is null 如果操作数为null 为true
is not null 如果操作数不为空 为true
再次声明mysql 不区分大小写
%号表示以A开头 任意后缀结尾
_号表示A开头 后缀任意字
##########################################################################################################################
查询记录操作
语法:
select 字段名,字段名, … (*) from 表名 where 子句 group by子句having子句 order by子句 limit子句 desc(asc)
group by子句是对匹配where子句的查询结果进行分组
having子句是对分组后的结果进行条件限制
order by子句是对查询结果结果进行排序,后面跟desc或asc。 
limit子句是对查询的显示结果限制数目
desc是将最终结果进行降序排列,asc是将最终结果进行升序。
例如:select * from badbird(表名) where fi=10条件;
##########################################################################################################################
MySQL数据库管理
数据库的启动与关闭,安全、访问控制和权限,数据库的备份与恢复,导入和导出记录
数据库管理员的职责
服务器的启动与关闭
用户帐户维护
日志文件维护
数据库的备份与拷贝
服务器的优化
数据库管理系统的软件更新
数据目录的安全性
服务器的安全性
灾难恢复
预防性维护
##########################################################################################################################
数据库的启动与关闭
1、数据库的启动:
方法1:使用service 命令启动MySQL
# service mysqld start // mysqld是MySQL的守护进程,通过运行它来启动MySQL服务。
方法2:使用mysqld脚本启动MySQL
# /etc/init.d/mysqld start
方法3:使用safe_mysqld实用程序启动MySQL服务,此方法可以使用相关参数
# safe_mysqld& //使用&符号将safe_mysqld放在后台运行。
2,校验MySQL是否被启动:
# service mysqld status //返回如下信息,表示已经启动
mysqld (pid 1663) is running… //1663是mysqld运行的进程号,可能根据不同系统运行的进程数量而不同
若需要重新启动MySQL可以使用如下命令之一:
# service mysqld restart
# /etc/init.d/mysqld restart
3、数据库的关闭:
可以使用如下命令之一:
# service mysqld stop
# /etc/init.d/mysqld stop
# /mysqladmin shutdown
##########################################################################################################################
######### MySQL管理 MySQL管理 MySQL管理 MySQL管理 MySQL管理 #####
######### MySQL管理 MySQL管理 MySQL管理 MySQL管理 MySQL管理 #####
######### MySQL管理 MySQL管理 MySQL管理 MySQL管理 MySQL管理 #####
##########################################################################################################################
一,修改root管理密码
方法1:
mysql>set password for ‘帐号’@‘主机’ = old_password(‘输入新密码’);
update mysql.user set password = old_password(‘输入新密码’) where host = ‘主机’ and user = ‘帐号’;
flush privileges;
方法2:
mysqladmin -u 用户 -p 旧密码 password ‘新密码’;
用户密码
对于MySQL密码可以使用PASSWORD()和ENCRYPT()函数进行加密
mysql>select PASSWORD(“alex”);
“23fc96e064be0017”
注:ENCRYPT()在Windows上不可用
方法3:
使用update语句和password()函数将root口令设置为crp。
mysql> update mysql.user set password=password(‘crq’) where user=’root’; //返回如下信息,表示授权表user修改成功
Query OK, 2 row affected (0.09 sec)
Rows matched:2 changed:2 warnings: 0
mysql> flush privileges; //此时即生效可以使用。注意:由此种方法是直接对授权表user进行修改,而服务器只有在启动时才会加载授权表中的权限设置,因此必须要使用客户端程序mysql环境下的flush privileges命令或使用管理工具mysqladmin的flush-privileges子命令通知服务器重新加载授权表。
##########################################################################################################################
二,改变数据库存储路径
在Window下,MySQL的所有数据库都保存在“%mysqlroor%data”目录下。
停止MySQL服务
修改%systemroor%my.ini文件
[mysqld]
datadir=D:/data
将原目录中的所有文件和文件夹内容,全部移动到新的目录D:/data目录中。
重启MySQL服务
##########################################################################################################################
三,修改MySQL字符集
找到MySQL配置文件my.ini,一般在C:windowmy.ini。
在my.ini文件里面加上“default-character-set=gbk #”或gb2312,utf8
重启MySQL服务
##########################################################################################################################
四,删除匿名用户:
myslq> delete from user where user=’ ‘;
//返回如下信息,表示匿名用户删除成功
Query OK, 2 row affected (0.03 sec)
##########################################################################################################################
五,添加新的用户权限:
使用grant语句用于授予用户权限,
语法:
GRANT priv_type[(column_list)][,priv_type[(column_list)]…]
ON {*.* | * | db_name.* | db_name.tabl_name | db_name}
TO user_name [IDENTIFIED BY ‘password’]
[,user_name [IDENTIFIED BY ‘password’]…]
[WITH GRANT OPTION]
##########################################################################################################################
六,创建新用户
制定用户名,最长允许为16个英文字符
制定允许该用户可以访问的数据库和表
制定允许该用户对数据库做什么的操作
制定允许该用户从哪些主机/IP进行远程连接
制定允许该用户对其他用户进行授权或取消授权
例如:添加一个可以从本地主机连接到MySQL服务器的超级用户crq,但是连接时必须使用口令crqpass
mysql> grant all on *.* tocrq@localhostidentfied by ‘crqpass’ with grant option;//返回如下信息,表明权限设置成功
Query OK, 0 rows affected (0.02 sec)
例如:使用同样的方法添加一个可以从其他任何地方连接到MySQL服务器的超级用户crq,但是连接时必须使用口令crqpass
mysql> grant all on *.* tocrq@’%’identified by ‘crqpass’ with grant option;
##########################################################################################################################
七,授予用户特定的权限:
使用grant语句添加一个可以从本地机连接的MySQL服务器的用户user1,并且只授予其针对sales数据库中employee表的select和insert权限。
mysql> grant select,insert on sales.employee touser1@localhostidentified by ‘user1pass’;
说明:使用:# mysql –u user1 –puser1pass 登录数据库以后可以做如下操作:
mysql> use sales; //打开sales数据库
mysql> show tables; //只能看到employee表
mysql> select * from employee; //可进行查看操作
mysql> insert into employee ……. //可进行插入操作。
##########################################################################################################################
八,撤销用户权限:
语法:REVOKE priv_type[(column_list)][,priv_type[(column_list)]…]
ON {*.* | * | db_name.* | db_name.tbl_name | db_name}
FROM user_name [,user_name…]
例如:撤消用户user1针对sales数据库中employee表的insert权限:
mysql> revoke insert on sales.employee fromuser1@localhost;
//返回如下信息,表明权限撤销成功。
Query OK, 0 row in set affected (0.00 sec)
##########################################################################################################################
九,权限更改何时生效
当mysqld启动时,所有的授权表内容被读进存储器并且从那点生效。
用GRANT、REVOKE或SET PASSWORD对授权表施行的修改会立即被服务器注意到。
如果你手工地修改授权表(使用INSERT、UPDATE等等),你应该执行一个FLUSH PRIVILEGES语句或运行mysqladmin flush-privileges告诉服务器再装载授权表,否则你的改变将不生效,除非你重启服务器。
##########################################################################################################################
十,权限更改的影响
当服务器注意到授权表被改变了时,现存的客户连接有如下影响:
表和列权限在客户的下一次请求时生效。
数据库权限改变在下一个USE db_name命令生效。
全局权限的改变和口令改变在下一次客户连接时生效。
##########################################################################################################################
十一, 数据库的备份与恢复
1、数据库的备份:
A、用mysqldump备份数据库:
语法: mysqldump [OPTIONS] database [table]
实例:
将数据库sales备份成sales_bak030630.sql文件。
# mysqldump –u root –p –opt sales > sales_bak030630.sql
//返回如下信息,表明备份成功
-rw-r–r– 1 root root 2296 Jun 29 23:30 sales_bak030630.sql
B、用直接拷贝的方法备份数据库:
不用mysqldump 来备份数据库或表的另一种方法是直接拷贝表文件。通常可利用像cp、tar 或cpio 这样的实用程序来进行。当使用直接拷贝备份( direct-copy backup)方法时,必须确保没有使用这些表。如果在拷贝一个表的同时服务器正在修改它,则拷贝无效。
确保拷贝完整性的最好方法是关闭服务器,拷贝文件,然后重新启动服务器。
2、数据库的恢复:
数据库系统出现崩溃时,应该使用最近的一次备份对数据库进行恢复,如果启用了更新日志,还需要重新执行更新日志中最近一次备份之后对数据库进行修改的任何查询,以尽可能将数据恢复到崩溃时刻所处的状态。
# mysql –u root –p sales < sales_bak030630.sql ########################################################################################################################## 优化表 在大多数情况下,优化表的做法很值得。当一个表被多次修改,那它的结构将很快变得支离破碎,其结果是导致性能的下降。这个时候可以使用OPTIMIZE TABLE 命令来刷新,清理出空间。 mysql>OPTIMIZE TABLE tablename;
##########################################################################################################################
导入和导出记录
INSERT语句不是向表中插入记录的唯一方法,MySQL还允许使用LOAD DATA INFILE 命令一次性插入多条记录。这个命令可以从文本文件读出原始数据(该文件可以放置在连接服务器上或者客户端),在列和行界定符号的基础上进行分析,然后自动产生INSERT 语句来向一个表写数据。
导入数据
默认情况下,MySQL认为数据文件是在服务器上,在LOAD DATA INFILE 语句中指定位置。
如果想要使用客户机上的数据,可以在语句中添加LOCAl关键字,告诉MySQL在客户机的文件系统上查找文件。
mysql>LOAD DATA LOCAL INFILE ‘c:data.txt’
INTO TABLE user
FIELDS TERMINATED BY ‘,’ LINES TERMINATED BY ‘n’;
最好在此之前加上如下命令
mysql>LOAD DATA LOW_PRIORITY INFILE ‘data.txt’ INTO TABLE user;
当然还有IGNORE REPLACE等关键字。
导出数据
如果不指定一个FIELDS子句,缺省值与这样写的相同:
FIELDS TERMINATED BY ‘t’ ENCLOSED BY ” ESCAPED BY ”
如果不指定一个LINES子句,缺省值与这样写的相同:
LINES TERMINATED BY ‘n’
换句话说,缺省值导致读取输入时,LOAD DATA INFILE表现如下:
在换行符处寻找行边界
在定位符处将行分成字段
不要期望字段由任何引号字符封装
将由“”开头的定位符、换行符或“”解释成字段值的部分字面字符
导出数据
相反,缺省值导致在写入输出时,SELECT … INTO OUTFILE表现如下:
在字段之间写定位符
不用任何引号字符封装字段
使用“”转义出现在字段中的定位符、换行符或“”字符
在行尾处写换行符
注意,为了写入FIELDS ESCAPED BY ”,对作为一条单个的反斜线被读取的值,你必须指定2条反斜线值。
##########################################################################################################################

使用LR的socket协议进行进行性能测试

在公司的产品基本的功能测试做的差不多了之后,该做性能测试了,但发现一个问题,因为产品是属于嵌入式的产品终端的和B/S架构的软件结合使用的,而软件使用最容易造成瓶颈的地方不是系统B/S架构部分,而是在来源于终端对前置服务器和数据处理中心的压力。
我们又不可能有那么多的终端来同时产生压力,终端软件又是运行于ARM平台上的,连录制脚本的机会都没有。于是找终端开发的人员进行了了解,从他们那里了解到这边终端和前置服务器的连接采用的是tcp/ip协议进行通信。通过查找资料,发现我们LR的windows sockets协议可以模拟tcp/ip协议和前置服务器进行数据交互,这样便可以模拟终端来进行性能测试了。
还好几大中心集成测试的时候都是让开发给了他们的设计文档,对各个模块通信的数据格式还是比较了解,开着抓包工具,很快抓到了他们通信的数据包。
根据资料将数据分别填写到脚本中
user_init部分
/*********************************************************************
* Created by Mercury Interactive Windows Sockets Recorder
*
* Created on: Thu Jul 05 14:19:06
*********************************************************************/
#include “lrs.h”
vuser_init()
{
lrs_startup(257);
lrs_create_socket(““, “TCP”, “LocalHost=0″,”RemoteHost=192.168.1.9:9999”, LrsLastArg);//选择协议方式,接收数据的前置服务器IP:端口 与服务器建立socket连接。
return 0;
}
****************************************************************
//action 部分
Action()
{
lrs_send(““, “buf5”, LrsLastArg);//发送buf5中的数据到服务器,开始公话认证
return 0;
}
*************************************************************** //user_end 部分
vuser_end()
{
lrs_cleanup();//断开建立的TPC连接
return 0;
}
****************************************************************
//data.ws 部分
;WSRData 2 1
send buf5 44 //定义发送的内容变量buf5和信息的长度
“xaax00x1cx00x00x00x00x00xcax10x05x00x07x00x00xacx00x00x00xd3x00x00x00x34x00x00x00x03x00x00x00x03x00x00x00x00x00x00x00x00x27xfbx1fxee”//因为发送数据为16进制所以每个数据字段前需要添加x
弄好脚本后dubug了几次发现都能收到前置服务器的回应,但现在又面临了其他问题,如果每次发送的费用流水到数据处理中心都一样的话,数据处理中心会认为是重复流水,并不会进入数据处理流程进行处理。
这样就需要我们自己来生成发送的数据,除开消息的报文头,经历过一系列操作的随机变量转为16进制后,发送到前置竟然得不到回复信息了。检查了多次消息格式都是正确,找来开发的同事一问结果消息中还有信息的验证字段。因为生成的信息格式虽然正确但是效验不过,被认为是出错的数据包,前置服务器直接将数据包丢弃。又调用了他们的生成验证字段的dll生成效验字段后总算再次得到了回复,经过dba修改存储过程中对数据的效验后跑通了整个流程。
开启性能测试后对多个节点进行了跟踪,发现前置服务器这里收到数据后一段时间后不在对我们的消息进行回复,然后就前置就崩溃了,进过分析发现,前置服务器,因为数据处理中心接收处理数据缓慢,将数据都堆积到了缓存中,结果数据太多后,内存溢出程序崩溃。
最后在接收中心和处理中心分别添加缓存机制,数据处理中心先将数据接收过来在由另外的线程进行处理,同时前置将数据进行打包发送,不在一条一条的进行发送后,在进行压力测试,前置服务器崩溃的问题虽然解决了,但数据处理中心调用存储过程来处理数据依然缓慢,达不到系统的业务需求,又增加数据处理线程,几经周折终于达标了。
性能测试,想说爱你不容易啊。

Jenkins内置环境变量

一、查看Jenkins有哪些环境变量
1、新建任意一个job
2、增加构建步骤:Execute shell 或 Execute Windows batch command
3、点击输入框下方的“可用环境变量”

4、可以看到有如下变量供使用:

变量名 解释
BUILD_NUMBER The current build number, such as “153”
BUILD_ID The current build ID, identical to BUILD_NUMBER for builds created in 1.597+, but a YYYY-MM-DD_hh-mm-ss timestamp for older builds
BUILD_DISPLAY_NAME The display name of the current build, which is something like “#153” by default.
JOB_NAME Name of the project of this build, such as “foo” or “foo/bar”. (To strip off folder paths from a Bourne shell script, try: ${JOB_NAME##*/})
BUILD_TAG String of “jenkins-${JOB_NAME}-${BUILD_NUMBER}”. Convenient to put into a resource file, a jar file, etc for easier identification.
EXECUTOR_NUMBER The unique number that identifies the current executor (among executors of the same machine) that’s carrying out this build. This is the number you see in the “build executor status”, except that the number starts from 0, not 1.
NODE_NAME Name of the slave if the build is on a slave, or “master” if run on master
NODE_LABELS Whitespace-separated list of labels that the node is assigned.
WORKSPACE The absolute path of the directory assigned to the build as a workspace.
JENKINS_HOME The absolute path of the directory assigned on the master node for Jenkins to store data.
JENKINS_URL Full URL of Jenkins, like http://server:port/jenkins/ (note: only available if Jenkins URL set in system configuration)
BUILD_URL Full URL of this build, like http://server:port/jenkins/job/foo/15/ (Jenkins URL must be set)
SVN_REVISION Subversion revision number that’s currently checked out to the workspace, such as “12345”
SVN_URL Subversion URL that’s currently checked out to the workspace.
JOB_URL Full URL of this job, like http://server:port/jenkins/job/foo/ (Jenkins URL must be set)

 
二、使用Jenkins的内置变量
1、在Execute shell 或 Execute Windows batch command文本框中使用,使用方法:%变量名%,如下图

2、结合Ant,在build.xml文件中使用:
1、添加如下第4行代码:<property environment=”env”/>
2、使用方法:${env.WORKSPACE}

 1 <?xml version="1.0" encoding="UTF-8"?>
 2
 3 <project name="ant-test" default="run" basedir=".">
 4     <property environment="env"/>
 5
 6     <target name="clean">
 7         <mkdir dir="${env.WORKSPACE}/results/${env.BUILD_ID}" />
 8     </target>
 9
10 </project>

接口测试之——soapui学习(1)

      WebService
它是一种构建应用程序的普遍模型,可以在任何支持网络通信的操作系统中实施运行;
它是一种新的web应用程序分支,是自包含、自描述、模块 化的应用,可以发布、定位、通过web调用。
Web Service是一个应用组件,它逻辑性的为其他应用程序提供数据与服务.各应用程序通过网络协议和规定的一些标准数据格式(Http,XML,Soap)来访问Web Service,通过Web Service内部执行得到所需结果.
Web Service可以执行从简单的请求到复杂商务处理的任何功能。一旦部署以后,其他Web Service应用程序可以发现并调用它部署的服务。
——————
在构建和使用Web Service时,主要用到以下几个关键的技术和规则:
1.XML:描述数据的标准方法.
2.SOAP:表示信息交换的协议.
3.WSDL:Web服务描述语言.
4.UDDI通用描述、发现与集成,它是一种独立于平台的,基于XML语言的用于在互联网上描述商务的协议。
FONT style=”BACKGROUND-COLOR: rgb(0,255,0)”>http://www.webxml.com.cn/zh_cn/index.aspx   这个网站中有不少免费的WebService可用
——————我个人觉得下面的这个理解起来更容易些,甚至我都觉得他有点想API,只是放到web中了而已————————-
1,什么是 Web Service?
Web Service 就是一个网络组件(一个可以通过网络访问的程序)。
它有一个或多个端口(Port),这些端口用于接收客户端的请求,并返回响应
请求和响应的 都是一种基于XML的消息。 不过这种消息遵循特定的格式(SOAP )。

2,怎样调用 Web Service?
   可能这样说不太准确,应该是“怎样调用Web Service中定义的操作 ”
每个Web Service 都有一个描述文件(WSDL ),
它描述 一个 Web Service 的如下方面:
(1)服务的端口(接收SOAP消息的端口)
(2)服务提供的操作
(3)操作的输入输出格式的定义(通过XMLSchema 定义输入输出格式)
有了Web Service 的描述文件(WSDL ),我们就知道怎样调用这个Web Service 中定义的操作了。
(1)通过服务提供的操作找到你想调用的操作
(2)找到这个操作的输入格式的定义(XMLSchema ),按照这种输入格式构造一个SOAP消息
(3)将这个SOAP消息发送到服务的指定端口
(4)准备接收一个从Web Service服务器返回的 SOAP 响应吧 !

3,Web Service服务器
   一个Web Service服务器,本质上和一个Web服务器是相同的。
它主要做下面这些事:
–> 监听网络端口(监听服务端口)
–> 接收客户端请求(接收SOAP请求)
–> 解析客户端请求(解析SOAP消息,将SOAP消息转换为数据对象)
–> 调用业务逻辑 (调用Web Service实现类的特定操作,参数是由SOAP消息转换而来的数据对象)
–> 生成响应 (将返回值转换为SOAP消息)
–> 返回响应 (返回SOAP响应)
 
=================================================================================
XML
什么是 XML?
·         XML 指可扩展标记语言(EXtensible Markup Language)
·         XML 是一种标记语言,很类似 HTML
·         XML 的设计宗旨是传输数据,而非显示数据
·         XML 标签没有被预定义。您需要自行定义标签。
·         XML 被设计为具有自我描述性。
·         XML 是 W3C 的推荐标准
XML 与 HTML 的主要差异
XML 不是 HTML 的替代。
XML 和 HTML 为不同的目的而设计:
XML 被设计为传输和存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。
HTML 旨在显示信息,而 XML 旨在传输信息。
没有任何行为的 XML。XML 是不作为的。也许这有点难以理解,但是 XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息。
下面是 John 写给 George 的便签,存储为 XML:

        <note><to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don’t forget the meeting!</body>
</note>

       这个标签有标题以及留言。它也包含了发送者和接受者的信息。但是,这个 XML 文档仍然没有做任何事情。它仅仅是包装在 XML 标签中的纯粹的信息。我们需要编写软件或者程序,才能传送、接收和显示出这个文档。
XML 仅仅是纯文本
XML 没什么特别的。它仅仅是纯文本而已。有能力处理纯文本的软件都可以处理 XML。
不过,能够读懂 XML 的应用程序可以有针对性地处理 XML 的标签。标签的功能性意义依赖于应用程序的特性。
通过 XML 您可以发明自己的标签
上例中的标签没有在任何 XML 标准中定义过(比如 <to> 和 <from>)。这些标签是由文档的创作者发明的。这是因为 XML 没有预定义的标签。在 HTML 中使用的标签(以及 HTML 的结构)是预定义的。HTML 文档只使用在 HTML 标准中定义过的标签(比如 <p> 、<h1> 等等)。XML 允许创作者定义自己的标签和自己的文档结构。
XML 不是对 HTML 的替代
XML 是对 HTML 的补充。XML 不是对 HTML 的替代,理解这一点很重要。在大多数 web 应用程序中,XML 用于传输数据,而 HTML 用于格式化并显示数据。
XML 应用于 web 开发的许多方面,常用于简化数据的存储和共享。
XML 把数据从 HTML 分离
如果你需要在 HTML 文档中显示动态数据,那么每当数据改变时将花费大量的时间来编辑 HTML。通过 XML,数据能够存储在独立的 XML 文件中。这样你就可以专注于使用 HTML 进行布局和显示,并确保修改底层数据不再需要对 HTML 进行任何的改变。通过使用几行 JavaScript,你就可以读取一个外部 XML 文件,然后更新 HTML 中的数据内容。
XML 简化数据共享
在真实的世界中,计算机系统和数据使用不兼容的格式来存储数据。XML 数据以纯文本格式进行存储,因此提供了一种独立于软件和硬件的数据存储方法。这让创建不同应用程序可以共享的数据变得更加容易。
XML 简化数据传输
通过 XML,可以在不兼容的系统之间轻松地交换数据。对开发人员来说,其中一项最费时的挑战一直是在因特网上的不兼容系统之间交换数据。由于可以通过各种不兼容的应用程序来读取数据,以 XML 交换数据降低了这种复杂性。
XML 简化平台的变更
升级到新的系统(硬件或软件平台),总是非常费时的。必须转换大量的数据,不兼容的数据经常会丢失。XML 数据以文本格式存储。这使得 XML 在不损失数据的情况下,更容易扩展或升级到新的操作系统、新应用程序或新的浏览器。
XML 使您的数据更有用
由于 XML 独立于硬件、软件以及应用程序,XML 使您的数据更可用,也更有用。不同的应用程序都能够访问您的数据,不仅仅在 HTML 页中,也可以从 XML 数据源中进行访问。通过 XML,您的数据可供各种阅读设备使用(手持的计算机、语音设备、新闻阅读器等),还可以供盲人或其他残障人士使用。
XML 用于创建新的 Internet 语言
很多新的 Internet 语言是通过 XML 创建的:
其中的例子包括:
·  XHTML – 最新的 HTML 版本
·  WSDL – 用于描述可用的 web service
·  WAP 和 WML – 用于手持设备的标记语言
·  RSS – 用于 RSS feed 的语言
·  RDF 和 OWL – 用于描述资源和本体
·  SMIL – 用于描述针针对 web 的多媒体
假如开发人员都是理性的
假如他们都是理性的,就让未来的应用程序使用 XML 来交换数据吧。
未来也许会出现某种字处理软件、电子表格程序以及数据库,它们可以使用纯XML
=================================================================================
WSDL          什么是 WSDL?
·  WSDL 指网络服务描述语言
·  WSDL 使用 XML 编写
·  WSDL 是一种 XML 文档
·  WSDL 用于描述网络服务
·  WSDL 也可用于定位网络服务
·  WSDL 还不是 W3C 标准
WSDL 可描述网络服务(Web Services)
WSDL 指网络服务描述语言 (Web Services Description Language)。
WSDL 是一种使用 XML 编写的文档。这种文档可描述某个 Web service。它可规定服务的位置,以及此服务提供的操作(或方法)。
WSDL 文档仅仅是一个简单的 XML 文档。
它包含一系列描述某个 web service 的定义。
WSDL 文档结构
WSDL 文档是利用这些主要的元素来描述某个 web service 的:

元素 定义
<portType> web service 执行的操作
<message> web service 使用的消息
<types> web service 使用的数据类型
<binding> web service 使用的通信协议

一个 WSDL 文档的主要结构是类似这样的:

 <definitions>
<types>
definition of types……..
</types>
<message>
definition of a message….
</message>
<portType>
definition of a port…….
</portType>
<binding>
   definition of a binding….
</binding>
</definitions>

   PS:实际上以上的结构,可以用浏览器打开一个具体的webservice来看,比如以下查询手机归属地的wsdl格式的webservice
http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?wsdl

WSDL 文档可包含其它的元素,比如 extension 元素,以及一个 service 元素,此元素可把若干个 web services 的定义组合在一个单一的 WSDL 文档中。

WSDL 端口
<portType> 元素是最重要的 WSDL 元素。 它可描述一个 web service、可被执行的操作,以及相关的消息。 可以把 <portType> 元素比作传统编程语言中的一个函数库(或一个模块、或一个类)。
WSDL 消息
<message> 元素定义一个操作的数据元素。 每个消息均由一个或多个部件组成。可以把这些部件比作传统编程语言中一个函数调用的参数。
WSDL types
<types> 元素定义 web service 使用的数据类型。 为了最大程度的平台中立性,WSDL 使用 XML Schema 语法来定义数据类型。
WSDL Bindings
<binding> 元素为每个端口定义消息格式和协议细节。
 
WSDL 实例
这是某个 WSDL 文档的简化的片段:

 <message name=”getTermRequest”>
<part name=”term” type=”xs:string”/>
</message>
<message name=”getTermResponse”>
<part name=”value” type=”xs:string”/>
</message>
<portType name=”glossaryTerms”>
<operation name=”getTerm”>
<input message=”getTermRequest”/>
<output message=”getTermResponse”/>
</operation>
</portType>

       在这个例子中,<portType> 元素把 “glossaryTerms” 定义为某个端口的名称,把 “getTerm” 定义为某个操作的名称。
操作 “getTerm” 拥有一个名为 “getTermRequest” 的输入消息,以及一个名为 “getTermResponse” 的输出消息。
<message> 元素可定义每个消息的部件,以及相关联的数据类型。
对比传统的编程,glossaryTerms 是一个函数库,而 “getTerm” 是带有输入参数 “getTermRequest” 和返回参数 getTermResponse 的一个函数。

软件测试之黑盒——等价类划分

是把所有可能的输入数据,即程序的输入域划分成若干部分(子集),然后从每一个子集中选取少数具有代表性的数据作为测试用例.该方法是一种重要的,常用的黑盒测试用例设计方法.
1)划分等价类:等价类是指某个输入域的子集合.在该子集合中,各个输入数据对于揭露程序中的错误都是等效的.并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据.取得较好的测试结果.等价类划分可有两种不同的情况:有效等价类和无效等价类.
有效等价类:是指对于程序的规格说明来说是合理的,有意义的输入数据构成的集合.利用有效等价类可检验程序是否实现了规格说明中所规定的功能和性能.
无效等价类:与有效等价类的定义恰巧相反.
设计测试用例时,要同时考虑这两种等价类.因为,软件不仅要能接收合理的数据,也要能经受意外的考验.这样的测试才能确保软件具有更高的可靠性.
2)划分等价类的方法:下面给出六条确定等价类的原则.
①在输入条件规定了取值范围或值的个数的情况下,则可以确立一个有效等价类和两个无效等价类.
②在输入条件规定了输入值的集合或者规定了“必须如何”的条件的情况下,可确立一个有效等价类和一个无效等价类.
③在输入条件是一个布尔量的情况下,可确定一个有效等价类和一个无效等价类.
④在规定了输入数据的一组值(假定n个),并且程序要对每一个输入值分别处理的情况下,可确立n个有效等价类和一个无效等价类.
⑤在规定了输入数据必须遵守的规则的情况下,可确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则).
⑥在确知已划分的等价类中各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步的划分为更小的等价类.
3)设计测试用例:在确立了等价类后,可建立等价类表,列出所有划分出的等价类:
输入条件有效等价类无效等价类
然后从划分出的等价类中按以下三个原则设计测试用例:
①为每一个等价类规定一个唯一的编号.
②设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖地有效等价类,重复这一步.直到所有的有效等价类都被覆盖为止.
③设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步.直到所有的无效等价类都被覆盖为止.

软件测试之黑盒——错误推测法

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

软件测试之黑盒——黑盒测试之边界值分析法

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