测试的痛点

大家好,我是老马。

每一位开发者大部分工作都是写代码、测试代码、修BUG。

我们有很多测试代码,总是花费大量的实践去构建一个对象。

于是就在想,能不能自动填充一个对象呢?

于是去 github 查了一下,找到了一个测试神器 data-factory。

https://github.com/houbb/data-factory/

data-factory

作用

data-factory 项目用于根据对象,随机自动生成初始化信息。便于测试。

特性

  • 8 大基本类型的支持

  • 数组、对象、枚举、Map、链表、Set 等支持

  • String、BigDecimal、BigInteger、Currency 等常见类型的支持

  • Date、LocalDate、LocalDateTime、LocalTime、Year 等常见日期类型支持

  • 支持 Regex 正则表达式

  • @DataFactory 注解支持灵活配置

快速入门

引入依赖

<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>data-factory-core</artifactId>
<version>0.0.8</version>
</dependency>

我们通过 DataUtil.build(class) 就可以生成对应类的随机值。

比如 DataUtil.build(String.class);,就可以生成随机的字符串:

0s5Z8foS1

老马发现,基本支持所有常见的类型,我们指定对应的 class 即可,这点还是挺方便的。

不过我一般都是使用对象,那可以自动填充一个对象吗?

对象 bean 填充

当然,最常用的还是初始化一个 java 对象。

public class User {

    private String name;

    private int age;

    private Date birthday;

    private List<String> stringList;

    //S/F 的枚举
private StatusEnum statusEnum; private Map<String, String> map; //Getter & Setter
}

构建方法 User user = DataUtil.build(User.class);

构建对象如下:

User{name='wZ8CJZtK', age=-564106861, birthday=Wed Feb 27 22:14:34 CST 2019, stringList=[Du4iJkQj], statusEnum=S, map={yA5yDqM=Kdzi}}

内容每次都随机,便于基本的测试数据填充。

@DataFactory 注解

当然,有时候我们希望生成的数据符合一定的规则,这个时候可以通过 @DataFactory 注解去进行限制。

注解属性

/**
* 数据生成注解
* @author binbin.hou
* @date 2019/3/9
* @since 0.0.2
*/
@Inherited
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataFactory { /**
* 是否忽略此字段
*
* @return 默认不忽略
*/
boolean ignore() default false; /**
* 数字整数部分最大值。
* 只作用于数字类型的字段
*
* @return 返回最大值
*/
int max() default 100; /**
* 数字整数部分最小值。
* 只作用于数字类型的字段
*
* @return 返回最小值
*/
int min() default 0; /**
* 精度。
* 作用于Float、Double、BigDecimal 小数部分长度
*
* @return 返回精度
*/
int precision() default 2; /**
* 最大长度。只作用于String类型的字段
*
* @return 返回最大长度
*/
int maxLen() default 30; /**
* 最小长度。只作用于String类型的字段
*
* @return 返回最小长度
*/
int minLen() default 1; /**
* 指定当前字段的类实现策略
* @return 实现类
* @since 0.0.6
*/
Class<? extends IData> data() default IData.class; /**
* 正则表达式
* 1. 当前版本为了简单方便,如果 regex 存在,则直接忽略长度,精度等其他注解配置。
* 2. 建议直接使用在 String 类型
* 3. 如果使用其他类型,则必须保证提供了对应的 String 构造器。如{@link Long#Long(String)}
* 4. 基本类型会直接使用对应的包装类型。
* @since 0.0.3
* @return 表达式信息
*/
String regex() default ""; }

String 类

  • 定义对象
/**
* 字符串类注解测试
* @author binbin.hou
* @date 2019/3/9
* @since 0.0.2
*/
public class UserAnnotationString { /**
* 指定最小长度,最大长度
*/
@DataFactory(minLen = 2, maxLen = 10)
private String name; /**
* 忽略生成当前字段
*/
@DataFactory(ignore = true)
private String hobby; //Getter & Setter }
  • 测试代码
/**
*
* Method: build(clazz)
*/
@Test
public void stringAnnotationTest() throws Exception {
for(int i = 0; i < 100; i++) {
UserAnnotationString userAnnotationString = DataUtil.build(UserAnnotationString.class); Assertions.assertNull(userAnnotationString.getHobby());
Assertions.assertTrue(userAnnotationString.getName().length() >= 2);
Assertions.assertTrue(userAnnotationString.getName().length() <= 10);
}
}

Number 类

  • 对象定义
/**
* 数字类注解测试
* @author binbin.hou
* @date 2019/3/9
* @since 0.0.2
*/
public class UserAnnotationNumber { @DataFactory(min = 10, max = 20)
private Byte aByte; @DataFactory(min = 10, max = 20)
private Short aShort; @DataFactory(min = 10, max = 20)
private Integer integer; @DataFactory(min = 10, max = 20)
private Long aLong; @DataFactory(min = 10, max = 20, precision = 3)
private Double aDouble; @DataFactory(min = 10, max = 20, precision = 3)
private Float aFloat; @DataFactory(min = 10, max = 20, precision = 3)
private BigDecimal bigDecimal; @DataFactory(min = 10, max = 20)
private BigInteger bigInteger; //Getter & Setter }
  • 测试代码

通过 DataUtil.build(UserAnnotationNumber.class) 生成的对象如下:

UserAnnotationNumber{aByte=10, aShort=17, integer=19, aLong=11, aDouble=19.888, aFloat=10.067, bigDecimal=18.035, bigInteger=13}

正则表达式

正则表达式作为一大神器,自然是不能落下。

定义

对象的定义如下:

/**
* 正则表达式测试对象
* @author binbin.hou
* @date 2019/3/12
* @since 0.0.3
*/
public class RegexBean { @DataFactory(regex = "[0-3]([a-c]|[e-g]{1,2})")
private String name; @DataFactory(regex = "[0-9]{1,2}")
private int age; @DataFactory(regex = "[0-9]{1,2}")
private BigDecimal amount; //Getter & Setter }

效果

生成效果如下:

RegexBean{name='2c', age=61, amount=39}

自定义 Data 生成策略

当然,所有的内置策略只能满足最常见的需求。

但是无法满足各种特殊的定制化策略,幸运的是我们可以自定义自己的数据填充策略。

自定义生成策略

这里我们实现一个最简单的生成策略,如果是字符串,固定为 123。

public class MyStringData implements IData<String>  {

    @Override
public String build(IContext context, Class<String> stringClass) {
return "123";
} }

使用

我们在 @DataFactory 注解中指定自己的策略。

public class UserAnnotationData {

    @DataFactory(data = MyStringData.class)
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }

这样生成的就是我们自己的数据生成策略。

不足之处

当然,老马觉得这些特性还是不太方便。

希望作者可以实现支持全局配置之类的特性,这样会更加方便的。

各位小伙伴也可以体验一下,让自己早点下班,享受属于自己的时光。

小结

今天我们和大家一起感受了数据填充工具的便利性,大家工作中有需要就可以用起来。

为了便于大家学习,所有源码均已开源:

对象填充:https://github.com/houbb/data-factory

性能压测:https://github.com/houbb/junitperf

希望本文对你有所帮助,如果喜欢,欢迎点赞收藏转发一波。

我是老马,期待与你的下次相遇。

开源神器:自动生成随机 mock 数据测试对象的更多相关文章

  1. Ogre 编辑器三(自动生成与更新Ogre对象编辑界面)

    最开始设计这个编辑器时,其中一个要求就是能在运行过程中,通过UI来更新各对象,这样我们就能明确每个Ogre对象更新其属性影响的渲染效果.比如点光源,方向光源,聚光灯各属性与效果,深度测试开启与关闭,深 ...

  2. 什么是静态代码块?java中如何使用空参构造方法自动生成不同名字的对象,使用非静态的属性和静态属性有什么区别,原因是什么?如何理解static关键字

    静态代码块?类加载就执行,最先执行 class demo{ static int num; static{ num=10; num*=3; System.out.println("haha& ...

  3. eclipse、idea中自动生成元模型JPA元模型对象

    一.eclipse 1.首先准备好两个jar包hibernate-jpa-2.0-api-1.0.1.Final和hibernate-jpamodelgen-4.3.5.Final 2.选中项目右击 ...

  4. 自动生成 java 测试 mock 对象框架 DataFactory-01-入门使用教程

    项目简介 Data-Factory 用于根据对象,随机自动生成初始化信息,避免了手动创建对象的繁琐,便于测试. 特性 8 大基本类型的支持 String.Date.金额,日期等常见类型的支持 java ...

  5. 《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇01:道路的自动生成》

    1.道路的自动生成 道路自动生成概述: 3D跑酷游戏的核心就是跑,在跑这一过程中增加趣味性使得游戏具有更多的可玩性.道路的自动生成和自由拼接,为游戏增设了更多的不可预见性.这种不可预见性使得玩家在游戏 ...

  6. 米扑科技的开源项目:sitemap-php 自动生成网站地图

    米扑科技旗下的产品,近期正在做SEO网站优化,其中子需求之一是调研实现了网站地图(sitemap.xml) 封装简化了许多功能模块,现在分享出来,源代码可在Github上下载,有简单的示例. Gith ...

  7. Spring Boot(九)Swagger2自动生成接口文档和Mock模拟数据

    一.简介 在当下这个前后端分离的技术趋势下,前端工程师过度依赖后端工程师的接口和数据,给开发带来了两大问题: 问题一.后端接口查看难:要怎么调用?参数怎么传递?有几个参数?参数都代表什么含义? 问题二 ...

  8. MOCK.JS 生成随机数据,拦截 Ajax 请求

    mock.js 的用处 前后端分离 :让前端攻城师独立于后端进行开发. 增加单元测试的真实性 :通过随机数据,模拟各种场景. 开发无侵入 :不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响 ...

  9. Go 语言,开源服务端代码自动生成 框架 - EasyGoServer

    EasyGoServer 作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblog ...

  10. Mysql逆向工程效率神器之使用IDE自动生成Java实体类

    Mysql逆向工程效率神器之使用IDE自动生成Java实体类 简介:实战使用IDE根据Mysql自动生成java pojo实体类 1.IDEA连接数据库 菜单View→Tool Windows→Dat ...

随机推荐

  1. P5729 【深基5.例7】工艺品制作

    1.题目介绍 [深基5.例7]工艺品制作 题目描述 现有一个长宽高分别为 \(w,x,h\) 组成的实心玻璃立方体,可以认为是由 \(1\times1\times1\) 的数个小方块组成的,每个小方块 ...

  2. [kubernetes]服务健康检查

    前言 进程在运行,但是不代表应用是正常的,对此pod提供的探针可用来检测容器内的应用是否正常.k8s对pod的健康状态可以通过三类探针来检查:LivenessProbe.ReadinessProbe和 ...

  3. Linux系统下安装JDK8和Maven3.8.5

    一.下载JDK8Linux版本 官网下载太慢了,小编这里为大家下载好了: 链接:百度网盘地址 提取码:ov24 二.下载Maven maven3.8.5下载链接 三.使用xftp上传到linux上 四 ...

  4. 【rt-thread】Kconfig文件添加子Kconfig文件时是以顶级Kconfig所在目录为当前路径的

    示例如下 顶级Kconfig文件所在目录 子级Kconfig文件所在目录 子级Kconfig文件添加次子级Kconfig文件,以顶级目录为当前路径依次写出次子级Kconfig文件所在目录

  5. 配置Chrome支持网页内的frame跨域

    前言 跨域限制可以保证安全,但是调试的时候关掉会更方便,然而现在网络上能找到的关闭跨域限制方法,在新版的Chrome浏览器上根本没用-- 经过一番摸索,发现用旧版的Chrome就可以绕过跨域限制,刚好 ...

  6. [转帖]RabbitMQ学习笔记:内置Prometheus支持rabbit_prometheus插件

    从3.8.0开始,RabbitMQ提供内置的Prometheus和Grafana支持. rabbitmq_prometheus插件中提供了对Prometheus指标收集的支持.该插件以Promethe ...

  7. [转帖]分享6个SQL小技巧

    https://www.jianshu.com/p/2fcf0a4e83b7   简介 经常有小哥发出疑问,SQL还能这么写?我经常笑着回应,SQL确实可以这么写.其实SQL学起来简单,用起来也简单, ...

  8. [转帖]jmeter线程组与循环次数的区别

    在压测的时候,有些接口需要携带登录信息,但是我们只想登录一次,然后其他接口进行多用户压测,此时你会怎么办?用仅一次控制器实现吗?下面我们来看看用仅一次控制器能不能实现 压测时jmeter中的线程数是模 ...

  9. 关于sar的学习

    关于sar的学习 背景 公司一套基于某冷门Python架构的系统前几天出现异常卡顿. 当时安装的时候必须使用ubuntu系统. 所以当时默认安装的ubuntu1804, 本来想尝试使用一下sar查看卡 ...

  10. Redis lua脚本简要学习

    Redis lua脚本简要学习 背景 上周督促客户从Windows平台升级到了Linux平台. redis一周相安无事. 但是这周一突然又出现了卡断和慢的情况. 只能继续进行分析. 分析思路 现场日志 ...