<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Dockertest 極速搭建集成測試環(huán)境神器

          共 7630字,需瀏覽 16分鐘

           ·

          2022-05-15 14:12

          1 推薦背景

          在開發(fā)應用程序時,經(jīng)常需要與數(shù)據(jù)庫系統(tǒng)交互的服務,如,各種數(shù)據(jù)庫,以及 minio,Kafka,Redis 等服務組件,沒錯Dockertest 基本都支持主流數(shù)據(jù)庫和服務組件。對這些服務進行集成測試是很麻煩的,因為模擬數(shù)據(jù)庫/數(shù)據(jù)庫抽象層是很費勁的一件事。對模式進行細微的更改意味著至少重寫部分(如果不是全部)模擬;數(shù)據(jù)庫抽象層中的API 變化也是如此。為了避免這種情況,更聰明的做法是用一個真實的數(shù)據(jù)庫來測試這些特定的服務,而這個數(shù)據(jù)庫在測試后就會被銷毀。Docker 是運行集成測試的完美系統(tǒng),因為我們可以在幾秒鐘內(nèi)啟動容器,并在測試完成后殺死它們。
          Dockertest 庫提供了易于使用的命令來啟動 Docker 容器并在測試中使用它們,解決以上提到的集成測試問題,不需要通過 Dockerfile 或 docker-compose 手動設置 Docker。

          2 怎么使用

          第一步:安裝

             
          go get -u github.com/ory/dockertest/v3

          第二步:使用

          這里測試目標是用 Iris 搭建的 Web API ,即用 Dockertest 來啟動 Docker 容器并模擬 Web 服務器和數(shù)據(jù)庫,請確保環(huán)境中已安裝 Docker 。
          使用 Dockertest 設置基礎設施的最簡單方法是在測試文件的 TestMain 函數(shù)中添加設置代碼,這個測試示例中會生成 Postgres Docker 容器,Web API 的代碼請瀏覽
          https://codeload.github.com/jonnylangefeld/go-api-base-project/zip/refs/tags/part-2
          下載,并在項目根目錄下創(chuàng)建 main_test.go 文件,寫入以下測試示例代碼
             
          package main

          import (
           "encoding/json"
           "fmt"
           "log"
           "os"
           "testing"
           "time"

           "my-go-api/model"

           "github.com/jinzhu/gorm"
           "github.com/kataras/iris"
           "github.com/kataras/iris/httptest"
           "github.com/ory/dockertest"
           "github.com/ory/dockertest/docker"
           "github.com/stretchr/testify/assert"
          )


          var db *gorm.DB
          var app *iris.Application

          func TestMain(m *testing.M) 
          {
           // Create a new pool for docker containers
           pool, err := dockertest.NewPool("")
           if err != nil {
            log.Fatalf("Could not connect to docker: %s", err)
           }

           // Pull an image, create a container based on it and set all necessary parameters
           opts := dockertest.RunOptions{
            Repository:   "mdillon/postgis",
            Tag:          "latest",
            Env:          []string{"POSTGRES_PASSWORD=123456"},
            ExposedPorts: []string{"5432"},
            PortBindings: map[docker.Port][]docker.PortBinding{
             "5432": {
              {HostIP: "0.0.0.0", HostPort: "5477"},
             },
            },
           }

           // Run the docker container
           resource, err := pool.RunWithOptions(&opts)
           if err != nil {
            log.Fatalf("Could not start resource: %s", err)
           }

           // Exponential retry to connect to database while it is booting
           if err := pool.Retry(func() error {
            databaseConnStr := fmt.Sprintf("host=localhost port=5477 user=postgres dbname=postgres password=123456 sslmode=disable")
            db, err = gorm.Open("postgres", databaseConnStr)
            if err != nil {
             log.Println("Database not ready yet (it is booting up, wait for a few tries)...")
             return err
            }

            // Tests if database is reachable
            return db.DB().Ping()
           }); err != nil {
            log.Fatalf("Could not connect to docker: %s", err)
           }

           log.Println("Initialize test database...")
           initTestDatabase()

           log.Println("Create new iris app...")
           app = newApp(db)

           // Run the actual test cases (functions that start with Test...)
           code := m.Run()

           // Delete the docker container
           if err := pool.Purge(resource); err != nil {
            log.Fatalf("Could not purge resource: %s", err)
           }

           os.Exit(code)
          }

          func TestName(t *testing.T) {
           // Request an endpoint of the app
           e := httptest.New(t, app, httptest.URL("http://localhost"))
           t1 := e.GET("/bill").Expect().Status(iris.StatusOK)

           // Compare the actual result with an expected result
           assert.Equal(t, "Hello bill", t1.Body().Raw())
          }

          func TestOrders(t *testing.T) {
           e := httptest.New(t, app, httptest.URL("http://localhost"))
           t1 := e.GET("/orders").Expect().Status(iris.StatusOK)

           expected, _ := json.Marshal(sampleOrders)
           assert.Equal(t, string(expected), t1.Body().Raw())
          }

          func initTestDatabase() {
           db.AutoMigrate(&model.Order{})

           db.Save(&sampleOrders[0])
           db.Save(&sampleOrders[1])
          }

          var sampleOrders = []model.Order{
           {
            ID:          1,
            Description: "An old glove",
            Ts:          time.Now().Unix() * 1000,
           },
           {
            ID:          2,
            Description: "Something you don't need",
            Ts:          time.Now().Unix() * 1000,
           },
          }

          第三步:運行測試示例

             
          go test -v
          執(zhí)行成功會打印測試結果,失敗會給出反饋:
             
          2022/05/08 10:10:43 Database not ready yet (it is booting up, wait for a few tries)...
          2022/05/08 10:10:49 Database not ready yet (it is booting up, wait for a few tries)...
          2022/05/08 10:10:55 Initialize test database...
          2022/05/08 10:10:55 Create new iris app...
          === RUN   TestName
          --- PASS: TestName (0.00s)
          === RUN   TestOrders
          --- PASS: TestOrders (0.00s)
          PASS
          ok      my-go-api       25.706s
          以這種方式可以在每個測試模塊上執(zhí)行,單獨模塊服務在新容器中運行,從而使測試完全獨立,測試完即可銷毀容器,就好像什么都沒發(fā)生一樣。
          更多示例請瀏覽:
          https://codeload.github.com/jonnylangefeld/go-api-base-project/zip/refs/tags/part-

          3 總結

          使用Dockertest可以在不修改業(yè)務邏輯或者服務模式的情況下就能夠對應用服務組件進行集成測試,上手無需任何額外技能,很易用,推薦大家使用。
          歡迎加入 GOLANG 中國社區(qū):
           https://gocn.vip

          參考資料

          • https://github.com/ory/dockertest

          • https://pkg.go.dev/github.com/ory/dockertest#section-readme

          • https://jonnylangefeld.com/blog/how-to-write-a-go-api-part-3-testing-with-dockertest

          • https://medium.com/easyread/integration-test-database-in-golang-using-dockertest-59ed3b35240e


          想要了解更多相關的內(nèi)容,歡迎掃描下方?? 關注 公眾號,回復關鍵詞 [實戰(zhàn)群]  ,就有機會進群和我們進行交流~

          瀏覽 29
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人AV片导航 | 一区二区三区四区五区六区久久 | 亚洲情热| 亚洲系列在线 | 日本香蕉色 |