歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> 學習Linux

Docker 容器測試全探索

Docker 容器測試全探索


Docker 容器測試全探索


導讀當我們構建好Docker鏡像並利用多套容器共同組合成應用程序,建立起持續交付通道,了解了如何將新創建的鏡像納入到生產或者測試環境當中之後,新的問題來了——我們該如何測試自己的Docker容器?測試的策略多種多樣,反映了各種各樣的測試性格:天真型,懶人省事型,超前理想主義型,完美主義處女座型……那麼你是哪一型?下面我們就對其各自的方案利弊進行逐一分析。“天真”型方案

大多數人會將此作為默認方案。其利用CI服務器實現任務執行。在這項方案中,開發人員利用Docker作為軟件包管理器,其實際效果優於jar/rpm/deb方案。CI服務器對應用程序代碼進行編譯,而後執行測試(包括單元、服務及功能等)。Docker中的build可復用以生成新的鏡像,由此生成的鏡像不僅包含應用程序的“二進制代碼”,同時亦擁有運行時所必需的依賴性及配置。

不過為了實現應用程序的可移植性,我們需要放棄開發與測試的可移植能力。在這種情況下,我們無法在CI之外重新建立同樣的開發與測試環境。為了創始這樣一套新的測試環境,我們需要設置測試工具(正確版本與插件)、配置運行時與操作系統設定,同時獲取相同版本的測試腳本與測試數據。
Docker 容器測試全探索Docker 容器測試全探索
為了解決上述難題,我們需要考慮以下方案。

應用&測試容器方案

現在我們嘗試創建單一捆綁包,其中應用程序“二進制代碼”中包含全部必需的軟件包、測試工具(包括對應版本)、測試工具插件、測試腳本以及其它各類測試環境元素。但這種方式也存在著顯著弊端:
鏡像體積直線增長——這是因為其中包含有測試工具、必要軟件包、測試腳本甚至是測試數據。
特定測試配置可能對鏡像運行時環境造成污染,甚至引入不必要的依賴性(集成測試中需要用到)。
我們還需要考慮如何處理測試結果與記錄日志;

如何將其導出以及向哪裡導出,通過以下經過簡化的 Dockerfile,我們可以了解上述方案的整個流程。

FROM "":""WORKDIR ""# install packages required to run app and testsRUN apt-get update && apt-get install -y /" and " / # add app runtime and required packages" and " / # add testing tools and required packages&& rm -rf /var/lib/apt/lists/*# copy app filesCOPY app appCOPY run.sh run.sh# copy test scriptsCOPY tests tests# copy "main" test commandCOPY test.sh test.sh# ... EXPOSE, RUN, ADD ... for app and test environment# main app commandCMD [run.sh, ""]# it's not possible to have multiple CMD commands, but this is the "main" test command# CMD [/test.sh, ""]

Docker 容器測試全探索Docker 容器測試全探索
毫無疑問,應該有更好的容器內測試方案可供選擇。

測試感知型容器方案

目前,Docker承諾以“Build -> Ship -> Run”這一簡單操作完成鏡像構建、發布至注冊表並在其它位置運行等任務。Test這一重要環節,正確且完整的流程應該是Build -> Test -> Ship -> Run。 下面讓我們看看能夠為Docker命令提供“測試友好”型語法與擴展的Dockerfile是如何建立而成的。“理想”版本,大家應該能夠看出其中可用於實踐的指導思路。

ONTEST [INSTRUCTION]

首先定義一條特殊的ONTEST指令,其與現有ONBUILD指令非常相似。ONTEST指令會向鏡像添加一條觸發指令,其在隨後鏡像接受測試時自動執行。任意build指令都可被注冊為觸發條件。

ONTEST指令可由一條新的docker test命令進行識別。

docker test [OPTIONS] IMAGE [COMMAND] [ARG...]

事實上,docker test命令的語法與docker run命令非常相似,docker test會自動生成一套新的“可測試”鏡像,執行全部build操作,於ONTEST命令後進行定義並執行ONTEST CMD(或者ONTEST ENTRYPOINT)。其中若測試發生錯誤,docker test命令應當返回一段非零代碼。此測試結果應當被寫入至自動生成且指向/var/tests/results文件夾的VOLUME。

下面我們來看看經過修改的Dockerfile——其中包含新的ONTEST指令。

FROM "":""WORKDIR ""# install packages required to run appRUN apt-get update && apt-get install -y /" and " / # add app runtime and required packages&& rm -rf /var/lib/apt/lists/*# install packages required to run testsONTEST RUN apt-get update && apt-get install -y /" and " / # add testing tools and required packages&& rm -rf /var/lib/apt/lists/*# copy app filesCOPY app appCOPY run.sh run.sh# copy test scriptsONTEST COPY tests tests# copy "main" test commandONTEST COPY test.sh test.sh# auto-generated volume for test results# ONTEST VOLUME "/var/tests/results"# ... EXPOSE, RUN, ADD ... for app and test environment# main app commandCMD [run.sh, ""]# main test commandONTEST CMD [/test.sh, ""]

Docker 容器測試全探索Docker 容器測試全探索

如何實現“測試感知容器”

Docker擁有ONBUILD這樣一條非常實用的指令。該指令允許我們在已經成功的build之上觸發另一build指令。其基本思路是在運行docker-test命令的同時,使用ONBUILD指令。

以下為docker-test命令的執行流程:

docker-test將在應用程序Dockerfile當中搜索ONBUILD指令後,利用初始Dockerfile生成臨時的Dockerfile.test,再執行docker build -f Dockerfile.test [OPTIONS] PATH,其中包含受docker build命令支持的其它選項:-test將自動被添加至tag選項當中。
如果構建成功,則執行 docker run -v ./tests/results:/var/tests/results [OPTIONS] IMAGE:TAG-test [COMMAND] [ARG...]移除Dockerfile.test文件
那麼,為什麼不創建一個無需配合ONBUILD指令的Dockerfile.test文件?

這是因為,為了測試正確的鏡像(及標簽),我們需要保證FROM始終在測試目標的image:tag中得到不過前面提到的方案仍然存在局限——其不適用於“onbuild”鏡像(即用於自動化構建應用的鏡像),例如Maven:onbuild。

下面來看一條簡單的docker-test命令實現流程。其中強調了一大重要概念:docker-test命令應當能夠處理build與run命令選項,同時能夠妥善處理錯誤狀況。

#!/bin/bashimage="app"tag="latest"echo "FROM ${image}:${tag}" > Dockerfile.test &&docker build -t "${image}:${tag}-test" -f Dockerfile.test . &&docker run -it --rm -v $(pwd)/tests/results:/var/tests/results "${image}:${tag}-test" &&rm Dockerfile.test

讓我們把注意力集中在最值得關注的重要部分。

集成測試型容器方案

假設我們擁有一套自動化CI/CD通道,我的的應用程序由數十甚至數百項微服務構建而成,每項微服務都由CI進行構建與測試,並在之後被部署到某種環境當中(例如測試、分段或者生產環境)。我們的CI會對各項微服務進行分別測試——運行單元與服務測試(或者API合同測試)。甚至有可能進行微集成測試——即將測試運行在特設的子系統之上但這又會帶來一些新問題:

實際集成測試或者長期運行測試該如何完成(例如性能與壓力測試)?彈性測試該如何實現(例如‘混亂猴子’測試)?如何實現安全掃描?那些需要耗費較長時間且運行在完整操作系統之上的測試與掃描要如何完成?

應當存在一類特殊的集成測試容器。這些容器將僅包含測試工具與測試元素:測試腳本、測試數據、測試環境配置等等。為了簡化此類容器的編排與自動化流程,我們應當定義並遵循某些約定並使用元數據標簽(Dockerfile中的LABEL指令)。

集成測試標簽

test.type – 測試類型,負責定義integration; 可屬於 integration, performance, security, chaos 或者其它任意文本之一; 此標簽代表其屬於一套集成測試容器

test.results – 用於存放測試結果的VOLUME ; 默認位置為 /var/tests/results

test.XXX -任何其它相關元數據,僅使用test.後綴名作為標簽名稱

集成測試容器

集成測試容器其實就是一種常規Docker容器,其中不包含任何應用程序邏輯及代碼。它的惟一用途就是創建可重復且可移植的測試流程。以下為建議納入集成測試容器的內容:

測試工具 - Phantom.js, Selenium, Chakram, Gatling, …測試工具運行時 - Node.js, JVM, Python, Ruby, …測試管理配置 – 環境變量, 配置文件, 引導腳本, …測試 -作為經過編譯的軟件包或者腳本文件存在測試數據 – 任何用於測試的數據文件類型: json, csv, txt, xml, …測試啟動腳本 -用於運行測試的部分“main”啟動腳本,僅負責創建test.sh並借此啟動該測試工具。

集成測試容器應當運行在全部微服務都已經部署到位的運營環境之下,這些容器可與其它服務采取一致的部署方式。在實際集成測試當中,我們必須對多項服務進行訪問來測試多種不同環境下是否能正常運行。將集成測試納入應用服務容器不僅會增加容器自身體積,同時亦會在各服務之間帶來不必要的依賴性。因此,我們將所有依賴性都限制在集成測試容器當中。

原文來自:https://linux.cn/article-7689-1.html

本文地址:http://linuxprobe.com/docker-test-probe.html


http://xxxxxx/Linuxjc/1156036.html TechArticle

Copyright © Linux教程網 All Rights Reserved