Kuigi kĂ”ik teavad, et oma tarkvara testimine on oluline, ja paljud teevad seda juba automaatselt, ei leidunud Habras ĂŒhtegi retsepti, mis kĂ€sitleks selliste populaarsete toodete nagu (meie lemmik) GitLab ja JUnit seostamist. TĂ€idame selle tĂŒhimiku!

Sissejuhatus
Alustuseks mÀÀratleksin konteksti:
- Kuna kÔik meie rakendused töötavad Kuberneteses, arutame testide kÀivitamist vastavas infrastruktuuris.
- Kogumise ja juurutamise jaoks kasutame (infrastruktuuri komponente silmas pidades tÀhendab see ka automaatselt, et on kasutusel Helm).
- Katsesideme loomise detailidesse sĂŒvenema ei hakka: meie puhul kirjutab kliendi testid ise ning meie tagame vaid nende kĂ€ivitamise (ja vastava aruande olemasolu merge request'is).
Kuidas nĂ€eb vĂ€lja ĂŒldine tegevuste jĂ€rjestus?
- Rakenduse kogumine â selle etapi kirjeldamise jĂ€tame kĂ”rvale.
- Rakenduse juurutamine eraldi Kubernetes klastrinimesse ja testimise kÀivitamine.
- Artefaktide otsimine ja JUnit aruande parsimine GitLabi poolt.
- Varasemalt loodud nimede asendamine eemaldamine.
NĂŒĂŒd â rakenduse juurde!
Seadistamine
GitLab CI
Alustame lĂ”igust .gitlab-ci.yaml, mis sisaldab rakenduse juurutamise ja testide kĂ€ivitamise kirjeldust. Loend osutus ĂŒsna mahukaks, seega on see hoolikalt tĂ€iendatud kommentaaridega:
muutujad:
# kuulutame vÀlja werf versiooni, mida plaanime kasutada
WERF_VERSION: "1.0 beta"
.base_deploy: &base_deploy
skript:
# loome K8s-i nimelruumi, kui seda pole
- kubectl --context="${WERF_KUBE_CONTEXT}" get ns ${CI_ENVIRONMENT_SLUG} || kubectl create ns ${CI_ENVIRONMENT_SLUG}
# laeme werfi ja teeme vĂ€ljalaskmise â lĂ€hemalt vt dokumentatsioonis
# (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:-''}"
# edastame muutuja `run_tests`
# seda kasutatakse Helm-vÀljalaske renderdamisel
--set "global.run_tests=${RUN_TESTS:-no}"
--set "global.env=${CI_ENVIRONMENT_SLUG}"
# muudame timeouti (kasutada vÔib pikki teste) ja edastame selle vÀljalaskesse
--set "global.ci_timeout=${CI_TIMEOUT:-900}"
--timeout ${CI_TIMEOUT:-900}
sÔltuvused:
- Ehitus
.test-base: &test-base
laiendab: .base_deploy
before_script:
# loome kausta tulevase aruande jaoks, lÀhtudes $CI_COMMIT_REF_SLUG-st
- mkdir /mnt/tests/${CI_COMMIT_REF_SLUG} || true
# sunnitud lahendus, kuna GitLab soovib, et saaks arhiivid oma build-dirâisse
- mkdir ./tests || true
- ln -s /mnt/tests/${CI_COMMIT_REF_SLUG} ./tests/${CI_COMMIT_REF_SLUG}
after_script:
# pĂ€rast testide lĂ”ppemist eemaldame vĂ€ljalaske koos Jobâiga
# (ja vÔib-olla ka selle infrastruktuuriga)
- 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
# lubame vead, kuid vÔite teha teisiti
allow_failure: true
muutujad:
RUN_TESTS: 'jah'
# mÀÀrame konteksti werf-is
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#infrastructure)
WERF_KUBE_CONTEXT: 'admin@stage-cluster'
sildid:
# kasutame jooksjat sildiga `werf-runner`
- werf-runner
artefaktid:
# oluline on koguda artefakt, et saaks seda nÀha
# protsessis ja alla laadida â nĂ€iteks hoolikalt uurimiseks
teed:
- ./tests/${CI_COMMIT_REF_SLUG}/*
# nÀdala vanused artefaktid eemaldatakse
expire_in: 7 pÀeva
# oluline: need read vastutavad GitLab-i aruande parsimise eest
aruanded:
junit: ./tests/${CI_COMMIT_REF_SLUG}/report.xml
# lihtsustamiseks on siin nÀidatud vaid kaks etappi
# tegelikult on neid rohkem â vĂ€hemalt vĂ€ljalaskmise tĂ”ttu
etapid:
- ehitus
- testid
ehitus:
etapp: ehitus
skript:
# kokkupanek â jĂ€lle werfi dokumentatsiooni jĂ€rgi
# (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
sildid:
- werf-runner
vÀlja arvatud:
- ajakavad
testide kÀitamine:
<<: *test-base
keskkond:
# "nime" nimete ruumi nimed
# (https://docs.gitlab.com/ce/ci/variables/predefined_variables.html)
nimi: tests-${CI_COMMIT_REF_SLUG}
etapp: testid
vÀlja arvatud:
- ajakavadKubernetes
NĂŒĂŒd kataloogis .helm/templates loome YAML koos Job'iga â tests-job.yaml â testide kĂ€ivitamiseks ja vajalike Kubernetes'i ressurssidega. TĂ€iendavad selgitused on loendi pĂ€rast:
{{- if eq .Values.global.run_tests "yes" }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: tests-script
data:
tests.sh: |
echo "======================"
echo "${APP_NAME} TESTID"
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 }} Millised ressursid on selle konfiguratsiooni all kirjeldatud? Rakenduse juurutamisel loome projekti jaoks ainulaadse nimiruumi (see on nĂ€idatud ka .gitlab-ci.yaml â tests-${CI_COMMIT_REF_SLUG}) ja siia paigaldame:
- ConfigMap testi skripti;
- Töö pod'i kirjelduse ja mÀÀratud kÀsu
command, mis kÀivitab testid; - PV ja PVC, mis vÔimaldavad testide andmete salvestamist.
Pange tĂ€hele sissejuhatav tingimus if maniifesti alguses â vastavalt tuleb teised Helm-chart YAML-failid rakenduse kohta ĂŒmbritseda tagurpidi struktuuriga, et neid ei juurutataks testimise ajal. See tĂ€hendab:
{{- if ne .Values.global.run_tests "yes" }}
---
teine yaml fail
{{- end }}Siiski, kui testid nĂ”uavad teatud infrastruktuuri (nĂ€iteks Redis, RabbitMQ, Mongo, PostgreSQLâŠ) â nende YAML-id saab ei vĂ€lja lĂŒlitada. Juurutage need testkeskkonnas⊠muidugi, kohandades vastavalt oma soovidele.
Viimane puudutus
Kuna build ja juurutamine werfi abil toimib seni ainult build-serveris (gitlab-runneriga), ja testa pod kÀivitatakse meistris, tuleb luua kataloog /mnt/tests meistris ja anda see runnerile, nÀiteks NFS. NÀidis koos selgitustega on saadaval .
Tulemuseks saab olema:
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 0Keegi ei keela NFS-share tegemist otse gitlab-runner'is, mille jÀrel saab selle pod'idesse monteerida.
MĂ€rkus
VĂ”ib-olla kĂŒsite, miks ĂŒldse seda kĂ”ike keeruliseks ajada Job'i loomisega, kui saab lihtsalt kĂ€ivitada skripti testidega otse shell-runner'is? Vastus on piisavalt triviaalneâŠ
MĂ”ned testid nĂ”uavad infrastruktuuri (MongoDB, RabbitMQ, PostgreSQL jne) poole pöördumist nende Ă”ige toimimise kontrollimiseks. Me teeme testimise ĂŒhtseks â selle lĂ€henemisega on selliste lisade kaasamine lihtne. Lisaks saame tava lĂ€henemise juurutamisel (isegi NFS-i kasutamise ja kataloogide tĂ€iendava monteerimisega).
Tulemus
Mida me nÀeme, kui rakendame ettevalmistatud konfiguratsiooni?
Merge request'is kuvatakse kokkuvÔtlik statistika testide kohta, mida kÀidi lÀbi tema viimasel pipeline'il:

Iga vea puhul saab siia klĂ”psata, et saada ĂŒksikasju:

NBEttevaatlik lugeja mĂ€rkab, et testime NodeJS-rakendust, kuid ekraanipiltidel on .NET... Ărge imestage: lihtsalt artikli ettevalmistamise kĂ€igus ei leidnud me ĂŒhtegi viga esimeses rakenduses, kuid leidisime need teises.
KokkuvÔte
Nagu nÀha, pole midagi keerulist!
PĂ”himĂ”tteliselt, kui teil on juba shell-koguja ja see töötab ning Kubernetes pole vajalik â testimise ĂŒhendamine sellega on veelgi lihtsam ĂŒlesanne kui siin kirjeldatud. Ja leiate nĂ€iteid Ruby, Go, Gradle, Maven ja mĂ”nede teiste jaoks.
P.S.
Lugege ka meie blogist:
- «»;
- «»;
- «».
Allikas: habr.com
