Selamat datang kembali, kawan-kawan! Hari ini, kami akan membincangkan ujian hujung ke hujung dalam catatan blog yang menarik. Jika anda tidak pernah menulis jenis ujian ini atau jika anda berusaha untuk memperbaikinya, teruskan membaca kerana saya akan membimbing anda melalui perjalanan yang menarik ini. Pada penghujung artikel, anda akan tahu cara memperkasakan penggunaan pakej testcontainers-go untuk membolehkan suite ujian anda bersinar.
Sebelum bergerak ke hadapan, mari kita tetapkan sempadan untuk catatan blog ini kerana kita akan merangkumi beberapa konsep, alatan dan teknik.
Memandangkan kita akan menyentuh beberapa topik sepanjang catatan blog yang lain, saya rasa adalah idea yang baik untuk meletakkannya di sini.
Alat yang saya bentangkan sepanjang catatan blog ini adalah gabungan alat yang saya tahu dengan baik dan beberapa yang saya gunakan buat kali pertama. Cuba untuk tidak menggunakan alatan ini tanpa berfikir, tetapi nilaikannya berdasarkan senario anda.
Kami akan bergantung pada:
Untuk mengelakkan pembacaan kembung, saya tidak akan membincangkan setiap aspek dan aspek topik yang dibentangkan di sini. Saya akan meletakkan URL dokumentasi yang berkaitan di mana perlu.
Anggap kita perlu menulis ujian hujung ke hujung pada projek yang bukan milik kita. Dalam kes saya, saya ingin menulis ujian hujung ke hujung pada projek yang ditulis dengan bahasa pengaturcaraan Java. Memandangkan saya tidak tahu cara membuat kod dalam Java, pilihan ujian saya hanyalah ujian hujung ke hujung. Perkhidmatan yang perlu saya uji ialah satu set API REST. Penyelesaiannya telah jelas: gunakan titik akhir dengan mengeluarkan permintaan HTTP.
Ia membolehkan menguji ciri yang terdedah seperti kotak hitam. Kami hanya perlu berurusan dengan permukaan awam: apa yang kami hantar ke pelayan dan apa yang kami dapat kembali daripadanya. Tiada lebih, tiada kurang.
Kami mengambil berat tentang titik akhir api/akaun yang menyenaraikan akaun bank dalam pangkalan data kami (contoh MySQL). Kami akan mengeluarkan dua permintaan ini:
HTTP Method | Address | Expected Status Code |
---|---|---|
GET | api/accounts?iban=IT10474608000005006107XXXXX | 200 StatusOK |
GET | api/accounts?iban=abc | 400 StatusBadRequest |
Sekarang, anda sepatutnya mempunyai idea yang lebih jelas tentang matlamat kami. Jadi, mari beralih ke kod ujian.
Dalam bahagian ini, saya membentangkan semua kod berkaitan yang perlu kami tulis untuk ujian hujung ke hujung yang digeruni.
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:
Kandungan fail agak mudah. Kita boleh meringkaskan perkara yang ditakrifkan dalam senarai berikut:
Untuk rujukan Docker Compose lanjut, anda boleh lihat di sini. Sekarang, mari lihat kod ujian hujung ke hujung.
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 kami akan menggunakannya kemudian, mari muat turun dari sini. Anda boleh memuat turunnya dalam dua cara:
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.
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.
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") }
Satu-satunya perkara yang luar biasa mungkin ialah dot-import dalam bahagian import. Anda boleh membaca lebih lanjut mengenainya dalam dokumentasi di sini.
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:
Memiliki kod ditulis dengan cara ini boleh membantu anda mengelakkan kerumitan berurusan dengan arahan cli docker dan makefiles.
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)) }) }) }) })
Pada pandangan pertama, ia mungkin kelihatan sukar untuk dihadam. Untuk memudahkan urusan, mari pecahkannya kepada bahagian yang lebih kecil.
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 ini membolehkan kami mengekstrak logik persediaan biasa. Bahagian kod ini melaksanakan sekali dan sebelum ujian dalam suite. Mari kita imbas semula apa yang dilakukan:
Saya memudahkan kod ujian kerana saya tidak mahu membuat catatan blog ini lebih lama lagi ?.
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.
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.
Saya tahu terdapat banyak perkara yang dipendekkan ke dalam catatan blog ini. Matlamat saya adalah untuk memberikan pandangan dan pendekatan tentang cara menulis suite ujian yang baik. Anda mungkin ingin 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 lagi ?
Atas ialah kandungan terperinci Manfaatkan Suite Ujian Anda Dengan testcontainers-go & docker-compose. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!