一 字符相关
1 由英文字符大小不一致造成错误。
常见如文件路径名称在windows系统可以执行,linux系统文件或路径找不到。
2 图形验证码使用不高效的情况。
解决方案:
- 验证码内容一般后端处理统一使用大写比较。
- 建议将【数字0和英文O】、【数字1和英文字符l,i,I】字符剔除,方便用户辨识。
- 电子邮箱地址一般统一小写保存。可以便捷高效的解决查询和判断邮箱是否已被使用的业务处理。
- 手机注意处理国际号的特殊处理。
如手机号国号【0086, 086, 86, +0086, +086, +86, +0086-,+086-,+86-, 86-, (86), (+86)】等情况都认为是国内手机。 - 姓名类需要大小写字符、简繁情况,一般统一转成小写简体处理和比较。
- 其他字符类比较时,需要考虑全角半角符号,字符大小写,简繁体、连续重复空格等情况是否对业务有影响。
- 输入输出一般情况需要对文本进行trim()处理,保证干净。
- 生成指定关联ID方式情况。
用户ID:1234,职位ID:567,生成投递记录ID(用户ID+职位ID)为:1234567,这样生成就会有问题。
用户ID:12345,职位ID:67,生成投递记录ID(用户ID+职位ID)也是:1234567;导致ID重复的问题。
一般解决方案我们将字段间增加分隔符,这样可以确保唯一性,如用户ID:1234,职位ID:567,生成投递记录ID(用户ID+“_”+职位ID)为:1234_567。 - 注意检查错别字或文案语法错误。
二 内容边界
根据不同的性质,使用合理的边界范围。
- 年龄:一般0~100岁;
- 出生日期:符合常理;
- 身高:0~300cm;
- 体重:0~300kg;
- 价格:非负数;
- 日期:不要出现如:0001-01-01的情况,不要手动计算月份时间:查询2月份数据出现2021-02-31情况;
- 时间:不要出现如:2小时72分钟、12:70:10的情况;
- 区间范围:查询2月份数据出现>=2021-02-01 <=2021-02-28 情况,应该是 >=2021-02-01 00:00:00 <= 2021-02-28 23:59:59;
- 预约时间:必须是当前时间之后的时间,而且是在一个合理的区间;
- 小数精度:批量计算时不要每次都四舍五入,而是计算完后,最后再四舍五入,注意业务对小数点精度的要求,一般保留两位小数。不要将1+1的计算为1+1=11的情况;
- 除数:分母不能为0;
- 范围不合理:如开始时间大于结束时间,最小值大于最大值的情况,一般情况比例不能超过100%或负值;
- 数据字典:确保提交保存的code是属于对应数据字典元素,确保页面显示时是显示的是翻译的内容,不要把CODE直接显示出来;
- 边界情况:注意【> 、>=】、【< 、<=】的使用情况,防止边界未按要求覆盖;
- 工作年限:特殊业务,一般保存设计为开始工作年限,动态计算;
- 所属关系:如所在城市,不要出现如:安徽省-南京市;
三 变量相关
- 变量未定义就使用。
- 变量定义但没有初始化,直接使用。
- 变量作用域问题,在域外使用了该变量。
- 循环中局部变量没有初始化,下一循环使用了上一次的变量值。
String msgStr = '';
for(i=0;i<100;i++){
if(value > 100){
msgStr="当前位置" + i + "内容为:" + value;
}
if("".equals(msgStr)){
sendMsg(msgStr);
}
}
调整方案:
String msgStr = '';
for(i=0;i<100;i++){
msgStr = '';
if(value > 100){
msgStr="当前位置" + i + "内容为:" + value;
}
if("".equals(msgStr)){
sendMsg(msgStr);
}
}
四 方法参数
- 传参时参数个数或类型不符合要求。
- 底层方法参数新增必填参数、调整参数类型或调整参数顺序,没有将所有使用的地方同步调整过来。
五 分页相关
- 第1页数据显示了全部查询结果信息。
错误原因:忘记增加分页参数。 - 查看第2页时重复显示第1页的数据。
错误原因:忘记调整当前页pagenum值,查询依然使用pagenum=1的条件查询。 - 记录不变的情况下,第二页偶尔显示了第1页的部分数据。
错误原因:排序条件不唯一造成的,需要确保查询排序的唯一性。
六 循环问题
防止循环、递归不能跳出的问题,确保设定最大循环次数的控制。
七 响应时效
开发或测试环境都可正常执行,线上情况请求数据时的响应:SQL、Redis、文件、其他服务反应很慢,这种情况一般是数据量达到一定基本后,慢查询或循环中多次执行业务产生的。一般需要考虑:SQL慢查询原因(索引是否有效),查询次数问题,Redis慢查询原因(keys,hkeys)等情况。
八 接口超时设定
调用第三方的接口时,超时时间需要合理设置。比如设定调用第三方接口超时时间为10秒,而第三方接口一般处理耗时都是30秒左右。那么就会出现业务端报接口调用失败,而在第三方的系统中这次的请求最终的结果时处理成功的情况。以往经验一般接口超时时间设置需要大于被调用方接口超时的最大时间,大多数时我们是2倍的方式进行设置。
九 数据一致性
删除数据库相关数据时,没删除相应的缓存数据。
十 信息显示问题
没有根据业务逻辑要求,对相应字段做相应处理。
比如:未下载的简历,不显示简历姓名手机,但导出时未做处理。
十一 路径覆盖不全
- 测试用例由输入数据和与之对应的输出结果组成,应包括合理和不合理的输入条件。
- 保证一个模块中所有路径至少被测试一次。
- 所有逻辑值都要测试真和假两种情况。
- 检查上下边界及可操作范围内运行所有循环。
十二 SQL相关
- SQL动态条件拼写错误,导致查询条件字段和参数不匹配。
解决方案:动态拼接查询条件和参数时,要每个路径都要检查到位。 - 保存数据,没有检查数据格式和长度,导致SQL报错失败。
解决方案:确保数据符合表字段对应的类型和规格。 - 一般无特殊固定情况,所有的删除操作要做成逻辑删除。
- 数据编辑后,没有更新编辑时间、编辑人,常规情况每个表里需要定义创建时间、创建人、编辑时间、编辑人。
- SQL查询in条件方式需要控制参数数量,一般建议最多100个。
超过100个使用分批方式处理。 - SQL判断重复时没有排除掉无效的信息。如:
文件夹逻辑删除,确保文件夹名称唯一,同一用户下不可重复增加相同文件记录。如果判断方法可能会写成:
select count(folderName) as num from S_folder where userid = 1 and folderName = 'abcd';
此时此用户下已有abcd文件夹,但是status ='09’即已删除状态,则无法增加新的文件夹了。
SQL应该调整为:
方式1:
Select folderName from S_folder where userid = 1 and folderName = 'abcd' and status = '01' LIMIT 1;
好处是:性能最好,但需要判断是否查询到记录。
方式2:
select count(folderName) as num from (select folderName from S_folder where userid = 1 and folderName = 'abcd' and status = '01' LIMIT 1) as tmp;
好处是:不需要判断是否查询到记录,只需判断num是否大于0。
- 没有统一使用同一时间服务器,导致有时差情况,建议统一使用数据库时间作为标准。
- 修改数据操作没有控制影响行数,导致修改数据量大引发的数据响应缓慢。
update t_msg set status='09',updatedate=now() where userid=1;
如果这个人的信息量很多,会照成SQL执行缓慢,建议根据业务需求调整为分批删除。
- 消费扣除积分、等级等类似操作,防止扣成负数的情况。
- 数据计算问题,如金额加减情况。不可将金额查询出来做加减计算然后再保存。
原代码:
dbResult = select cost from t_msg where userid = 1;
Integer i_cost = dbResult.cost - num;
update t_msg set cost = i_cost, updatedate = now() where userid = 1;
优化为:
update t_msg set cost = cost - num,updatedate = now() where userid = 1 and cost >= num;
- 修改信息状态,将约定终止不可再次变更的状态。如:已删除的状态又可以改成其他状态。用户id=1对应的status状态为09,业务要求该状态不可变更。
如果更新SQL写为:
update t_User set status='02',updatedate=now() where userid = 1;
则会把状态修改成02状态,该SQL处理是有问题的。
解决方案:更新对应的状态时,需要加上当前更新时的状态条件,防止并发引起的数据已变更的情况。
调整为:
dbResult = select status from t_User where userid = 1;
String strStatus = dbResult.status;
update t_User set status = '02',updatedate = now() where userid = 1 and status = strStatus and status!= '09';
- ORACLE like 关键字区分大小写
不区分的写法SQL写法:
select email from t_User where id > 1 and id < 1000 and upper(email) like upper('%abc%');
- MYSQL like 关键字不区分大小写
区分的写法:
select email from t_User where id > 1 and id < 1000 and binary email like '%abc%';
- 用户表要求手机号码唯一,更新或修改手机号码时提示该手机已存在。原因时忘记排查掉自己的情况。
解决方案:
a) 根据手机号查询所有记录然后程序排查掉自己的记录。
b) SQL查询条件排除属于自己的记录。
十三 用户权限相关
- 给某账号赋予权限后,登陆该账号,查看是否拥有已赋予的权限,以及权限设置是否正确(权限是否超过或者不足)。
- 调整已经登陆并且正在执行操作的账号权限,程序能否正确控制该账号的越权操作。
- 账号支持多种身份模式下,变更登陆身份后,程序能否正确执行,之前所拥有的权限能否继续使用。
- 角色管理情况下,删除包含当前用户的角色,程序能否正确使用。
- 组织管理情况下,删除包含当前用户的组织,程序能否正确使用。
- 当前用户能否将自己的权限提权。
- 当前用户能否将修改比自己大的权限用户。
- 角色权限降级后,该角色对应的用户是否能继续访问已禁用的功能。
- 是否允许删除系统管理员或者修改管理员权限,删除或者修改后的实际情况。一般系统要求至少保留一个权限最大大超级管理员账号。
- 修改用户权限或者信息后,对其他模块是否有影响,比如:没有查看权限时,对应的查看入口菜单或结果列表是否要隐藏掉。
- 修改用户信息和已存在的其他用户信息相同,能否保存成功,是否有对应提示。
- 同一用户是否可以同时拥有多个角色,角色权限能否交叉。
十四 其他
- 送测了测试代码。
- 配置文件没有新增配置项。
- 漏送SQL脚本。
十五 总结
- 开发未完全按照产品文档开发功能包括逻辑和页面等方面。
- 开发未完全做单元测试、未把所有路径测试。
完整的自行测试是减少bug的最佳方案!