我来设计(二):测试数据生成工具
生成测试数据的方法有很多种,在这里除了介绍测试数据的生成方法,
还会介绍不要机械理解测试数据仅仅就是随机就可以了,所谓的随机策略也可能会影响到你的业务程序。
地点字典:
街道名字,比如:历山
街道后缀,比如:路,大街
城市字典:比如:济南,青岛,西宁
省份字典(包含直辖市):比如:山东省,北京市,上海市
邮编字典:比如:270000
城市字典与省份字典有一对多的对应关系。
邮编字典与城市字典一一对应
名字字典:
姓字典:比如:李,王,廖,甄,慕容,公孙
女性名字字典: 比如:文秀,小倩,敏,娟
男性名字字典: 比如:涛,华,科,伟,国,斌,明泽,小兵,远华
对于FirstName和LastName这里不举例,思路类似;
公司名字字典:比如:绿荷经贸,茂田实业,中福文化传播
公司名字后缀:比如:有限公司,有限责任公司,连锁店,律师事务所,机械工厂,第一分公司
邮箱相关字典:
域名后缀:org,net,com,biz,us,co.uk,co.in,in,info,cn,com.cn
邮箱运营商字典:163,qq,gmail,hotmail,yahoo,rediffmail
职位字典:
董事长,总经理,主管,经理
通用字典税务编码实现思路:
把每一个分类的数据保存到文件中,获取这些数据后放到一个数组中,
随机生成一个小于数组长度的数字,然后以这个数字为下标获取数组中的值;
有关联关系的字典,要在初始的时候建立好引用关系;
邮箱生成规则:
姓名的汉语拼音+出生日期或一个两位数的随机数+@+邮箱运营商字典+.+域名后缀
出生日期字典:
年份:1950-2000
月份:1-12
天数1-31(是否有29,30,31看年和月份而定)
日期生成编码实现思路:
初始化Calendar对象,调整到1950-01-01然后随机加上一个代表天数的数值,
就可以得到新的Calendar对象,从而获取其日期
关于业务上的日期还要提供显示日期的格式。
业务固定的有限几个值:
比如:客户根据自己的要求某个字段就3种类型:业务一,业务二,业务三
这3个值是跟业务有关,不可能包含在工具字典里面的。
有限固定值编码实现思路:
根据输入的值进行随机选择一个值返回
数字:
可以指定数字类型(含不含小数,小数几位),最小值,最大值,平均值,默认值
字符串:
根据指定的字符串长度来循环调用获取单个字符的方法,
长度可以指定最小长度和最大长度,最小长度和最大长度相等时,返回的字符串长度固定。
外键生成数据:
需要指定执行的sql来从某个主表中获取数据。
随机几率:
上面的几个基本都是用随机数就能搞定,但是随机也要考虑一定的几率性,
比如北京一年四季的天气温度大部分还是在零上,这样在随机生成这个数据的时候,
就得考虑10-20温度的生成的几率就大一些,其他的几率就小一些。
对随机几率有要求的需求的编码思路:
先判断是否能拿到随机值的几率,
能拿到就调用系统提供的随机方法,获取随机值
如果拿不到就使用系统提供的默认值。
获取是否能拿到随机值的几率的相关代码:
public boolean chance(int chance) { //chance的值代表百分比,比如其值等于70就是70%
return random.nextInt(100) < chance;
}
这里举例仅仅是对一个值出现的几率进行运算,对多个值分别执行使用几率也可以运算,思路一样。
比如:A 出现几率50% B出现几率30% C出现几率15% D出现几率5%
数据偏差:
比如甲告诉你投资100一个月后最少能拿到110 最多能拿到130 平均是120,
乙也告诉你投资100一个月后最少能拿到80 最多能拿到160 平均是120。
平均收益都是120的两件事,实际背后可以分析出来乙的方案是高风险,这种结论是通过分析工具分析出来的结果,而对于测试数据工具来讲,是不关心这个的。
所以在提供平均值的场景下,可以根据业务要求来提供数据偏差,这样生成数据的时候可以根据这个偏差生成相应的数据。
数据的分布密集程度:
可以理解成数据倾斜,在我们数据库中的某个表中,数据量很大,
某个字段的值是否取值均匀可以决定建立在这个字段上的索引的集群分子,
如果集群分子很大,在我们的sql中就可能不执行建立在这个字段上的索引。
数据库的提供的索引有多种类型,在生成数据的同时也可以校验我们建立的索引类型是否高效。
在后台运行的程序对这个字段进行分派出去运算的时候,会根据这个值通过某个公式算出某个值出来,然后再分派到后台的某个计算服务器进行运算,如果某个阶段的值过于集中,就会导致分派到某个计算服务器的压力过大,
从而会导致异常出现。对于这种场景可以看出测试数据也可以影响到你的程序。所以在我们生成测试数据的时候,还是要对这些测试数据多用心,不要主观认为全部随机生成就可以模拟所有的真实数据环境。全部随机就会导致所有的数据都会均匀分布,这在某些场景下是不现实的,比如现实富人区和穷人区的比例是均匀的吗。
实际中用到的几段代码:
实例化随机数对象:Random random = newRandom();
生成字符(大写):
public char getRandomChar() {
return (char) (random.nextInt(26) + 'A');
}
生成字符串(minLength==maxLength会返回固定长度的字符串):
public String getRandomChars(int minLength, int maxLength) {
//先校验最小值和最大值是否合法的代码,省掉
StringBuilder sb = new StringBuilder(maxLength);
int length =minLength;
if (maxLength != minLength) {
length = length + random.nextInt(maxLength - minLength);
}
while (length > 0) {
sb.append(getRandomChar());
length--;
}
return sb.toString();
}
Random 的常用方法:setSeed,nextInt,nextBoolean,nextDouble,nextGaussian
Math的常用方法调用: Math.exp,Math.log,Math.max,Math.min