Terlepas dari kenyataan bahwa semua orang tahu bahwa penting dan perlu untuk menguji perangkat lunak Anda, dan banyak yang telah melakukannya secara otomatis untuk waktu yang lama, tidak ada resep tunggal di ruang terbuka Habr untuk menyiapkan banyak produk populer di ceruk ini sebagai (favorit kami) GitLab dan JUnit . Isi celah ini!

Pendahuluan
Pertama, saya akan menguraikan konteksnya:
- Karena semua aplikasi kami berfungsi di Kubernetes, kami akan mempertimbangkan untuk menjalankan tes dalam infrastruktur yang sesuai.
- Untuk perakitan dan penyebaran kami menggunakan werf (dalam arti komponen infrastruktur, ini juga secara otomatis berarti bahwa Helm terlibat).
- Saya tidak akan masuk ke detail langsung membuat tes: dalam kasus kami, klien menulis tes sendiri, dan kami hanya memastikan bahwa itu dijalankan (dan laporan terkait tersedia dalam permintaan penggabungan).
Seperti apa urutan tindakan secara keseluruhan?
- Perakitan aplikasi - kami akan menghilangkan deskripsi tahap ini.
- Menyebarkan aplikasi ke namespace cluster Kubernetes terpisah dan meluncurkan pengujian.
- Cari artefak dan parsing laporan JUnit oleh GitLab.
- Hapus namespace yang sebelumnya dibuat.
Sekarang - untuk implementasi!
Kustomisasi
Gitlab ci
Mari kita mulai dengan fragmen
.gitlab-ci.yaml
menjelaskan penyebaran aplikasi dan menjalankan tes. Daftar itu ternyata agak tebal, oleh karena itu dilengkapi dengan komentar:
variables:
Kubernetes
Sekarang di direktori
.helm/templates
, buat YAML dengan Pekerjaan -
tests-job.yaml
- untuk menjalankan tes dan sumber daya Kubernet yang dibutuhkan. Penjelasan lihat setelah daftar:
{{- if eq .Values.global.run_tests "yes" }} --- apiVersion: v1 kind: ConfigMap metadata: name: tests-script data: tests.sh: | echo "======================" echo "${APP_NAME} TESTS" echo "======================" cd /app npm run test:ci cp report.xml /app/test_results/${CI_COMMIT_REF_SLUG}/ echo "" echo "" echo "" chown -R 999:999 /app/test_results/${CI_COMMIT_REF_SLUG} --- apiVersion: batch/v1 kind: Job metadata: name: {{ .Chart.Name }}-test annotations: "helm.sh/hook": post-install,post-upgrade "helm.sh/hook-weight": "2" "werf/watch-logs": "true" spec: activeDeadlineSeconds: {{ .Values.global.ci_timeout }} backoffLimit: 1 template: metadata: name: {{ .Chart.Name }}-test spec: containers: - name: test command: ['bash', '-c', '/app/tests.sh'] {{ tuple "application" . | include "werf_container_image" | indent 8 }} env: - name: env value: {{ .Values.global.env }} - name: CI_COMMIT_REF_SLUG value: {{ .Values.global.commit_ref_slug }} - name: APP_NAME value: {{ .Chart.Name }} {{ tuple "application" . | include "werf_container_env" | indent 8 }} volumeMounts: - mountPath: /app/test_results/ name: data - mountPath: /app/tests.sh name: tests-script subPath: tests.sh tolerations: - key: dedicated operator: Exists - key: node-role.kubernetes.io/master operator: Exists restartPolicy: OnFailure volumes: - name: data persistentVolumeClaim: claimName: {{ .Chart.Name }}-pvc - name: tests-script configMap: name: tests-script --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: {{ .Chart.Name }}-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Mi storageClassName: {{ .Chart.Name }}-{{ .Values.global.commit_ref_slug }} volumeName: {{ .Values.global.commit_ref_slug }} --- apiVersion: v1 kind: PersistentVolume metadata: name: {{ .Values.global.commit_ref_slug }} spec: accessModes: - ReadWriteOnce capacity: storage: 10Mi local: path: /mnt/tests/ nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - kube-master persistentVolumeReclaimPolicy: Delete storageClassName: {{ .Chart.Name }}-{{ .Values.global.commit_ref_slug }} {{- end }}
Sumber daya apa yang dijelaskan dalam konfigurasi ini? Saat menggunakan, buat namespace unik untuk proyek (ini juga ditunjukkan dalam
.gitlab-ci.yaml
-
tests-${CI_COMMIT_REF_SLUG}
) dan gulung ke dalamnya:
- ConfigMap dengan skrip pengujian;
- Pekerjaan dengan deskripsi pod dan arahan
command
ditentukan, yang hanya menjalankan tes; - PV dan PVC , yang memungkinkan Anda untuk menyimpan data uji.
Perhatikan kondisi pengantar dengan
if
pada awal manifes - oleh karena itu, file YAML lain dari bagan Helm dengan aplikasi harus dibungkus dengan konstruksi
terbalik sehingga tidak digunakan selama pengujian. Itu adalah:
{{- if ne .Values.global.run_tests "yes" }} --- {{- end }}
Namun, jika tes
memerlukan beberapa infrastruktur (misalnya, Redis, RabbitMQ, Mongo, PostgreSQL ...) - YAML mereka dapat dimatikan. Sebarkan di lingkungan uji ... tentu saja, sesuaikan yang Anda suka.
Sentuhan terakhir
Karena perakitan dan penyebaran menggunakan werf sejauh ini
hanya berfungsi pada server build (dengan gitlab-runner), dan pod dengan tes dijalankan pada wizard, Anda harus membuat
/mnt/tests
pada wizard dan memberikannya kepada pelari,
misalnya, melalui NFS . Contoh terperinci dengan penjelasan dapat ditemukan dalam
dokumentasi K8s .
Hasilnya adalah:
user@kube-master:~$ cat /etc/exports | grep tests /mnt/tests IP_gitlab-builder/32(rw,nohide,insecure,no_subtree_check,sync,all_squash,anonuid=999,anongid=998) user@gitlab-runner:~$ cat /etc/fstab | grep tests IP_kube-master:/mnt/tests /mnt/tests nfs4 _netdev,auto 0 0
Tidak ada yang melarang membuat NFS-bola langsung di gitlab-runner, dan kemudian memasangnya di pod.
Catatan
Anda mungkin bertanya, mengapa mempersulit segalanya dengan penciptaan Ayub, jika Anda bisa menjalankan skrip uji langsung pada shell runner? Jawabannya cukup sepele ...
Beberapa tes memerlukan akses ke infrastruktur (MongoDB, RabbitMQ, PostgreSQL, dll.) Untuk memeriksa kebenaran bekerja dengan mereka. Kami membuat pengujian disatukan - dengan pendekatan ini, menjadi mudah untuk memasukkan entitas tambahan tersebut. Selain itu, kami mendapatkan pendekatan
standar dalam penyebaran (bahkan jika menggunakan NFS, pemasangan direktori tambahan).
Hasil
Apa yang akan kita lihat ketika kita menerapkan konfigurasi yang sudah disiapkan?
Permintaan penggabungan akan menampilkan statistik ringkasan tentang tes yang diluncurkan di saluran terakhir:

Anda dapat mengklik setiap kesalahan di sini untuk mendapatkan detail:
NB : Pembaca yang penuh perhatian akan melihat bahwa kami sedang menguji aplikasi NodeJS, dan dalam tangkapan layar - .NET ... Jangan kaget: hanya sebagai bagian dari persiapan artikel, tidak ada kesalahan dalam menguji aplikasi pertama, tetapi mereka ditemukan di yang lain.Kesimpulan
Ternyata, tidak ada yang rumit!
Pada prinsipnya, jika Anda sudah memiliki shell-builder dan itu bekerja, dan Anda tidak memerlukan Kubernetes, mengacaukan pengujian untuk itu akan menjadi tugas yang lebih sederhana daripada yang dijelaskan di sini. Dan dalam
dokumentasi GitLab CI Anda akan menemukan contoh untuk Ruby, Go, Gradle, Maven dan beberapa lainnya.
PS
Baca juga di blog kami: