Haruskah saya memasukkan tes dalam gambar Docker?

19

Ketika datang ke tes, saya bisa memikirkan dua opsi:

  1. Letakkan kedua tes dan aplikasi dalam satu gambar.
  2. Sertakan hanya kode aplikasi dalam gambar. Buat wadah uji khusus yang dibangun setelah gambar utama dan tambahkan beberapa lapisan ke dalamnya (kode uji, dependensi dll).

Dengan opsi pertama, saya dapat menguji wadah dan mengirimkannya persis seperti yang diuji. Kelemahan yang jelas adalah kode yang tidak perlu (dan berpotensi menguji data) akan dimasukkan dalam gambar.

Dengan opsi kedua, gambar yang dikirim tidak sama dengan gambar yang diuji.

Keduanya terlihat seperti strategi yang buruk. Apakah ada strategi ketiga yang lebih baik?

lk
sumber
1
Anda pada dasarnya menjawab sendiri. Keduanya adalah ide yang buruk. Anda akan mengirimkan proses runnable yang sudah diuji ke dalam wadah berukuran dan disesuaikan dengan kebutuhan. Anda tidak ingin dev-dependensi atau kode src. Dalam produksi itu dianggap sebagai risiko.
Laiv
1
Pengujian sebelum kontainerisasi berarti lingkungan tidak diuji, hanya kodenya. Anda hanya akan menguji sebagian dari apa yang Anda kirim, tidak semuanya.
lfk

Jawaban:

10

Untuk menjalankan tes waktu-bangun, cara yang lebih disukai adalah menggunakan build multi-tahap . Dockerfiles Multi-tahap memungkinkan Anda untuk memiliki panggung yang lebih besar dengan semua dependensi untuk membangun dan menguji, lalu menyalin artefak yang tepat yang Anda uji ke tahap lain untuk gambar runtime yang lebih kecil.

Anda juga ingin pengujian tingkat sistem dari beberapa wadah, menggunakan antarmuka eksternal alih-alih berjalan di dalam wadah. Karena tes-tes tersebut melibatkan koordinasi antar layanan, memerlukan dependensi berbeda seperti akses ke orkestrasi Anda, tidak selengkap tes build-time, dan seringkali ditulis dalam bahasa yang sangat berbeda, itu bukan masalah besar untuk menjalankannya dari Docker yang terpisah. wadah yang didedikasikan hanya untuk pengujian sistem.

Karl Bielefeldt
sumber
1
Jadi itu cukup banyak opsi 2 - Saya menjalankan tes di lingkungan / wadah yang sangat mirip dengan produksi, tetapi tidak persis sama. Apakah itu benar?
lfk
9

Ada cara ketiga, seperti kata Anda sendiri. Saya pikir Anda mencampuradukkan pengembangan, pengujian dan penyebaran. Saya mengusulkan agar seluruh SDLC dilihat secara keseluruhan, pertama, untuk memahami apa yang ingin Anda capai. Ini adalah topik besar, tetapi saya akan melakukan yang terbaik untuk meringkas.

TL; DR;

Singkatnya, Anda perlu memisahkan:

  • kode Anda, dari
  • konfigurasi aplikasi, dari
  • konfigurasi lingkungan sistem.

Masing-masing harus independen satu sama lain dan sesuai:

  • versi terkontrol
  • diuji
  • dikerahkan

Versi yang lebih panjang

Pertama, Anda memiliki aplikasi yang terdiri dari kode dan (set terpisah) konfigurasi. Ini perlu diuji, baik untuk fungsi build dan disengaja - ini disebut integrasi berkelanjutan (CI). Ada banyak penyedia layanan ini baik online dan lokal - misalnya CircleCI untuk penyedia cloud yang menautkan ke repositori Anda dan membangun dan menguji setiap kali Anda berkomitmen. Jika repositori Anda di tempat dan tidak dapat menggunakan penyedia cloud, sesuatu seperti Jenkinsakan menjadi setara. Jika aplikasi Anda cukup standar, mungkin ada gambar Docker yang ada yang dapat digunakan layanan CI. Jika tidak, Anda harus membuat satu, atau sekelompok, kode aplikasi dan konfigurasi Anda dapat digunakan. Dikonfigurasi dengan benar, Anda akan memiliki banyak statistik pada kualitas kode aplikasi Anda.

Selanjutnya, setelah Anda puas dengan fungsionalitas dan kebenaran aplikasi Anda, basis kode harus ditandai untuk rilis tertentu. Bangunan ini kemudian harus digunakan untuk lingkungan pengujian. Perhatikan bahwa kode akan sama dengan yang diuji dalam CI Anda (terbukti demikian, jika Anda telah melakukan ini dengan benar), tetapi konfigurasi Anda mungkin berbeda. Sekali lagi beberapa penyedia CI dapat menawarkan langkah ini sehingga Anda dapat menguji penyebaran aplikasi yang dikemas dan konfigurasi terpisah. Tahap ini biasanya akan mencakup pengujian fungsional pengguna (untuk fungsionalitas baru), serta pengujian otomatis (untuk fungsionalitas yang diketahui). Jika rilis melewati tahap ini, Anda memiliki kandidat rilis untuk pengujian integrasi. Anda dapat menjalankan tes otomatisasi dari wadah Docker lain,beberapa metrik yang menyatakan upaya pengujian adalah 1: 1 untuk upaya pengkodean (meskipun saya sendiri tidak yakin tentang ini).

Secara singkat, langkah selanjutnya adalah di mana Anda membangun lingkungan (sistem) Anda seolah-olah itu adalah produksi. Jika Anda menggunakan Docker dalam produksi, ini adalah tempat Anda akan memikirkan pengerasan keamanan, optimisasi jaringan dan server dll. Gambar Docker Anda mungkin didasarkan pada yang Anda gunakan dalam Pengembangan (idealnya demikian), tetapi mungkin ada perubahan untuk penskalaan dan keamanan , seperti yang saya katakan. Sekarang pengujian fungsional aplikasi harus lengkap, Anda lebih mementingkan keamanan dan kinerja. Sesuai dengan pengujian fungsional, pengujian Anda di sini dapat dikembangkan, disebarkan, dan dijalankan dari gambar Docker lainnya. Langkah ini dulunya mahal dan jarang dilakukan sehingga Anda memerlukan perangkat keras khusus di tempat yang mereproduksi produksi. Hari ini, ini benar-benar layak karena Anda dapat berdiri dan menghancurkan seluruh lingkungan dari hampir semua skala berdasarkan permintaan.

Akhirnya, Anda memiliki rilis yang harus siap produksi dengan hanya satu set kecil delta konfigurasi dari pengujian integrasi Anda (alamat IP, URI basis data, kata sandi, dll.) Basis kode Anda telah diuji setidaknya dalam tiga lingkungan yang berbeda pada saat ini. titik dan mayoritas konfigurasi sistem setidaknya sekali.

avastmick
sumber
Apakah itu berarti CI Anda tidak akan menguji Dockerfiles Anda sama sekali? Misalnya, jika Dockerfile Anda kehilangan dependensi, tes masih akan berlalu?
lfk
1
Tidak semuanya. Pertama-tama uji kodenya, lalu uji konfigurasi aplikasi, lalu uji sistem. Apa yang saya katakan adalah bahwa ini adalah kegiatan yang terpisah. Hal yang hebat tentang kemewahan adalah impian pembangunan di lingkungan yang sama dengan prod sangat dekat. Tetapi pengerasan akan membuat pengembangan terlalu sulit.
avastmick
0

Saya pikir Anda mencampur berbagai jenis tes. Pada dasarnya Anda perlu bertanya pada diri sendiri: Apa unit yang diuji di sini?

Skenario yang paling umum ketika Anda bekerja sebagai pengembang adalah menulis tes unit / integrasi untuk beberapa bagian kode yang sedang Anda kerjakan, di mana bagian kode tersebut adalah unit yang sedang diuji. Anda menjalankan tes tersebut secara lokal dan / atau dalam CI.

Ketika Anda telah membangun gambar buruh pelabuhan baru, itu menjadi unit baru yang dapat Anda uji. Jenis hal apa yang ingin Anda uji untuk gambar ini? Apa API yang disediakannya? Bagaimana Anda mengujinya?

Jika ini adalah aplikasi web, Anda dapat memulai sebuah wadah berdasarkan gambar dan melakukan beberapa permintaan HTTP dan memeriksa apakah responsnya sesuai dengan yang Anda harapkan. Masalahnya saya pikir Anda alami adalah bahwa Anda sangat terbiasa dengan kerangka uji yang digabungkan ke kode aplikasi. Itu bagus selama pengembangan, tetapi sekarang Anda ingin menguji gambar buruh pelabuhan dan Anda memerlukan jenis kerangka uji baru yang dapat melakukan itu dan tidak terikat dengan kode aplikasi.

Jadi saya pikir opsi ke-3 yang Anda cari adalah:

  • Jalankan tes unit / integrasi Anda sebelum membuat gambar buruh pelabuhan.
  • Buat gambar buruh pelabuhan yang berisi hanya aplikasi yang ingin Anda distribusikan.
  • Alih-alih menambahkan lapisan tambahan di atas gambar aplikasi itu, Anda mengujinya apa adanya dengan menjalankannya dengan beberapa parameter yang diberikan dan menegaskan hasil yang Anda harapkan.

Jadi langkah-langkah CI / CD adalah:

Atur lingkungan pengembangan -> Jalankan tes pada kode -> Bangun gambar akhir -> Jalankan tes pada gambar -> Sebarkan gambar.

Lars Nyström
sumber