Apakah ada praktik terbaik yang ditetapkan untuk memisahkan pengujian unit dan pengujian integrasi di GoLang (bersaksi)? Saya memiliki campuran tes unit (yang tidak bergantung pada sumber daya eksternal dan dengan demikian berjalan sangat cepat) dan tes integrasi (yang bergantung pada sumber daya eksternal dan dengan demikian berjalan lebih lambat). Jadi, saya ingin dapat mengontrol apakah akan menyertakan tes integrasi atau tidak ketika saya katakan go test
.
Teknik yang paling lurus ke depan adalah dengan mendefinisikan sebuah flag -integrate di main:
var runIntegrationTests = flag.Bool("integration", false
, "Run the integration tests (in addition to the unit tests)")
Dan kemudian untuk menambahkan pernyataan-if ke bagian atas dari setiap pengujian integrasi:
if !*runIntegrationTests {
this.T().Skip("To run this test, use: go test -integration")
}
Apakah ini yang terbaik yang bisa saya lakukan? Saya mencari dokumentasi bersaksi untuk melihat apakah mungkin ada konvensi penamaan atau sesuatu yang menyelesaikan ini untuk saya, tetapi tidak menemukan apa pun. Apakah saya melewatkan sesuatu?
sumber
var integration = flag.Bool("integration", true, "Enable integration testing.")
luar fungsi, variabel akan muncul dalam cakupan paket, dan flag akan bekerja dengan baikJawaban:
@ Ainar-G menyarankan beberapa pola bagus untuk memisahkan pengujian.
Kumpulan praktik Go dari SoundCloud ini merekomendasikan penggunaan tag build ( dijelaskan di bagian "Batasan Build" dari paket build ) untuk memilih pengujian mana yang akan dijalankan:
Sebagai opsi serupa, Anda juga bisa menjalankan pengujian integrasi secara default dengan menggunakan kondisi build
// +build !unit
, lalu menonaktifkannya sesuai permintaan dengan menjalankango test -tags=unit
.@adamc komentar:
Untuk orang lain yang mencoba menggunakan tag build, penting bahwa
// +build test
komentar tersebut adalah baris pertama dalam file Anda, dan Anda menyertakan baris kosong setelah komentar, jika tidak,-tags
perintah akan mengabaikan perintah tersebut.Selain itu, tag yang digunakan dalam komentar build tidak boleh menggunakan tanda hubung, meskipun garis bawah diperbolehkan. Misalnya,
// +build unit-tests
tidak akan berhasil, sedangkan// +build unit_tests
akan.sumber
// + build unit
pengujian unit dan menggunakan -tag unit untuk menjalankan pengujian// +build
komentar pengujian adalah baris pertama dalam file Anda, dan Anda menyertakan baris kosong setelah komentar, jika tidak,-tags
perintah akan mengabaikan perintah tersebut. Selain itu, tag yang digunakan dalam komentar build tidak boleh menggunakan tanda hubung, meskipun garis bawah diperbolehkan. Misalnya,// +build unit-tests
tidak akan berhasil, sedangkan// +build unit_tests
akango test -tags=integration ./...
tidak bekerja, itu mengabaikan tagUntuk menguraikan komentar saya untuk jawaban yang sangat baik @ Ainar-G, selama setahun terakhir saya telah menggunakan kombinasi
-short
denganIntegration
konvensi penamaan untuk mencapai yang terbaik dari kedua dunia.Unit dan Integrasi menguji harmoni, dalam file yang sama
Bendera build sebelumnya memaksa saya memiliki banyak file (
services_test.go
,services_integration_test.go
, dll).Sebagai gantinya, ambil contoh di bawah ini di mana dua yang pertama adalah pengujian unit dan saya memiliki pengujian integrasi di bagian akhir:
Perhatikan tes terakhir memiliki konvensi:
Integration
dalam nama tes.-short
perintah bendera.Pada dasarnya, spesifikasi tersebut berbunyi: "tulis semua pengujian secara normal. Jika ini adalah pengujian yang berjalan lama, atau pengujian integrasi, ikuti konvensi penamaan ini dan periksa
-short
bersikap baik kepada rekan Anda."Jalankan hanya tes Unit:
ini memberi Anda serangkaian pesan yang bagus seperti:
Jalankan Tes Integrasi saja:
Ini hanya menjalankan tes integrasi. Berguna untuk kenari penguji asap dalam produksi.
Jelas sisi negatif dari pendekatan ini adalah jika ada yang menjalankan
go test
, tanpa ekstensi-short
flag, itu akan secara default menjalankan semua tes - tes unit dan integrasi.Pada kenyataannya, jika proyek Anda cukup besar untuk memiliki pengujian unit dan integrasi, kemungkinan besar Anda menggunakan di
Makefile
mana Anda dapat memiliki arahan sederhana untuk digunakango test -short
di dalamnya. Atau, masukkan saja ke dalamREADME.md
file Anda dan hentikan.sumber
import
membuat paket dan mengujinya, yang akhirnya menunjukkan kepada saya seperti apa API saya bagi orang lain. Saya kemudian menindaklanjuti dengan logika tersisa yang perlu dicakup sebagai nama paket pengujian internal.package services
berisi sute uji integrasi, jadi untuk menguji APIfo paket sebagai kotak hitam kita harus menamainya dengan cara lainpackage services_integration_test
itu tidak akan memberi kita kesempatan untuk bekerja dengan struktur internal. Jadi paket untuk pengujian unit (mengakses internal) harus diberi namapackage services
. Begitu?Saya melihat tiga solusi yang mungkin. Yang pertama adalah menggunakan mode pendek untuk pengujian unit. Jadi, Anda akan menggunakan
go test -short
dengan unit test dan sama tetapi tanpa-short
tanda untuk menjalankan pengujian integrasi Anda juga. Pustaka standar menggunakan mode pendek untuk melewati pengujian yang berjalan lama, atau membuatnya berjalan lebih cepat dengan menyediakan data yang lebih sederhana.Yang kedua adalah menggunakan konvensi dan memanggil pengujian Anda,
TestUnitFoo
atauTestIntegrationFoo
lalu gunakan tanda-run
pengujian untuk menunjukkan pengujian mana yang akan dijalankan. Jadi, Anda akan menggunakannyago test -run 'Unit'
untuk pengujian unit dango test -run 'Integration'
untuk pengujian integrasi.Opsi ketiga adalah menggunakan variabel lingkungan, dan mendapatkannya dalam penyiapan pengujian Anda
os.Getenv
. Kemudian Anda akan menggunakan simplego test
untuk pengujian unit danFOO_TEST_INTEGRATION=true go test
untuk pengujian integrasi.Saya pribadi lebih suka
-short
solusinya karena lebih sederhana dan digunakan di perpustakaan standar, jadi sepertinya ini cara de facto untuk memisahkan / menyederhanakan pengujian yang berjalan lama. Tapi solusi-run
danos.Getenv
menawarkan lebih banyak fleksibilitas (lebih banyak kehati-hatian juga diperlukan, karena regexps terlibat dengan-run
).sumber
Tester-Go
) yang umum untuk IDE (Atom, Sublime, dll) memiliki opsi bawaan untuk dijalankan dengan-short
flag, bersama dengan-coverage
dan lainnya. oleh karena itu, saya menggunakan kombinasi dari kedua Integrasi dalam nama pengujian, bersama denganif testing.Short()
pemeriksaan dalam pengujian tersebut. itu memungkinkan saya untuk mendapatkan yang terbaik dari kedua dunia: dijalankan dengan-short
dalam IDE, dan secara eksplisit hanya menjalankan pengujian integrasi dengango test -run "Integration"
Saya mencoba mencari solusi untuk hal yang sama baru-baru ini. Ini adalah kriteria saya:
Solusi yang disebutkan di atas (bendera khusus, tag build khusus, variabel lingkungan) tidak benar-benar memenuhi semua kriteria di atas, jadi setelah sedikit menggali dan bermain, saya menemukan solusi ini:
Penerapannya mudah dan minimal. Meskipun memerlukan konvensi sederhana untuk pengujian, tetapi tidak terlalu rentan terhadap kesalahan. Perbaikan lebih lanjut dapat mengekspor kode ke fungsi pembantu.
Pemakaian
Jalankan pengujian integrasi hanya di semua paket dalam sebuah proyek:
Jalankan semua tes ( reguler dan integrasi):
Jalankan tes biasa saja :
Solusi ini bekerja dengan baik tanpa perkakas, tetapi Makefile atau beberapa alias dapat membuatnya lebih mudah untuk pengguna. Ini juga dapat dengan mudah diintegrasikan ke dalam IDE apa pun yang mendukung pengujian go.
Contoh lengkapnya dapat ditemukan di sini: https://github.com/sagikazarmark/modern-go-application
sumber