之前在X公司参与测试的项目,整个结构如图所示:
我负责第一层Linux服务器产品测试工作(红色标示部分),我到之前的测试流程为:
1. 数据库准备(远程Linux操作或者使用工具Toad/Navicat对多服务器的Oracle/MySQL测试数据增删改查)
Linux下环境准备(远程Linux操作第一层服务器配置文件修改、进程启停、配置重载等)
--》
2. 第二层部分测试环境准备(操作第二层数据库数据,远程登录服务器对第二层服务器配置文件修改、进程启停、数据重载等)
--》
3. 启动第三层客户端测试相应功能
--》
4. 缺陷跟踪管理(关于第一层)
方式:100%手工测试
职责:保证第一层Linux服务器相关产品的功能正确、性能良好。
特点概述:
1. 每一层服务器都不是单体结构,都包含多个子层次多部分和多个数据库,可能都部署在多个不同的服务器上,层次之间可能一对多或多对多(断线自动重连)。
2. 其中,第二层服务器结构最为繁杂、处理的逻辑业务量最大。第一层服务器的全部功能通过与第二层服务器交互最终反映到第三层客户端的功能表现(线上用户直接接触),即第二层服务器的一部分逻辑业务量处理与第一层服务器交互和客户端对应的功能逻辑控制,具体比如账号、金钱交易、计费、活动、安全保障等专有功能业务系统的质量,为我们所负责的范围。
3. 第一层服务器和第二层服务器之间全部按照严格定义格式的一系列应用协议进行通信,协议及种类根据需求灵活多变(区分不同项目,可增删改),数据包未加密(私网),第二层服务器和第三层客户端之间也是按照严格的一系列协议通信,数据包加密(公网)。
4. 第一层服务器可能有多个不同的开发人员,第二层服务器是另外多个不同的开发人员,第三层客户端同样是多个不同的开发人员。
5. 所有代码对测试保密,大团队长开发周期产品(3年以上),代码量极为庞大繁杂(纯CPP百MB到GB级),环环相扣,代码规范不统一,无单元测试。
看到的问题:
1. 全手工方式测试。
2. 停留在测试表现层的功能。
3. 庞大复杂的结构,很多传统测试套路无法适应。
4. 发现Bug,需要各个层次的开发人员协同定位,是某个数据库数据错误、第一层服务器处理错误、第二层服务器处理错误、还是第三层客户端的问题,然后才能由相应人员更改Bug。
想到的可突破点:
1. 测试流程方便化(测试辅助工具,可简化的手工操作)
2. 测试针对性深入化(Socket通信协议测试工具,定位第一层协议处理错误还是第二层协议处理错误,更加针对第一层服务器产品的质量,减少沟通成本和测试、开发的工作量,深入理解协议和发现最底层的错误,上升到越高层可能各层产生越多的问题。)
3. 测试流程自动化(自动化测试工具,控制逻辑的动态脚本语言支持,减少人力成本)
测试对象无论是由C/C++还是Java还是其他语言实现,对于协议测试(各种语言标准通用)和功能测试(白盒测试和单元测试另当别论),都不需要深入了解该语言,熟悉任一种高级语言(最好还有一种脚本语言)+ 自动化思维意识 + 快速学习能力,完全能实施测试自动化策略。
Socket网络通信理论基础
(详细参照http://blog.csdn.net/w565911788/article/details/8136323)
TCP/IP网络协议栈分为应用层(Application)、传输层(Transport)、网络层(Network)和链路层(Link)四层。如下图所示(该图出自[TCPIP])。
图 36.1. TCP/IP协议栈
两台计算机通过TCP/IP协议通讯的过程如下所示(该图出自[TCPIP])。
图 36.2. TCP/IP通讯过程
传输层及其以下的机制由内核提供,应用层由用户进程提供,应用程序对通讯数据的含义进行解释,而传输层及其以下处理通讯的细节,将数据从一台计算机通过一定的路径发送到另一台计算机。应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation),如下图所示(该图出自[TCPIP])。
图 36.3. TCP/IP数据包的封装
不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据报(datagram),在链路层叫做帧(frame)。数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理。
目的:使测试方便化&深入化&自动化。
1. 协议测试设计
关于第一层服务器和第二层服务器之间的协议,请求的数据包包括包头、包尾、包长度、固定标志位、特定字符串长度、特定字符串值等信息。返回对应严格格式的数据包,包括处理结果和标志等信息。
使用抓包器(如Fiddler、Wireshark、NetWork Monitor等),捕获tcp/ip通信数据包,tcp && ip.addr == 192.168.1.1,选择最上面一层(即与Telnet、FTP、HTTP、E-mail等协议同属的应用层,每低一层会增加标准协议的包头等附加信息--封装),即可查看到原始数据包,我们即是对此对象进行测试。
协议A格式(数字表示字节长度)
请求:
包头(2),包长度(2),协议名称(2),IP长度(1),IP串(0-16),账号长度(1),账号串(0-32),密码长度(1),密码串(0-32),包尾(2)
返回:
包头(2),包长度(2),协议名称(2),IP长度(1),IP串(0-16),账号长度(1),账号串(0-32),处理结果标志(2),包尾(2)
0x00:登录成功 0x01:用户不存在 0x02:密码错误
原始请求包:
0xaa,0xbb,0x00,0x18,0x00,0x0a,0x0b,0x01,0x0a,0x2e,0x01,0x0a,0x2e,0x01,0x0a,0x2e,0x01,0x0a,0x04,0x41,0x41,0x41,0x41,0x04,0x41,0x41,0x41,0x41,0xbb,0xaa
原始响应包:
0xaa,0xbb,0x00,0x15,0x00,0x0a,0x0b,0x01,0x0a,0x2e ,0x01,0x0a,0x2e,0x01,0x0a,0x2e,0x01,0x0a, 0x04,0x41,0x41,0x41,0x41, 0x00,0x01,0x00,0x00,0xbb,0xaa
解析请求包:
包头0xaa,0xbb; 包长度0x00,0x18(整个包长度-6=24); 协议名称a; IP长度11; IP 10.10.10.10; 账号长度4; 账号 AAAA; 密码长度4; 密码AAAA; 包尾0xbb,0xaa
解析响应包:
包头0xaa,0xbb; 包长度0x00,0x17(整个包长度-6=23); 协议名称a; IP长度11; IP 10.10.10.10; 账号长度4; 账号 AAAA;固定位0x00,0x01;返回标志0x00,0x00(登录成功); 包尾0xbb,0xaa
配置设计(DB和存储):
协议ID number (自增)如1
协议名称 varchar 如A
项目ID number (FK算法)如8
包头 varchar 如0xaa,0xbb
包体 varchar (可变)如$1,#1,$2,#2,$3,#3
包尾 varchar 如0xbb,0xaa
返回定位1 varchar (检查值算法)如,7,1|2;2
返回定位2 varchar (检查值算法)如|7;1
备注 varchar
$1,#1:IP长度和IP;$2,#2:账号长度和账号;$3,#3密码长度和密码
检查值算法:
(,7,1|2;2):第7字节存IP可变长度值(取得并跳过账号) + 下一可变账号长度相邻1字节(取得并跳过账号) + 固定2个字节;获得2个字节的返回标志0x00,0x00
(|7;1): 固定第7字节取得1个字节的返回值IP长度0x0b
项目ID算法:
增删改项目,可设置编码2^n,项目X为1=2^0,项目Y为2=2^1,项目Z为4=2^2,如果X+Y项目一样,则为项目ID为3=1+2,如果X+Z一样则5=1+4,使用时直接 (ID&编码)判断。
实现接口:
object[] returns = PacketSendReacive( “A”, //协议名称
“11|4|4”, ”10.10.10.10|AAAA|AAAA”, //可变长度和值
”192.168.1.1”, 8888);//服务器IP和端口
实现流程:
1. 读取协议A配置
2. 替换可变长度和值
3. 计算包体长度
4. 包头+包长度+包体+包尾
5. 建立到192.168.1.1:8888的 socket连接
6. 发送数据包
7. 等待接收返回数据包(超时)
8. 解析返回数据包
9. 得到定位值1和定位值2赋给数组returns(便于验证)
(基于Socket协议,选择任一种语言实现,快捷高效和准确为佳。)
2. 数据库操作设计
数据库配置:
ID number (自增)如1
数据库别名 varchar 如ORADB001
数据库类型 varchar (FK算法)如oracle
数据库连接串 varchar 如Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.210)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=ORCL)));User Id=TEST;Password=TEST123
常用数据库操作集合列表(增删改查管理),输入实际参数、一键执行:
插入一个账号: insert into user(name, password) values(‘AAAA’,PWD(‘AAAA’));
更改账号AAAA密码:update user set password=PWD(‘BBBB’)
删除账号AAAA并插入账号BBBB:delete from user where name=‘AAAA’; insert into user(name, password) values(‘BBBB’,PWD(‘BBBB’));
自定义更改账号: update user set $1=#1,$2=#2
实现接口:
Bool flag=DB_Exec(“ORADB001”,” delete from user where name=‘AAAA’; insert into user(name, password) values(‘BBBB’,PWD(‘BBBB’));”);
Bool flag=DB_Exec(“ORADB001”,
”DB已存操作名”,
”user|password”,”AAAA|BBBB”);//字段名和字段值
(读取数据库配置、已保存操作,多种不同数据库的操作支持。)
3. Linux操作设计
Linux配置:
ID number (自增)如1
Linux别名 varchar 如Linux001
用户名 varchar 如root
密码 varchar 如123456
端口 number 如22
常用Linux操作集合列表(增删改查管理),输入实际参数、一键执行。
实现接口:
String result=LinuxExec(“Linux001”,”touch /home/program/etc.ini&&echo \”IsServer=1\”>>/home/program/etc.ini”);
String result= LinuxExec(“Linux001”,
”Linux已存操作名”,
”$1|$2|$3”,”#1|#2|#3”); //自定义参数名和参数值
(读取Linux配置、已保存操作,利用SSH协议实现登录Linux并执行命令或脚本。)
4. 自动化过程实施(动态脚本语言解析)
(1)数据库测试数据准备DB_Exec,Linux测试环境准备LinuxExec
(2)根据协议生成、发送、接收数据包PacketSendReacive
(3)验证特定标志位(Pass/Fail)
(4)保存记录测试流程生成测试结果报告
(5)Bug验证和测试结果统计处理
5. 基于协议的压力测试
针对频繁请求和处理的协议(不频繁默认无问题),自动生成多测试数据,多客户端多线程长时间进行协议测试,不断加压,统计请求响应时间变化、失败和成功的数据及比例,并收集服务器性能参数和资源消耗等数据(可自动出图),手动检查和数据结果分析。
6. 应用数据库测试
(1) 应用数据库结构测试
更新升级,检查数据库结构的变化,生成更新前和更新后的SQL结构脚本,算法调整内容和顺序,对比检查各种对象和结构的差异(可图形化)。
(2) 数据库应用数据记录
生成并保存数据记录查询的批量SQL,更新升级,针对某个用户或某个操作,前后获得所有数据记录并保存为文件形式,调用Beyond Compare工具进行文件夹比较(二进制、数据比较)数据记录的差异变化。
1. 主体框架实现特定功能,高级语言完成,并开放大量实用API,且不断增加和完善
2. 嵌套或封装一种或多种脚本语言解析器,能够动态执行测试用例脚本,对Windows窗体、Web、代码、接口、协议或性能等若干方面进行测试(扩展:录制功能)
3. 流程完善,能够准确高效的解放人力和深入测试,手工尽可能少的参与或专注于测试用例脚本工作
4. 可扩展性强,能够远程操控多个多种平台(分布集群,通过网络通信、协议通信等),能够并行调度执行,可配置可存储,资源共享方便
5. 自动化框架工作:检测新的版本-->下载、编译、批量部署-->调用指定测试脚本执行测试-->邮件或消息通知QA测试结果报告路径和发现的bug。
6. 手工工作:编写修改测试脚本并上传、收邮件校验bug、喝咖啡。