Heim > Backend-Entwicklung > Golang > Nutzen Sie Ihre Testsuite mit testcontainers-go und docker-compose

Nutzen Sie Ihre Testsuite mit testcontainers-go und docker-compose

Linda Hamilton
Freigeben: 2024-10-04 16:07:02
Original
211 Leute haben es durchsucht

Leverage Your Test Suite With testcontainers-go & docker-compose

Willkommen zurück, Leute! Heute werden wir die End-to-End-Tests in einem interessanten Blogbeitrag behandeln. Wenn Sie diese Art von Tests noch nie geschrieben haben oder sie verbessern möchten, lesen Sie weiter, während ich Sie durch diese aufregende Reise begleite. Am Ende des Artikels erfahren Sie, wie Sie die Nutzung des Pakets testcontainers-go ermöglichen, damit Ihre Testsuite glänzt.

Die Prämisse?

Bevor wir fortfahren, legen wir die Grenzen für diesen Blogbeitrag fest, da wir verschiedene Konzepte, Tools und Techniken behandeln werden.

Die Überlebensliste ?️

Da wir im weiteren Verlauf des Blogbeitrags auf mehrere Themen eingehen werden, halte ich es für eine gute Idee, sie hier zusammenzustellen.

Die Tools, die ich in diesem Blogbeitrag vorstelle, sind eine Mischung aus Tools, die ich gut kenne, und einigen, die ich zum ersten Mal verwendet habe. Versuchen Sie, diese Tools nicht unüberlegt zu verwenden, sondern bewerten Sie sie basierend auf Ihrem Szenario.

Wir verlassen uns auf:

  • Die Programmiersprache Go
  • Docker
  • Das
  • testcontainers-go-Paket mit dem compose-Modul
  • Das
  • Ginkgo-Test-Framework und das Gomega-Assertion-Paket
Um die Lektüre nicht aufzublähen, werde ich nicht jeden Aspekt und jede Facette der hier vorgestellten Themen behandeln. Ich werde die relevanten Dokumentations-URLs bei Bedarf einfügen.

Das Szenario?

Nehmen wir an, wir müssen End-to-End-Tests für ein Projekt schreiben, das uns nicht gehört. In meinem Fall möchte ich End-to-End-Tests für ein Projekt schreiben, das mit der Programmiersprache Java geschrieben wurde. Da ich nicht wusste, wie man in Java programmiert, bestand meine Testoption nur aus End-to-End-Tests. Der Dienst, den ich testen musste, war eine Reihe von REST-APIs. Die Lösung lag auf der Hand: Trainieren Sie die Endpunkte, indem Sie HTTP-Anfragen ausgeben.

Es ermöglicht das Testen der exponierten Funktionen wie eine Blackbox. Wir müssen uns nur mit der öffentlichen Oberfläche befassen: mit dem, was wir an den Server senden und was wir von ihm zurückbekommen. Nicht mehr und nicht weniger.


Wir kümmern uns um den Endpunkt api/accounts, der die Bankkonten in unserer Datenbank (einer MySQL-Instanz) auflistet. Wir werden diese beiden Anfragen stellen:

Sekarang, anda sepatutnya mempunyai idea yang lebih jelas tentang matlamat kami. Jadi, mari beralih ke kod ujian.

Jom Bergembira?

Dalam bahagian ini, saya membentangkan semua kod berkaitan yang perlu kami tulis untuk ujian hujung ke hujung yang digeruni.

Fail docker-compose.yml

Memandangkan kami tidak peduli dengan kod sumber, titik permulaan ialah fail docker-compose.yml. Kod yang berkaitan ialah:


services:
  mysqldb:
    image: "mysql:8.0"
    container_name: mysqldb
    restart: always
    ports:
      - 3307:3306
    networks:
      - springapimysql-net
    environment:
      MYSQL_DATABASE: transfers_db
      MYSQL_USER: bulk_user
      MYSQL_PASSWORD: root
      MYSQL_ROOT_PASSWORD: root
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  api_service:
    build: .
    container_name: api_service
    restart: always
    ports:
      - 8080:8080
    networks:
      - springapimysql-net
    environment:
      - spring.datasource.url=jdbc:mysql://mysqldb:3306/transfers_db
      - spring.datasource.username=bulk_user
      - spring.datasource.password=root
    depends_on:
      mysqldb:
        condition: service_healthy
    volumes:
      - .m2:/root/.m2

networks:
  springapimysql-net:



Nach dem Login kopieren

Kandungan fail agak mudah. Kita boleh meringkaskan perkara yang ditakrifkan dalam senarai berikut:

  • Perkhidmatan mysqldb tidak layak mendapat penjelasan lanjut
  • Perkhidmatan api_service ialah sistem yang kami uji
  • Rangkaian springapimysql-net mengehoskan dua perkhidmatan yang ditakrifkan di atas

Untuk rujukan Docker Compose lanjut, anda boleh lihat di sini. Sekarang, mari lihat kod ujian hujung ke hujung.

Rangka Kerja Pengujian ginkgo

Rangka kerja ujian ginkgo membantu kami membina suite ujian. Ia ditulis sepenuhnya dalam Go. Tambahan pula, ia menyediakan utiliti CLI untuk menyediakan dan menjalankan ujian. Oleh kerana kita akan menggunakannya kemudian, mari muat turun dari sini. Anda boleh memuat turunnya dalam dua cara:

  1. Dengan menggunakan arahan go install (jika anda telah memasang Go pada sistem anda)
  2. Dengan memuat turun binari yang disusun (berguna jika anda tidak memasang Go pada sistem anda)

Untuk menyemak sama ada anda mempunyai utiliti yang berfungsi pada mesin anda, anda boleh menjalankan perintah versi ginkgo (pada masa penulisan, saya mempunyai versi 2.20.2).

Sila ambil perhatian bahawa arahan ginkgo tidak wajib untuk menjalankan ujian. Anda masih boleh menjalankan ujian tanpa utiliti ini dengan berpegang pada arahan go test.

Walau bagaimanapun, saya amat mengesyorkan anda memuat turunnya kerana kami akan menggunakannya untuk menjana beberapa kod boilerplate.

Letakkan Asas dengan Ginkgo

Terletak dalam direktori akar, mari buat folder yang dipanggil end2end untuk mengehoskan ujian kami. Dalam folder itu, mulakan modul Go dengan mengeluarkan arahan go mod init path/to/your/modul.

Kini, tiba masanya untuk menjalankan perintah ginkgo bootstrap. Ia sepatutnya menghasilkan fail baharu yang dipanggil end2end_suite_test.go. Fail ini mencetuskan suite ujian yang akan kami tentukan sebentar lagi.

Pendekatan ini serupa dengan yang mempunyai pakej testify/suite. Ia menguatkuasakan modulariti dan keteguhan kod memandangkan takrifan dan fasa larian diasingkan.

Sekarang, mari tambahkan ujian pada suite kami. Untuk menjana fail tempat ujian kami akan dijalankan, jalankan perintah ginkgo yang lain: ginkgo generate accounts. Kali ini, fail accounts_test.go muncul. Buat masa ini, mari biarkan ia seperti sedia ada dan beralih ke terminal. Kami membetulkan pakej yang hilang dengan menjalankan arahan Go go mod tidy untuk memuat turun kebergantungan yang hilang secara setempat pada mesin kami.

Fail end2end_suite_test.go

Mari kita mulakan dengan titik masuk suite ujian. Kandungan fail kelihatan kemas:


//go:build integration

package end2end

import (
 "testing"

 . "github.com/onsi/ginkgo/v2"
 . "github.com/onsi/gomega"
)

func TestEnd2End(t *testing.T) {
 RegisterFailHandler(Fail)
 RunSpecs(t, "End2End Suite")
}



Nach dem Login kopieren

Satu-satunya perkara yang luar biasa mungkin ialah dot-import dalam bahagian import. Anda boleh membaca lebih lanjut mengenainya dalam dokumentasi di sini.

Alamak! Bekas ujian liar muncul?

Pada beberapa ketika, kami memerlukan sedikit keajaiban untuk mencapai tahap ujian seterusnya. Ia kebetulan testcontainers-go. Demi demo ini, kami menggunakan modul karang (untuk rujukan lanjut, sila rujuk di sini).

Alat ini boleh menjalankan fail karang yang kita lihat sebelum ini dan melaksanakan ujian hujung ke hujung terhadap bekas yang sedang berjalan.

Ini adalah ekstrak daripada keupayaan testcontainers-go. Jika anda ingin mengetahui lebih lanjut, sila rujuk kepada dokumen atau hubungi. Saya berbesar hati untuk membimbing anda melalui ciri-cirinya yang menakjubkan.

Pakej ini membolehkan menjalankan suite hujung ke hujung dengan satu arahan. Ini adalah cara yang lebih konsisten dan atom untuk menjalankan ujian ini. Ia membolehkan saya:

  1. Mulakan bekas sebelum suite
  2. Jalankan ujian bergantung pada bekas ini
  3. Kosongkan bekas selepas suite dan pembersihan sumber yang digunakan

Memiliki kod ditulis dengan cara ini boleh membantu anda mengelakkan kerumitan berurusan dengan arahan cli docker dan makefiles.

Fail accounts_test.go

Sekarang, mari lihat kod tempat ujian kami dijalankan.


//go:build integration

package end2end

import (
 "context"
 "net/http"
 "os"

 . "github.com/onsi/ginkgo/v2"
 . "github.com/onsi/gomega"
 tc "github.com/testcontainers/testcontainers-go/modules/compose"
 "github.com/testcontainers/testcontainers-go/wait"
)

var _ = Describe("accounts", Ordered, func() {
 BeforeAll(func() {
 os.Setenv("TESTCONTAINERS_RYUK_DISABLED", "true")
 composeReq, err := tc.NewDockerComposeWith(tc.WithStackFiles("../docker-compose.yml"))
  Expect(err).Should(BeNil())
  DeferCleanup(func() {
   Expect(composeReq.Down(context.Background(), tc.RemoveOrphans(true), tc.RemoveImagesLocal)).Should(BeNil())
  })
 ctx, cancel := context.WithCancel(context.Background())
  DeferCleanup(cancel)
 composeErr := composeReq.
   WaitForService("api_service", wait.ForListeningPort("8080/tcp")).
   Up(ctx, tc.Wait(true))
  Expect(composeErr).Should(BeNil())
 })

 Describe("retrieving accounts", func() {
  Context("HTTP request is valid", func() {
   It("return accounts", func() {
 client := http.Client{}
 r, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080/api/accounts?iban=IT10474608000005006107XXXXX", nil)
 res, err := client.Do(r)
    Expect(err).Should(BeNil())
    Expect(res).To(HaveHTTPStatus(http.StatusOK))
   })
  })

  Context("HTTP request is NOT valid", func() {
   It("err with invalid IBAN", func() {
 client := http.Client{}
 r, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080/api/accounts?iban=abcd", nil)
    Expect(err).Should(BeNil())
 res, err := client.Do(r)
    Expect(err).Should(BeNil())
    Expect(res).To(HaveHTTPStatus(http.StatusBadRequest))
   })
  })
 })
})



Nach dem Login kopieren

Pada pandangan pertama, ia mungkin kelihatan sukar untuk dihadam. Untuk memudahkan urusan, mari pecahkannya kepada bahagian yang lebih kecil.

Nod bekas Huraikan

Nod bekas Describe hanyalah pembalut untuk menyimpan kod yang berkaitan untuk suite kami. Segala-galanya mesti hidup di dalamnya. Ia adalah sebahagian daripada kod perancah: var _ = Describe("accounts", Ordered, func() {}. Dalam {}, anda harus meletakkan semua kod yang berkaitan. Untuk menguatkuasakan penggunaan nod persediaan (seperti BeforeAll), kita mesti mentakrifkan bekas Describe as Ordered.

Jangan risau jika anda terlupa menambahnya kerana pengkompil Go akan mengadu.

Mari kita teruskan.

Nod persediaan BeforeAll

Nod ini membolehkan kami mengekstrak logik persediaan biasa. Bahagian kod ini melaksanakan sekali dan sebelum ujian dalam suite. Mari kita imbas semula apa yang dilakukan:

  • Tetapkan pembolehubah persekitaran TESTCONTAINERS_RYUK_DISABLED kepada benar. Anda boleh belajar tentang konfigurasi di sini. Jika anda ingin tahu tentang Ryuk, anda mungkin mahu melihat ini
  • Buat pembolehubah *tc.DockerCompose berdasarkan fail docker-compose.yml yang kami sediakan
  • Tangguhkan seruan fungsi untuk menamatkan bekas dan pembersihan sumber
  • Mulakan susun tindanan dan tunggu bekas yang dipanggil api_service siap dan sedia untuk mendengar pada port 8080/tcp

Saya memudahkan kod ujian kerana saya tidak mahu membuat catatan blog ini lebih lama lagi ?.

Akhirnya, ujian! ?

Fungsi ujian hidup dalam satu Huraikan Nod Bekas. Anda boleh mengetahui cara ginkgo mengendalikan spesifikasi ujian dengan merujuk di sini. Nod Huraikan membolehkan anda mengumpulkan dan mengatur ujian berdasarkan skopnya. Anda boleh menyarangkan nod ini di dalam yang lain Huraikan.

Semakin banyak anda menyarangkan nod Huraikan, semakin anda menyempitkan skop ujian.

Kemudian, kami mempunyai Konteks Nod Bekas yang melayakkan induk Huraikan. Ia melayakkan keadaan di mana ujian itu sah. Akhirnya, kami mempunyai bahagian Ia, Subjek Spec. Ini adalah ujian sebenar yang kami laksanakan dan merupakan tahap daun bagi pokok hierarki. Kod ujian adalah jelas, jadi saya akan melompat ke bahagian di mana kami menjalankan ujian.

3, 2, 1... ?

Tahniah ? Kami berjaya sampai ke sini. Kini, kami hanya terlepas operasi menjalankan ujian. Dalam sekelip mata, kami akan mendapatkan laporan pelaksanaan ujian kami dicetak ke terminal.

Mari bertukar ke terminal dan jalankan perintah ginkgo --tags=integration -v. Selepas beberapa ketika, anda akan melihat output dicetak pada terminal.

Nota Penutup ?

Saya tahu terdapat banyak perkara yang dipendekkan dalam catatan blog ini. Matlamat saya adalah untuk memberikan pandangan dan pendekatan tentang cara menulis suite ujian yang baik. Anda mungkin mahu menyesuaikan alat, pakej dan teknik yang dibentangkan kepada jenis ujian atau kes penggunaan lain.

Sebelum pergi, saya ingin menggariskan satu lagi keindahan modul karang bagi pakej testcontainers-go.

Jika anda berpegang pada konfigurasi yang saya sediakan, anda pasti akan menggunakan imej Docker terkini dan anda boleh mengelakkan penyelesaian masalah berjam-jam akibat penggunaan imej yang sudah lapuk. Ia serupa dengan arahan docker compose build --no-cache && docker compose up. Anda akan berterima kasih kepada saya?

Terima kasih atas perhatian, kawan-kawan! Jika anda mempunyai sebarang soalan, keraguan, maklum balas atau ulasan, saya bersedia untuk mendengar dan bercakap bersama-sama. Jika anda mahu saya membincangkan beberapa konsep khusus, sila hubungi saya. Sehingga lain kali, jaga diri dan jumpa anda ?

Das obige ist der detaillierte Inhalt vonNutzen Sie Ihre Testsuite mit testcontainers-go und docker-compose. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage