使用遠端Docker進行整合測試

西北偏北UP發表於2021-07-04

需求背景

團隊有整合測試的需求,整合測試需要依賴一些中介軟體,比如mysql,rabbitmq。每個研發人員有對自己開發的那部分程式碼進行測試編寫和執行檢測的需求。

為了不互相影響,可以選擇在研發本地搭建自己的依賴環境,我們希望這些環境搭建要容易、快速,且方便清理。

使用docker進行環境搭建

而docker,則能很好實現上述訴求。
但僅僅這樣還不夠,我們還面臨著以下一些問題

  • 本地環境搭建的繁瑣。每個研發,都要在本地安裝docker環境,這會導致在使用上的一些門檻和不便,以我司為例,由於有嚴格的網路管控,我們都是內網進行開發,無法聯網。特別windows 在安裝docker時,需要聯網。雖然可以想辦法解決,但每個新來小夥伴都要經歷一些本地環境安裝除錯過程,實屬繁瑣
  • 測試執行速度無法保證。當一個專案依賴中介軟體較多時,基於本地的docker也會佔用大量的資源影響測試速度
  • 多環境整合測試麻煩。由於整合測試依賴本地docker,那麼這份程式碼在不同的環境,比如在Jenkins上打包執行時,需要在對應的環境也安裝docker

總結來看,使用docker可以幫助我們快速的搭建專案依賴環境,但是本地化的docker依賴,依然讓我們的程式碼在測試時,不夠純粹,對其各個執行環境,都有有本地docker安裝的要求。

以中心化的docker server改進整合測試

而實際上,docker本身提供了遠端連結模式,則使得我們可以中心化的部署docker,然後整合測試程式碼以tcp連結的方式,使用docker server,進行依賴中介軟體搭建,測試。

Docker Server遠端連結配置

以centos 為例7.6為例,講解如何將一個docker配置成可以遠端連結。

  • /etc/docker/daemon.json中開啟遠端連結埠

     {"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]}
    
  • 新增檔案/etc/systemd/system/docker.service.d/override.conf,注意上述路徑不存在則手動建立

     [Service]
     ExecStart=
     ExecStart=/usr/bin/dockerd
    
  • 過載守護程式 systemctl daemon-reload

  • 重啟docker容器systemctl restart docker.service

Testcontainers 框架

在部署好遠端docker後,隨之而來的問題是

  • 如何在程式碼中連線和使用遠端docker環境
  • 兩個研發同時跑測試用例時,怎麼保證他們各自啟動的container 在埠上不衝突
  • 使用完後的container,怎麼清理

幸運的是,Testcontainers框架,幫我們很好的解決了上述問題。

  • 它能於junit 4 ,junit 5整合,幫助我們啟停容器
  • 每一次執行測試,都會啟動全新的容器,暴露不一樣的埠,使得兩個研發同時跑測試用例時,環境互不干擾
  • 它使用testcontainers/ryuk在指定延遲後,清理不再使用的container
  • 上述這一切對使用者都是透明的

Testcontainers 同spring boot整合

更進一步的, 遊戲公司Playtika提供了Testcontainers 同spring boot整合的測試框架https://github.com/Playtika/testcontainers-spring-boot,使得Spring Boot或Spring cloud生態的應用在編寫整合測試時,更方便

環境變數依賴

使用Testcontainers 或 playtika的testcontainers-spring-boot進行遠端docker連結時,都不需要在本地安裝docker客戶端。但需要進行相關環境變數配置,使得程式碼可以知道遠端docker的地址。該地址的配置有如下幾種方式

  • 方式1,系統環境變數配置,在當前系統配置環境變數DOCKER_HOST=tcp://remote_docker_server_ip:2375
  • 方式2,直接在java測試程式碼中,容器構造前,通過程式碼System.setProperty("DOCKER_HOST","tcp://remote_docker_server_ip:2375")指定環境變數
  • 方式3,如果整合測試使用maven failsafe外掛,則在外掛上配置環境變數
    file

以command line遠端使用和管理docker

上述測試程式碼不需要安裝docker 客戶端。但倘若我們需要以命令列的方式,管理docker,則可以安裝一些docker客戶端,來跟遠端docker通訊。當然上述的Testcontainers 相當於客戶端的一種。

不同作業系統的客戶端程式安裝方式見: https://gist.github.com/kekru/4e6d49b4290a4eebc7b597c07eaf61f2

參考資料

https://www.testcontainers.org/
https://gist.github.com/styblope/dc55e0ad2a9848f2cc3307d4819d819f
https://github.com/Playtika/testcontainers-spring-boot
https://gist.github.com/kekru/4e6d49b4290a4eebc7b597c07eaf61f2

歡迎關注我的個人公眾號"西北偏北UP",記錄程式碼人生,行業思考,科技評論

相關文章