Senadyan kasunyatan manawa kabeh wong ngerti yen nguji piranti lunak sampeyan penting lan perlu, lan akeh sing wis nindakake kanthi otomatis kanggo wektu sing suwe, ing jembar Habr ora ana resep siji kanggo nyetel kombinasi produk populer kasebut ing niche iki minangka (favorit kita) GitLab lan JUnit. Ayo padha isi longkangan iki!
pambuka
Pisanan, aku menehi sawetara konteks:
Amarga kabeh aplikasi kita mlaku ing Kubernetes, kita bakal nimbang kanggo nganakake tes ing infrastruktur sing cocog.
Kanggo perakitan lan penyebaran kita digunakake werf (ing babagan komponen infrastruktur, iki uga kanthi otomatis tegese Helm melu).
Aku ora bakal njlèntrèhaké rinci babagan nggawe tes sing nyata: ing kasus kita, klien nulis tes kasebut dhewe, lan kita mung njamin peluncuran kasebut (lan anané laporan sing cocog ing panyuwunan gabungan).
Kaya apa urutan umum tumindak?
Mbangun aplikasi - kita bakal ngilangi deskripsi tahap iki.
Nyebarake aplikasi menyang ruang jeneng sing kapisah saka kluster Kubernetes lan miwiti nyoba.
Nggoleki artefak lan parsing laporan JUnit karo GitLab.
Mbusak spasi jeneng sing wis digawe sadurunge.
Saiki - kanggo implementasine!
imbuhan
GitLab CI
Ayo dadi miwiti karo pecahan .gitlab-ci.yaml, kang njlèntrèhaké deploying aplikasi lan mbukak tes. Dhaptar kasebut katon akeh banget, mula ditambahi kanthi lengkap karo komentar:
variables:
# объявляем версию werf, которую собираемся использовать
WERF_VERSION: "1.0 beta"
.base_deploy: &base_deploy
script:
# создаем namespace в K8s, если его нет
- kubectl --context="${WERF_KUBE_CONTEXT}" get ns ${CI_ENVIRONMENT_SLUG} || kubectl create ns ${CI_ENVIRONMENT_SLUG}
# загружаем werf и деплоим — подробнее об этом см. в документации
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#deploy-stage)
- type multiwerf && source <(multiwerf use ${WERF_VERSION})
- werf version
- type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
- werf deploy --stages-storage :local
--namespace ${CI_ENVIRONMENT_SLUG}
--set "global.commit_ref_slug=${CI_COMMIT_REF_SLUG:-''}"
# передаем переменную `run_tests`
# она будет использоваться в рендере Helm-релиза
--set "global.run_tests=${RUN_TESTS:-no}"
--set "global.env=${CI_ENVIRONMENT_SLUG}"
# изменяем timeout (бывают долгие тесты) и передаем его в релиз
--set "global.ci_timeout=${CI_TIMEOUT:-900}"
--timeout ${CI_TIMEOUT:-900}
dependencies:
- Build
.test-base: &test-base
extends: .base_deploy
before_script:
# создаем директорию для будущего отчета, исходя из $CI_COMMIT_REF_SLUG
- mkdir /mnt/tests/${CI_COMMIT_REF_SLUG} || true
# вынужденный костыль, т.к. GitLab хочет получить артефакты в своем build-dir’е
- mkdir ./tests || true
- ln -s /mnt/tests/${CI_COMMIT_REF_SLUG} ./tests/${CI_COMMIT_REF_SLUG}
after_script:
# после окончания тестов удаляем релиз вместе с Job’ом
# (и, возможно, его инфраструктурой)
- type multiwerf && source <(multiwerf use ${WERF_VERSION})
- werf version
- type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
- werf dismiss --namespace ${CI_ENVIRONMENT_SLUG} --with-namespace
# мы разрешаем падения, но вы можете сделать иначе
allow_failure: true
variables:
RUN_TESTS: 'yes'
# задаем контекст в werf
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#infrastructure)
WERF_KUBE_CONTEXT: 'admin@stage-cluster'
tags:
# используем раннер с тегом `werf-runner`
- werf-runner
artifacts:
# требуется собрать артефакт для того, чтобы его можно было увидеть
# в пайплайне и скачать — например, для более вдумчивого изучения
paths:
- ./tests/${CI_COMMIT_REF_SLUG}/*
# артефакты старше недели будут удалены
expire_in: 7 day
# важно: эти строки отвечают за парсинг отчета GitLab’ом
reports:
junit: ./tests/${CI_COMMIT_REF_SLUG}/report.xml
# для упрощения здесь показаны всего две стадии
# в реальности же у вас их будет больше — как минимум из-за деплоя
stages:
- build
- tests
build:
stage: build
script:
# сборка — снова по документации по werf
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#build-stage)
- type multiwerf && source <(multiwerf use ${WERF_VERSION})
- werf version
- type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
- werf build-and-publish --stages-storage :local
tags:
- werf-runner
except:
- schedules
run tests:
<<: *test-base
environment:
# "сама соль" именования namespace’а
# (https://docs.gitlab.com/ce/ci/variables/predefined_variables.html)
name: tests-${CI_COMMIT_REF_SLUG}
stage: tests
except:
- schedules
Kubernetes
Saiki ing direktori .helm/templates ayo nggawe YAML karo Ayub - tests-job.yaml - kanggo mbukak tes lan sumber daya Kubernetes sing dibutuhake. Deleng panjelasan sawise dhaptar:
Apa jenis sumber daya diterangake ing konfigurasi iki? Nalika nyebarake, kita nggawe ruang jeneng unik kanggo proyek kasebut (iki dituduhake ing .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) lan gulung metu:
ConfigMap karo script test;
Job kanthi katrangan saka pod lan arahan sing ditemtokake command, sing mung mbukak tes;
PV lan PVC, sing ngidini sampeyan nyimpen data tes.
Pay manungsa waé menyang kondisi pambuka karo if ing wiwitan manifest - miturut, file YAML liyane saka bagan Helm karo aplikasi kudu dibungkus mbalikke desain supaya padha ora njaluk disebarake sak testing. Iku:
{{- if ne .Values.global.run_tests "yes" }}
---
я другой ямлик
{{- end }}
Nanging, yen tes mbutuhake sawetara infrastruktur (contone, Redis, RabbitMQ, Mongo, PostgreSQL ...) - YAMLs bisa ora mateni. Nyebarake menyang lingkungan tes uga ... nyetel kaya sing dikarepake, mesthine.
tutul pungkasan
Amarga Déwan lan panyebaran nggunakake karya werf kanggo saiki mung ing server mbangun (karo gitlab-runner), lan pod karo tes diluncurake ing master, sampeyan kudu nggawe direktori /mnt/tests ing master lan menehi menyang runner, contone,, liwat NFS. Conto rinci kanthi panjelasan bisa ditemokake ing Dokumentasi K8.
Ora ana sing nglarang nggawe saham NFS langsung ing gitlab-runner, lan banjur dipasang ing pods.
komentar
Sampeyan bisa uga takon kenapa nggawe rumit kabeh kanthi nggawe Proyek yen sampeyan mung bisa mbukak skrip kanthi tes langsung ing pelari cangkang? Jawabane cukup sepele...
Sawetara tes mbutuhake akses menyang infrastruktur (MongoDB, RabbitMQ, PostgreSQL, lsp) kanggo verifikasi manawa bisa digunakake kanthi bener. Kita nggawe tes manunggal - kanthi pendekatan iki, dadi gampang kanggo nyakup entitas tambahan kasebut. Saliyane iki, kita entuk standar pendekatan penyebaran (sanajan nggunakake NFS, tambahan soyo tambah saka direktori).
asil
Apa sing bakal kita deleng nalika ngetrapake konfigurasi sing disiapake?
Panyuwunan gabungan bakal nuduhake statistik ringkesan kanggo tes sing ditindakake ing pipa paling anyar:
Saben kesalahan bisa diklik ing kene kanggo rincian:
NB: Pembaca sing ati-ati bakal sok dong mirsani yen kita lagi nyoba aplikasi NodeJS, lan ing gambar - .NET... Aja kaget: mung nalika nyiapake artikel, ora ana kesalahan nalika nyoba aplikasi pisanan, nanging padha ditemokake ing liyane.
kesimpulan
Nalika sampeyan bisa ndeleng, ora ana sing rumit!
Ing asas, yen sampeyan wis duwe cangkang kolektor lan bisa, nanging sampeyan ora perlu Kubernetes, masang testing kanggo iku bakal dadi tugas malah prasaja saka diterangake kene. Lan ing Dokumentasi GitLab CI sampeyan bakal nemokake conto kanggo Ruby, Go, Gradle, Maven lan sawetara liyane.