走進Java接口測試之從0到1搭建數據驅動框架(需求篇)

前言

一個 “好的” 數據驅動框架,需要從“時間”、“人力”、“收益”這三個方面出發,做好“取捨”。

不能由於被測業務系統發生一些變更,就導致花費了幾個小時的腳本無法執行。同時,我們需要看到“收益”,不能爲了總想看到100%的成功,而減少必須做的工作,這導致可能都需要進行大量的維護。

所以做好這三個方面的平衡並不容易,想要提高 ROI(投入產出比),我們必須從兩方面入手:

  • 減少開發成本。
  • 增加使用便利度。

針對“減少開發成本”,我們需要做到:

  • 減少持久層開發的成本。儘可能的減少開發、維護的時間,儘可能使用公司已有的,或是業界成熟的工具或組件;
  • 減少用例錄入成本。簡化測試用例錄入的方式,做到腳本和測試數據解耦,如果可以開發一些批量生成測試數據工具;
  • 減少用例維護成本。減少用例維護成本,儘量只用在參數上做簡單的變更即可完成維護動作,而不是進行大量的代碼操作。

針對“增加使用便利度”,我們需要做到:

  • 手工測試也能用,不需要進行接口用例邏輯開發,也可以準備測試數據;
  • 在開發和調試階段,可以幫助我們更快的定位問題;
  • 在測試的運維過程中,可以幫助我們記錄大部分的異常信息;
  • 支持對數據庫測試狀態進行實時監控預警。

所以,我這邊開發了一個數據驅動框架,來實現我對數據驅動想法的一些實踐。

目前遇到的痛點

測試用例管理

這裏不提倡把測試用例直接硬編碼寫在 Java 文件中,因爲這樣做會帶來很多問題:

  • 修改測試用例需要改動大量的代碼;
  • 代碼也不便於交接給其他同學,因爲每個人都有自己的編碼風格和用例設計風格,這樣交接,最後都會變成由下一個同學全部推翻重寫一遍;
  • 如果測試框架更換,無法做用例數據的遷移,只能手動介入,效率很低。

所以 “測試數據” 與 “腳本” 分離是非常有必要的

網上很多的範例是使用的 Excel 進行的數據驅動,而我這裏推薦使用關係型數據庫 MySQL,爲什麼呢?
一般我們的腳本和代碼都是提交至公司的 GitLab 倉庫,如果使用 Excel 很顯然不方便日常經常修改測試用例的情況,因爲我們需要做到版本控制,集中式管理。使用 MySQL 就沒有這樣的煩惱了,由於數據與腳本的分離,只需對數據進行修改即可,腳本每次會在數據庫中讀取最新的用例數據進行測試。同時,還可以防止一些操作代碼時的誤操作。

多業務數據源

作爲一個測試開發工程師,自動化接口測試經常要連 N個數據源。對於多數據源,網上提供了重寫:
數據據庫這邊的配置:

mybatis.config-location=classpath:mybatis/mybatis-config.xml

spring.datasource.test1.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.test1.username=root
spring.datasource.test1.password=root
spring.datasource.test1.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.test2.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.test2.username=root
spring.datasource.test2.password=root
spring.datasource.test2.driver-class-name=com.mysql.cj.jdbc.Driver

一個 test1 庫和一個 test2 庫,其中 test1 位主庫,在使用的過程中必須指定主庫,不然會報錯:

@Configuration
@MapperScan(basePackages = "com.zuozewei.mapper.test1", sqlSessionTemplateRef  = "test1SqlSessionTemplate")
public class DataSource1Config {

    @Bean(name = "test1DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.test1")
    @Primary
    public DataSource testDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "test1SqlSessionFactory")
    @Primary
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "test1TransactionManager")
    @Primary
    public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "test1SqlSessionTemplate")
    @Primary
    public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

一層一層注入,首先創建 DataSource,然後創建 SqlSessionFactory 再創建事務,最後包裝到 SqlSessionTemplate 中。其中需要指定分庫的 mapper 文件地址,以及分庫dao層代碼:

@MapperScan(basePackages = "com.zuozewei.mapper.test1", sqlSessionTemplateRef  = "test1SqlSessionTemplate")

這塊的註解就是指明瞭掃描 dao 層,並且給 dao 層注入指定的 SqlSessionTemplate。所有 @Bean 都需要按照命名指定正確。dao 層和 xml 需要按照庫來分在不同的目錄,比如:test1 庫 dao 層在 com.zuozewei.mapper.test1 包下,test2 庫在com.zuozewei.mapper.test2。

這個方式,確實可用,不足在於,需要根據不同數據源建立不同的 package,一旦數據源發生變更,需要更改所在的 package。也看過了動態數據源,那也不是我們想要的。

持久層開發

在使用 Mybatis 的時候,Dao 接口,Entity 實體類,還有每個實體類對應的 xml 都得自己寫,這其實也是工作量很大的事情,維護起來也很費勁。

日誌管理

一個成熟的接口測試框架,日誌管理這個是必不可少的。在開發和調試階段,日誌可以幫助我們更快的定位問題;而在測試的運維過程中,日誌系統又可以幫助我們記錄大部分的異常信息,通常很多測試框架會通過收集日誌信息來對接口測試狀態進行實時監控預警,比如慢SQL。

主流技術棧

主要考慮以下幾個方面:

  • 開發更簡單;
  • 測試更簡單;
  • 配置更簡單;
  • 部署更簡單;
  • 基於主流的框架;
  • 具備市場競爭能力。

主要功能

所以,總結以上的需求,我畫了一個圖:
在這裏插入圖片描述

功能描述

  • 靈活支持多業務數據源;
  • 測試用例集中式管理,結構化數據;
  • 數據驅動做到腳本與測試數據解耦;
  • 豐富的日誌管理功能,支持異常監控,便於開發調試;
  • 支持性能監控,比如業務數據源的慢SQL;
  • 開發的便利性,能節省重複工作,降低開發成本;
  • 靈活的擴展性,滿足自定義的數據類型;
  • 主流的技術棧,能跟上互聯網技術節奏,不易於快速被淘汰;
  • 友好的代碼結構及註釋,便於閱讀及二次開發。

小結

本文總結了數據驅動框架中一些常見的痛點和一些必備的功能,這決定後續我們的框架如何去設計,希望對你能有所啓發。

參考資料:
[1]:Lego-美團接口自動化測試實踐
[2]:在Mybatis-spring上基於註解的數據源實現方案

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章