Minkejja l-fatt li kulħadd jaf perfettament li l-ittestjar tas-softwer tiegħek huwa importanti u meħtieġ, u ħafna ilhom jagħmlu dan b’mod awtomatiku għal żmien twil, fil-kobor ta’ Habr ma kienx hemm riċetta waħda biex titwaqqaf taħlita ta’ prodotti popolari bħal dawn f’ din in-niċċa bħala (favoriti tagħna) GitLab u JUnit . Ejja nimlew dan il-vojt!
Introduttorja
L-ewwel, ħalluni nagħti xi kuntest:
Peress li l-applikazzjonijiet kollha tagħna jaħdmu fuq Kubernetes, se nikkunsidraw li nwettqu testijiet fuq l-infrastruttura xierqa.
Għall-assemblaġġ u l-iskjerament nużaw werf (f'termini ta' komponenti infrastrutturali, dan ifisser ukoll awtomatikament li Helm huwa involut).
Mhux se nidħol fid-dettalji tal-ħolqien attwali tat-testijiet: fil-każ tagħna, il-klijent jikteb it-testijiet huwa stess, u aħna niżguraw biss it-tnedija tagħhom (u l-preżenza ta 'rapport korrispondenti fit-talba għall-għaqda).
Kif se tkun is-sekwenza ġenerali ta' azzjonijiet?
Nibnu l-applikazzjoni - aħna se nħallu barra d-deskrizzjoni ta 'dan l-istadju.
Uża l-applikazzjoni fi spazju tal-isem separat tal-cluster Kubernetes u ibda l-ittestjar.
Tiftix għal artifacts u parsing tar-rapporti JUnit ma 'GitLab.
Tħassir ta' namespace maħluq qabel.
Issa - għall-implimentazzjoni!
aġġustament
GitLab CI
Nibdew bi framment .gitlab-ci.yaml, li jiddeskrivi l-iskjerament tal-applikazzjoni u t-tmexxija tat-testijiet. L-elenkar irriżulta li kien pjuttost voluminuż, għalhekk ġie supplimentat bir-reqqa b'kummenti:
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
Issa fid-direttorju .helm/templates ejja noħolqu YAML b'Job - tests-job.yaml — biex imexxi testijiet u r-riżorsi Kubernetes li jeħtieġ. Ara spjegazzjonijiet wara l-elenkar:
X'tip ta' riżorsi deskritt f'din il-konfigurazzjoni? Waqt l-iskjerament, noħolqu spazju tal-isem uniku għall-proġett (dan huwa indikat fi .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) u roll out:
ConfigMap b'kitba tat-test;
Job b'deskrizzjoni tal-pod u d-direttiva speċifikata command, li jmexxi biss it-testijiet;
PV u PVC, li jippermettulek taħżen data tat-test.
Oqgħod attent għall-kundizzjoni tal-bidu bil if fil-bidu tal-manifest - għaldaqstant, fajls YAML oħra tat-tabella Helm mal-applikazzjoni għandhom ikunu mgeżwra f' bil-maqlub disinn sabiex ma jiġux skjerati waqt l-ittestjar. Jiġifieri:
{{- if ne .Values.global.run_tests "yes" }}
---
я другой ямлик
{{- end }}
Madankollu, jekk it-testijiet jeħtieġu xi infrastruttura (pereżempju, Redis, RabbitMQ, Mongo, PostgreSQL...) - il-YAMLs tagħhom jistgħu jkunu ebda itfi. Tiskjerahom f'ambjent tat-test ukoll... aġġustahom kif jidhirlek xieraq, ovvjament.
Touch finali
Għax assemblaġġ u skjerament bl-użu ta 'xogħlijiet werf għalissa biss fuq is-server tal-bini (bil-gitlab-runner), u l-pod bit-testijiet huwa mniedi fuq il-kaptan, ser ikollok bżonn toħloq direttorju /mnt/tests fuq il-kaptan u agħtiha lill-runner, per eżempju, permezz NFS. Eżempju dettaljat bi spjegazzjonijiet jista’ jinstab fi Dokumentazzjoni K8s.
Ħadd ma jipprojbixxi li jagħmel sehem NFS direttament fuq gitlab-runner, u mbagħad iwaħħalha fil-miżwed.
Innota
Inti tista 'tistaqsi għaliex tikkomplika kollox billi toħloq Impjiegi jekk inti tista' sempliċiment tmexxi script b'testijiet direttament fuq il-shell runner? It-tweġiba hija pjuttost trivjali...
Xi testijiet jeħtieġu aċċess għall-infrastruttura (MongoDB, RabbitMQ, PostgreSQL, eċċ.) biex jivverifikaw li jaħdmu b'mod korrett. Aħna nagħmlu l-ittestjar unifikat - b'dan l-approċċ, isir faċli li jiġu inklużi entitajiet addizzjonali bħal dawn. B'żieda ma 'dan, aħna tikseb standard approċċ ta 'skjerament (anke jekk tuża NFS, immuntar addizzjonali ta' direttorji).
Riżultat
X'se naraw meta napplikaw il-konfigurazzjoni ppreparata?
It-talba għall-għaqda se turi statistika fil-qosor għat-testijiet imwettqa fl-aħħar pipeline tagħha:
Kull żball jista’ jiġi kklikkjat hawn għad-dettalji:
NB: Il-qarrej attent jinduna li qed nittestjaw applikazzjoni NodeJS, u fil-screenshots - .NET... Tiskantax: huwa biss li waqt il-preparazzjoni tal-artiklu, ma nstabu l-ebda żbalji fl-ittestjar tal-ewwel applikazzjoni, iżda dawn instabu f’ieħor.
Konklużjoni
Kif tistgħu taraw, xejn ikkumplikat!
Fil-prinċipju, jekk diġà għandek kollettur tal-qoxra u taħdem, iżda m'għandekx bżonn Kubernetes, it-twaħħil tal-ittestjar miegħu se jkun kompitu saħansitra aktar sempliċi minn dak deskritt hawn. U fi Dokumentazzjoni GitLab CI issib eżempji għal Ruby, Go, Gradle, Maven u xi wħud oħrajn.