Spring、Spring Boot和TestNG測試指南 - 集成測試中用Docker建立數據庫

原文地址html

測試關係型數據庫一篇裏咱們使用的是H2數據庫,這是爲了讓你免去你去安裝/配置一個數據庫的工做,可以儘快的瞭解到集成測試的過程。mysql

在文章裏也說了:git

在真實的開發環境中,集成測試用數據庫應該和最終的生產數據庫保持一致

那麼很容易就能想到兩種解決方案:github

  1. 開發團隊使用共用同一個數據庫。這樣作的問題在於:當有多個集成測試同時在跑時,會產生錯誤的測試結果。
  2. 每一個人使用本身的數據庫。這樣作的問題在於讓開發人員維護MySQL數據庫挺麻煩的。

那麼作到可否這樣呢?spring

  1. 測試啓動前,建立一個MySQL數據庫
  2. 測試過程當中鏈接到這個數據庫
  3. 測試結束後,刪除這個MySQL數據庫

So, Docker comes to the rescue。sql

咱們仍是會以測試關係型數據庫裏的FooRepositoryImpl來作集成測試(代碼在這裏)。下面來說解具體步驟:docker

安裝Docker

請查閱官方文檔。而且掌握Docker的基本概念。數據庫

配置fabric8 docker-maven-plugin

farbic8 docker-maven-plugin顧名思義就是一個可以使用docker的maven plugin。它主要功能有二:apache

  1. 建立Docker image
  2. 啓動Docker container

咱們這裏使用啓動Docker container的功能。segmentfault

大體配置以下

<plugin>
   <groupId>io.fabric8</groupId>
   <artifactId>docker-maven-plugin</artifactId>
   <version>0.28.0</version>

   <configuration>
     <images>
       <image>
         <!-- 使用mysql:8 docker image -->
         <name>mysql:8</name>
         <!-- 定義docker run mysql:8 時的參數 -->
         <run>
           <ports>
             <!-- host port到container port的映射
             這裏隨機選擇一個host port,並將值存到property docker-mysql.port裏 -->
             <port>docker-mysql.port:3306</port>
           </ports>
           <!-- 啓動時給的環境變量,參閱文檔:https://hub.docker.com/_/mysql -->
           <env>
             <MYSQL_ROOT_PASSWORD>123456</MYSQL_ROOT_PASSWORD>
             <MYSQL_DATABASE>test</MYSQL_DATABASE>
             <MYSQL_USER>foo</MYSQL_USER>
             <MYSQL_PASSWORD>bar</MYSQL_PASSWORD>
           </env>
           <!-- 設置斷定container啓動成功的的條件及timeout -->
           <wait>
             <!-- 若是container打出了這行日誌,則說明容器啓動成功 -->
             <log>MySQL init process done. Ready for start up.</log>
             <time>120000</time>
           </wait>
         </run>
       </image>
     </images>
   </configuration>

   <executions>
     <execution>
       <!-- 在集成測試開始前啓動容器 -->
       <id>start</id>
       <phase>pre-integration-test</phase>
       <goals>
         <goal>start</goal>
       </goals>
     </execution>
     <execution>
       <!-- 在集成測試結束後中止並刪除容器 -->
       <id>stop</id>
       <phase>post-integration-test</phase>
       <goals>
         <goal>stop</goal>
       </goals>
     </execution>
   </executions>
 </plugin>

配置maven-failsafe-plugin

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-failsafe-plugin</artifactId>
  <executions>
    <execution>
      <id>integration-test</id>
      <goals>
        <goal>integration-test</goal>
      </goals>
    </execution>
    <execution>
      <id>verify</id>
      <goals>
        <goal>verify</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <!-- 咱們被測的是一個Spring Boot項目,所以能夠經過System Properties把MySQL container的相關信息傳遞給程序
    詳見文檔:https://docs.spring.io/spring-boot/docs/1.5.4.RELEASE/reference/html/boot-features-external-config.html
    -->
    <systemPropertyVariables>
      <spring.datasource.url>jdbc:mysql://localhost:${docker-mysql.port}/test</spring.datasource.url>
      <spring.datasource.username>foo</spring.datasource.username>
      <spring.datasource.password>bar</spring.datasource.password>
    </systemPropertyVariables>
  </configuration>
</plugin>

執行

三種常見用法:

  • mvn clean integration-test,會啓動docker container、運行集成測試。這個頗有用,若是集成測試失敗,那麼你還能夠鏈接到MySQL數據庫查看狀況。
  • mvn clean verify,會執行mvn integration-test、刪除docker container。
  • mvn clean install,會執mvn verify,並將包安裝到本地maven 倉庫。

下面是mvn clean verify的日誌:

...
[INFO] --- docker-maven-plugin:0.28.0:start (start) @ spring-test-examples-rdbs-docker ---
[INFO] DOCKER> [mysql:8]: Start container f683aadfe8ba
[INFO] DOCKER> Pattern 'MySQL init process done. Ready for start up.' matched for container f683aadfe8ba
[INFO] DOCKER> [mysql:8]: Waited on log out 'MySQL init process done. Ready for start up.' 13717 ms
[INFO]
[INFO] --- maven-failsafe-plugin:2.22.1:integration-test (integration-test) @ spring-test-examples-rdbs-docker ---
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
...
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- docker-maven-plugin:0.28.0:stop (stop) @ spring-test-examples-rdbs-docker ---
[INFO] DOCKER> [mysql:8]: Stop and removed container f683aadfe8ba after 0 ms
[INFO]
[INFO] --- maven-failsafe-plugin:2.22.1:verify (verify) @ spring-test-examples-rdbs-docker ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
...

能夠看到fabric8 dmp在集成測試先後start和stop容器的相關日誌,且測試成功。

如何找到MySQL的端口開在哪個呢?運行docker ps查看端口(注意下面的0.0.0.0:32798->3306/tcp):

CONTAINER ID  IMAGE     COMMAND  CREATED  STATUS    PORTS                                NAMES
a1f4b51d7c75  mysql:8   ...      ...      Up 19...  33060/tcp, 0.0.0.0:32798->3306/tcp   mysql-1

參考文檔

相關文章
相關標籤/搜索