测试的痛点

大家好,我是老马。

每一位开发者大部分工作都是写代码、测试代码、修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)*/@Testpublic 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

心愿本文对你有所帮忙,如果喜爱,欢送点赞珍藏转发一波。

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