天天看點

【Maven插件】自動生成Mock測試代碼primo-generator-mock-test版本功能使用體驗

primo-generator-mock-test

項目位址:

https://github.com/chenhaoxiang/primo

介紹

你還在為寫大量單元測試而煩惱嗎,你還在苦苦的建構包裝類的值嗎?這裡有一款mock單元測試代碼自動生成的Maven插件,解決開發人員消耗大量時間在單元測試的問題,全面優化開發人員的測試效率和測試時間。

注意,本插件目前無法完成所有的mock測試,讓你不用修改一行代碼,暫時需要在primo-generator-mock-test生成mock測試代碼的基礎上再進行一點修改,例如分支覆寫,斷言使用。

本插件的目标是:實作讓開發人員不再寫一行mock測試代碼,primo-generator-mock-test幫你全部實作

願景是:減少開發人員的測試負擔,專注業務開發與疊代

經過本人的親自使用,外加我在團隊的内部"推(qiang)廣(tui)"使用,從統計來看,可以減少使用mock測試的小夥伴,至少30-50%的時間。

(此項目目前在我公司幾個團隊使用,節省了團隊成員非常多的單元測試時間,在此分享出來)

使用

1. 首先依賴插件:

最新版本

最新版本:1.0.0-SNAPSHOT

最簡單配置:

<plugin>
    <groupId>wiki.primo.generator</groupId>
    <artifactId>primo-generator-mock-test-maven-plugin</artifactId>
    <version>(版本号)</version>
    <configuration>
        <testPackageName>(待測試類的包名,0.1.0-SNAPSHOT+支援配置多個,英文分号進行隔開)</testPackageName>
    </configuration>
</plugin>           

(使用最簡單的配置,即可使用,感覺後面說明過多的不用往下看)

示例:

<plugin> 
    <groupId>wiki.primo.generator</groupId>
    <artifactId>primo-generator-mock-test-maven-plugin</artifactId>
    <version>1.0.0-SNAPSHOT</version> 
        <configuration>
            <testPackageName>wiki.primo.generator.primogeneratormocktestdemo.service.impl</testPackageName> 
        </configuration>
</plugin>           

2. 生成測試代碼

在引入插件的項目子產品下運作maven插件的 primo-generator-mock-test:test 指令

mvn primo-generator-mock-test:test           

直接運作mvn primo-generator-mock-test:test即可下載下傳模闆檔案&生成測試類

相關配置:

<configPath></configPath>

填寫路徑,相對路徑為目前運作項目的根路徑。(預設下載下傳路徑:/src/main/resources/test/template)

第一次運作運作插件的primo-generator-mock-test:test指令,即可将配置檔案下載下傳到對應的路徑。

可設定配置檔案的檔案名,通過

<configFileName>primo-generator-mock-test.ftl</configFileName>

設定配置檔案的檔案名稱。(預設檔案名稱為primo-generator-mock-test.ftl)

3. 引入mock相關依賴

自動測試代碼生成插件

插件生成的mock測試類方法依賴powermock&mockito,建議直接引入如下依賴(不依賴對于插件的運作沒有影響)

<dependency>
    <groupId>wiki.primo.generator</groupId>
    <artifactId>primo-generator-mock-test-jar</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <scope>test</scope>
</dependency>
           

4. configuration中相關配置屬性

在引入插件的項目名子產品下,運作插件的megatron:test指令即可在對應的test路徑下生成測試用例。

必填

  • <testPackageName>

    :必填)配置需要生成單元測試用例的包名,不要填寫接口所在包名,需要實作類所在包名,會周遊包下以及子包下所有類和類的方法(支援配置多個包名,英文分号隔開不同的包名)。

    可以配置單個類。例如:wiki.primo.generator.primogeneratormocktestdemo.service.impl.UserServiceImpl.java

    注意,配置單個類一定要以.java結尾。

不支援的類:

  • 接口
  • 枚舉
  • 抽象類
  • 私有類

選填

注意:在1.0.0-SNAPSHOT版本之前的jar包未上傳至中央倉庫

1.0.0-SNAPSHOT
  • <jsonConfigPath>

    : json配置檔案路徑,defaultValue = "/src/main/resources/test/template/"
  • <jsonConfigFileName>

    : json配置檔案名稱,defaultValue = "primo-generator-mock-test.json"
  • <isDownloadTemplateFile>

    : 是否将Template配置檔案下載下傳到本地,預設true
  • <isDownloadJsonFile>

    : 是否将json配置檔案下載下傳到本地,預設true
0.1.1-SNAPSHOT
  • <configPath>

    :下載下傳配置檔案的路徑
  • <author>

    :作者名稱
  • <configFileName>

    :下載下傳下來的配置檔案的名稱
  • <isGetChildPackage>

    :配置testPackageName的包是否遞歸擷取子包下的類(預設true)
  • <isMockThisOtherMethod>

    :配置是否mock掉父類以及自身測試類非測試的方法(預設true),父類/本類方法調用需要使用this進行調用,目前版本無法支援mock
  • <isSetBasicTypesRandomValue>

    :配置是否設定基礎類型的值随機生成(預設false)
  • <setStringRandomRange>

    :配置字元串随機值的位數(例如:"10",表示10位随機字母/數字字元)
  • <setIntRandomRange>

    :配置int/Integer類型随機值的範圍(例如:"0,1000",表示[0,1000)範圍的int數值,配置固定的值可配置為"0",則int值固定為0 )
  • <setLongRandomRange>

    :配置long/Long類型随機值的範圍(配置規則與setIntRandomRange類似)
  • <setBooleanRandomRange>

    :配置boolean/Boolean類型随機值的範圍(例如:配置為"true"/"false"表示為固定的值,其他任意值表示true和false随機)

版本功能

0.2.1-SNAPSHOT

  • fix - 修複在windows下無法生成測試代碼的bug

0.2.0-SNAPSHOT

  • 支援配置json,通過json構造參數的值
    • 隻支援實際方法的參數指派,mock的參數指派暫時不支援
    • 本次隻支援自定義的類型的值進行配置

      下面為json配置中屬性的描述:

      {
      "isOpen": "是否開啟json配置-預設false",
      "list":
      [
      {
      "scope":"作用域:全局(global)、包(package)、類(class)、方法(method) - 預設全局",
      "scopeValue": "作用域的值,global則無需配置該值,package則為包名,class則為類名,method則為方法名", 
      "fullyType": "類型的全限定名稱",
      "value":{
      "若type=base,則該值固定為value":"值",
      "若type=custom,自定義類型,value下的key為fastjson序列化的屬性名稱":"值"
      }
      }
      ]
      }           
  • 删除廢棄的配置
  • fix - 修複修改configFileName時無法下載下傳配置檔案的bug

json配置說明

  • 可以通過配置json來進行配置某個參數類型的參數值
  • 作用域(scope):全局(global)、包(package)、類(class)、方法(method)

    參數值配置優先級: 通過插件選填屬性配置 < 全局(global)< 包(package)< 類(class)< 方法(method)

  • testPackageName配置多個包,支援分号間換行,空格
  • testPackageName可以配置單個實作類。例如:wiki.primo.generator.primogeneratormocktestdemo.service.impl.UserServiceImpl.java 注意,配置單個類一定要以.java結尾。
  • 外部依賴隻需要引入primo-generator-mock-test-jar即可。

0.1.0-SNAPSHOT

  • 解決參數數量相同,重載方法的mock報錯,進行注釋代碼
  • 解決mock方法參數名稱改變問題
  • 記憶體中加載内加載器中類,不再需要手動在插件中依賴需要的類,也就是配置第三方依賴不再需要了
  • 不需要網絡便可以運作,原來是通過網絡流下載下傳檔案,本版本已經修改為jar包讀取
  • 增加測試類目錄可配置

0.0.1

新增/優化功能

  1. 支援包下所有類中公共非靜态方法生成測試方法
  2. 支援配置mock的包,将mock掉包下類的所有方法
  3. 支援基礎類型和包裝類型自動指派
  4. 增加枚舉參數的支援
  5. 可進行配置需要跳過的參數類型,直接配置包名,會進行跳過包内所有類的構造(用于跳過接口的構造,直接指派為null)
  6. 優化全限定名稱為簡稱,使用import導入包,名稱存在重複的類,使用全限定名稱
  7. 支援配置選擇是否自動mock掉父類&自身非測試的方法 - 預設true
  8. 支援配置實體基礎類型随機設定/使用預設值空值

    a. 随機 String長度:10位數字與字母,使用JDK UUID進行生成,確定唯一

    b. 随機 int:[0,1000)

    c. 随機 byte:[0,1)

    d. 随機 short:[0,127)

    e. 随機 double:[0.00,10000.00)

    f. 随機 float:[0.00f,10000.00f)

    g. 随機 long:[0L,100000L)

    g. 随機 char:數字/字母

  9. 每個測試類使用統一的before注解進行mock方法(考慮到後面每個分支的mock,如果同意進行mock的話,會導緻分支無法全面覆寫)
  10. mock注解的類,使用了全限定名稱,優化為簡稱,類進行導入,重複類簡稱,第一個類使用簡稱,後面的類使用全限定名稱
  11. 不再支援配置其他包下的類進行mock,非測試類的所有方法均進行mock,測試類的私有方法也進行mock
  12. 已生成測試類,不再進行覆寫生成
  13. 支援第三方包類的加載和構造
  14. 對于一些沒有setter方法的屬性,也進行了set值;期望:對于沒有setter的屬性值,不進行設定
  15. 支援字元串、int、long、布爾類型随機值的範圍設定
  16. 支援配置生成父類屬性的set方法進行設定值,預設true,生成的set方法包含父類的屬性(注意,父類如果不在目前項目中,需要在插件中引入包的依賴)
  17. 測試類新增方法支援追加生成mock測試方法
  18. 支援在不同包下的測試類同時進行生成
  19. 初始化下載下傳配置檔案不再需要,直接運作生成,自動檢測是否下載下傳,未下載下傳先進行下載下傳配置檔案再生成

其他功能排期

  • 配置檔案可以配置不進行下載下傳到本地,預設下載下傳
  • 支援日志級别設定,友善使用者進行調試
  • 支援if-else生成多個mock分支方法
  • 方法的參數值支援json檔案進行配置
  • 檢測代碼實作類的方法覆寫率百分比檢視以及通知到釘釘群
  • 支援簡單集合構造指派
  • 支援配置靜态方法mock,需要進行配置靜态類的全限定名稱(靜态方法不建議進行mock)
  • 測試類中的私有方法進行mock,私有方法專門開方法進行生成mock測試,預設不支援,需要配置(私有方法不建議進行mock)
  • 同一個測試方法中存在Mock方法名稱重複(參數個數不同)無法進行區分,僅僅對于第一個方法進行mock,且會存在重複mock代碼生成;期望:支援同名方法的mock
  • 無法支援重名方法(參數個數相同,參數類型不同),會出現生成的mock方法引用不明确;期望:mock方法引用明确(通過比對參數類型解決)
  • 不支援嵌套自定義參數的構造;期望:支援多級參數的構造
  • 不支援集合的構造;期望:支援集合的構造
  • mock方法傳回值不支援自定義,統一是傳回null;期望:支援mock傳回值的自定義/生成值
  • 不支援Spring自定義事務管理器DataSourceTransactionManager的mock;期望:支援自定義事務的mock
  • 支援多級參數構造指派
  • 支援重載方法的mock
  • 支援斷言配置
  • 參數值的配置yml檔案
  • 生成的測試方法可以配置是否編譯報錯,強制開發者主動進行單元測試

注意

配置mock靜态方法:

預設使用@RunWith(MockitoJUnitRunner.class),如果配置了mock靜态方法,将使用@RunWith(PowerMockRunner.class)。

使用PowerMockRunner與MockitoJUnitRunner類,都無法支援父類中的屬性(service的實作類中又同時注入了該類)自動注入的mock(例如mybatis中service層的泛型父類中的泛型baseMapper)。這是由于Mock類會将這兩個類作為不同的執行個體來進行處理,隻會mock掉你注入service實作類的基類,而無法注入service實作類的父類中的mapper。

例如:

service實作類

public class WorkFlowServiceImpl extends ServiceImpl<WorkFlowMapper, WorkFlowEntity> implements IWorkFlowService {
    @Autowired
    private WorkFlowMapper workFlowMapper;
    //...
}           

父類ServiceImpl:

public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
    @Autowired
    protected M baseMapper;
    //...
}           

在WorkFlowServiceImpl中使用時:

baseMapper.deleteById("1");           

在mock測試類中:

@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({BeanConvertUtil.class, FieldBaseDto.class})
public class WorkFlowServiceImplTest {
    @InjectMocks
    private WorkFlowServiceImpl workFlowServiceImpl;
    @Mock
    private WorkFlowMapper workFlowMapper;
    //...
}           

無法進行mock掉baseMapper執行個體,這是由于baseMapper與workFlowMapper并不是同一個執行個體!這裡僅僅隻能mock掉workFlowMapper。

目前可以在service層的實作類中将baseMapper再次注入,則使用PowerMockRunner.class也可以進行mock

service層的實作類不推薦使用泛型基類service父類進行調用泛型mapper操作資料庫層!可以選擇注入Mapper再進行調用。

使用體驗

199個測試方法,一共覆寫309個被測試方法,使用primo-generator-mock-test生成後,僅僅隻使用了3個多小時進行mock優化(僅僅優化了運作報錯的方法,沒有進行完善分支測試)。

按照我以前的經驗,如果全部由自己寫,一切順利的情況下,199個方法的mock測試,至少要多出幾倍的時間。

(此測試項目為使用mybatis-plus的項目,service層的實作類非常多的方法直接使用了父類方法,導緻mock很麻煩,耽擱了一些時間,其他項目相對而言會節省更多時間)

測試類:

【Maven插件】自動生成Mock測試代碼primo-generator-mock-test版本功能使用體驗

測試方法:

【Maven插件】自動生成Mock測試代碼primo-generator-mock-test版本功能使用體驗

單元覆寫資料:

【Maven插件】自動生成Mock測試代碼primo-generator-mock-test版本功能使用體驗
【Maven插件】自動生成Mock測試代碼primo-generator-mock-test版本功能使用體驗