首頁>技術>

測試的痛點

大家好,我是老馬。

每一位開發者大部分工作都是寫程式碼、測試程式碼、修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

我是老馬,期待與你的下次相遇。

9
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Netty 實戰:如何實現自定義協議訊息推送?