测试的痛点
大家好,我是老马。
每一位开发者大部分工作都是写代码、测试代码、修 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
心愿本文对你有所帮忙,如果喜爱,欢送点赞珍藏转发一波。
我是老马,期待与你的下次相遇。