测试 Java优雅的生成测试数据
前言
在日常的测试中,我们经常需要提前准备一大堆测试数据,用来验证业务逻辑。当然对于简单的数据类型完全可以通过 JDK 自带的 Random
类来实现。但是对于一个比较复杂的类,或者参数的格式有特殊要求的时候,Random
就不适用了,这个时候就需要借助一些能够生成测试数据的框架。
相关框架
我在实际调研中,找到了 2 个在个人看来还不错的生成框架,他们分别是:
-
jmockdata[1]
-
java-faker[2]
下面我将一个一个地介绍这些框架的优缺点以及适用场景。话不多说,直接开始撸代码。
JmockData
首先出场的是 JmockData 框架,它是官方定义如下:
一款实现模拟JAVA类型或对象的实例化并随机初始化对象的数据的工具框架。
依赖
-
<dependency>
-
<groupId>com.github.jsonzou</groupId>
-
<artifactId>jmockdata</artifactId>
-
<version>4.2.0</version>
-
</dependency>
基础类型数据生成
-
@Test
-
public void testBaseType(){
-
// 基础数据类型
-
System.out.println(JMockData.mock(byte.class));
-
System.out.println(JMockData.mock(int.class));
-
System.out.println(JMockData.mock(long.class));
-
System.out.println(JMockData.mock(double.class));
-
System.out.println(JMockData.mock(float.class));
-
System.out.println(JMockData.mock(String.class));
-
System.out.println(JMockData.mock(BigDecimal.class));
-
-
// 基础数据类型的数组
-
System.out.println(JMockData.mock(byte[].class));
-
System.out.println(JMockData.mock(int[].class));
-
System.out.println(JMockData.mock(long[].class));
-
System.out.println(JMockData.mock(double[].class));
-
System.out.println(JMockData.mock(float[].class));
-
System.out.println(JMockData.mock(String[].class));
-
System.out.println(JMockData.mock(BigDecimal[].class));
-
}
运行结果
-
0
-
2610
-
3401
-
8582.18
-
7194.44
-
5Xu7
-
9051.92
-
[B@7fbe847c
-
[I@41975e01
-
[J@c2e1f26
-
[D@dcf3e99
-
[F@6d9c638
-
[Ljava.lang.String;@7dc5e7b4
-
[Ljava.math.BigDecimal;@1ee0005
JavaBean 类型数据生成
-
/**
-
* java bean 测试
-
*/
-
@Test
-
public void testJavaBean(){
-
Person mock = JMockData.mock(Person.class);
-
System.out.println(mock);
-
}
运行结果
Person[address=RrayfQIK,age=5863,idCard=SDn,name=j]
这里可以看到,使用 JMockdata.mock(xx.class);
可以很容易的生成一个 JavaBean。框架通过反射,在底层遍历获得类的属性与类型,然后填充数据。
但是与此同时,大家也发现了,虽然我们可以的的确确的生成了一个 Person
类,也给它的每个属性都填充了值,但是生成的数据只是根据类型简单生成的,比如 age
字段被填充的是 5863。如果数据有现实含义,没有规则的随机就很容易出现乌龙。
要解决这个问题,我们就要限制随机数据的范围,可以通过它的配置功能实现。
使用随机配置
-
@Test
-
public void testJavaBeanWithConfig() {
-
-
MockConfig mockConfig =
-
new MockConfig()
-
.subConfig("age")
-
// 设置 int 的范围
-
.intRange(1, 100)
-
.subConfig("email")
-
// 设置生成邮箱正则
-
.stringRegex("[a-z0-9]{5,15}\\@\\w{3,5}\\.[a-z]{2,3}")
-
.globalConfig();
-
-
Person mock = JMockData.mock(Person.class, mockConfig);
-
System.out.println(mock);
-
}
运行结果
Person[address=hXttj2s,age=2,email=w14hnn@UvFB9.kt,idCard=V5bBdX,name=KM8]
可以看到 age
跟 email
已经正常了,可以通过他强大的配置功能对于数据进行生成的限制,但是你也发现了,对于一些有简单边界的数据,这样做可以,否则就像 address 、 name 这样的数据,很难通过简单规则去生成。
而对于有现实意义的数据生成,可以使用 java-faker 框架。
Java-faker
依赖
-
<dependency>
-
<groupId>com.github.javafaker</groupId>
-
<artifactId>javafaker</artifactId>
-
<version>1.0.2</version>
-
</dependency>
数据生成
-
@Test
-
public void testRandomName() {
-
Faker faker = new Faker();
-
final Name name = faker.name();
-
System.out.println("firstName : " name.firstName());
-
System.out.println("username : " name.username());
-
System.out.println("bloodGroup : " name.bloodGroup());
-
System.out.println("suffix : " name.suffix());
-
System.out.println("title : " name.title());
-
System.out.println("lastName : " name.lastName());
-
System.out.println("nameWithMiddle : " name.nameWithMiddle());
-
System.out.println("fullName : " name.fullName());
-
System.out.println("name : " name.name());
-
System.out.println("prefix : " name.prefix());
-
}
生成结果
-
firstName : Hollis
-
username : cristy.white
-
bloodGroup : O-
-
suffix : Sr.
-
title : Product Implementation Specialist
-
lastName : Johnston
-
nameWithMiddle : Alesia Hagenes Kiehn
-
fullName : Dr. Pat Marvin
-
name : Ms. Jamal Rau
-
prefix : Mr.
可以看到 java-faker 生成数据特别的方便,基本格式如下:
-
Faker faker = new Faker();
-
final Xx xx = faker.xx();
-
xx.yyyy;
步骤:
-
创建 faker 对象
-
通过 faker 对象获得要生成的实体对象
-
调用实体对象获得对于生成的部分
这里的实体对象,对应上面的 name,也就说我们要生成姓名相关的数据,拿到实体对象后还可以只获得其中的部分数据,比如姓名中的姓或名,还有前缀,甚至血型,可以说是非常全面。
而且 java-faker 支持的实体对象特别的多,如下:
Address
Ancient
Animal
App
Aqua Teen Hunger Force
Artist
Back To The Future
Aviation
Basketball
Beer
Bojack Horseman
Book
Bool
Business
ChuckNorris
Cat
Code
Coin
Color
Commerce
Company
DateAndTime
Demographic
Disease
Dog
DragonBall
Dune
Educator
Esports
File
Finance
Food
Friends
FunnyName
GameOfThrones
Gender
Hacker
HarryPotter
Hipster
HitchhikersGuideToTheGalaxy
Hobbit
HowIMetYourMother
IdNumber
Internet
Job
Kaamelott
LeagueOfLegends
Lebowski
LordOfTheRings
Lorem
Matz
Music
Name
Nation
Number
Options
Overwatch
PhoneNumber
Pokemon
Princess Bride
Relationship Terms
RickAndMorty
Robin
RockBand
Shakespeare
SlackEmoji
Space
StarTrek
Stock
Superhero
Team
TwinPeaks
University
Weather
Witcher
Yoda
Zelda
从身份证到姓名再到地址、动物、书籍、头像、职位等等,基本上覆盖了我们生活中的方方页面。
另外,java-faker 更贴心的是帮我们实现了国际化,可能刚才看了姓名的例子,有些朋友觉得这个框架好看但不好用,就拿生成姓名来说,生成都是 Johnston、Tom、Kiwi 之类英文名,在国内很少用到这些数据。其实java-faker 已经考虑到这个问题。而且只要改一行代码就可以了。
修改后的代码
-
// 原代码 Faker faker = new Faker();
-
// 新代码
-
Faker faker = new Faker(Locale.CHINA);
-
final Name name = faker.name();
-
System.out.println("firstName : " name.firstName());
-
System.out.println("username : " name.username());
-
System.out.println("bloodGroup : " name.bloodGroup());
-
System.out.println("suffix : " name.suffix());
-
System.out.println("title : " name.title());
-
System.out.println("lastName : " name.lastName());
-
System.out.println("nameWithMiddle : " name.nameWithMiddle());
-
System.out.println("fullName : " name.fullName());
-
System.out.println("name : " name.name());
-
System.out.println("prefix : " name.prefix());
生成结果
-
firstName : 熠彤
-
username : 烨霖.龙
-
bloodGroup : A-
-
suffix : IV
-
title : Investor Division Engineer
-
lastName : 范
-
nameWithMiddle : 胡思
-
fullName : 孟鸿涛
-
name : 黎航
-
prefix : Miss
只需要,把之前的 Faker faker = new Faker(); 改成 Faker faker = new Faker(Locale.CHINA); 即可。如果你想生成其它国家的内容也是可以的,java-faker 支持的国家如下:
bg
ca
ca-CAT
da-DK
de
de-AT
de-CH
en
en-AU
en-au-ocker
en-BORK
en-CA
en-GB
en-IND
en-MS
en-NEP
en-NG
en-NZ
en-PAK
en-SG
en-UG
en-US
en-ZA
es
es-MX
fa
fi-FI
fr
he
hu
in-ID
it
ja
ko
nb-NO
nl
pl
pt
pt-BR
ru
sk
sv
sv-SE
tr
uk
vi
zh-CN
zh-TW
总结
JmockData
个人感觉它是 plus 版的 Random 类,方便简单的按类型生成数据,也可以自己给定配置与规则去生成,缺点,上文也说了,生成的数据没有太多实际意义,简单数据还好,如果像姓名、地址等有现实意义的数据,就不太合适了。
Java-faker
java-faker 其实是迁移自 ruby 中大名鼎鼎的 faker。很多语言都有他的对应迁移,比如 python、java。所以数据量和功能是很完善并且经过考验的,使用起来也很方便。实际工作中,可以优化使用。如果要说缺点,个人觉得他有些地方国际化的并不全面,比如车牌、身份证之类的。如果对于这些数据有比较严格的要求,推荐另一个项目 yindz/common-random: 简单易用的随机数据生成器。[3]这个项目对于本地化数据,做了很多处理,基本够用。
学习更多JAVA知识与技巧,关注与私信博主(555)!
热爱学习和渴望进阶的小伙伴,各种JAVA学习路线、笔记、面试题,免费分享!
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgakfhh
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01