Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

afrim IaC (Infrastruktura si kod) përbëhet jo vetëm nga kodi që ruhet në depo, por edhe nga njerëzit dhe proceset që e rrethojnë këtë kod. A është e mundur të ripërdoren qasjet nga zhvillimi i softuerit deri te menaxhimi dhe përshkrimi i infrastrukturës? Do të ishte një ide e mirë ta mbani në mend këtë ide ndërsa lexoni artikullin.

versioni anglisht

Ky është një transkript i imja shfaqje mbi DevopsConf 2019-05-28.

Sllajde dhe video

Infrastruktura si histori bash

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Supozoni se ju vini në një projekt të ri dhe ata ju thonë: "Ne kemi Infrastruktura si Kod". Në realitet rezulton Infrastruktura si histori bash ose për shembull Dokumentacioni si histori bash. Kjo është një situatë shumë reale, për shembull, një rast i ngjashëm u përshkrua nga Denis Lysenko në një fjalim Si të zëvendësoni të gjithë infrastrukturën dhe të filloni të flini të qetë, ai tregoi se si ata patën një infrastrukturë koherente për projektin nga historia e bashit.

Me pak dëshirë mund ta themi këtë Infrastruktura si histori bash ky është si kodi:

  1. riprodhueshmëria: Mund të merrni historinë e bash-it, të ekzekutoni komandat prej andej dhe, meqë ra fjala, mund të merrni një konfigurim funksional si rezultat.
  2. versionimi: ju e dini se kush hyri dhe çfarë bëri, përsëri, nuk është fakt që kjo do t'ju çojë në një konfigurim pune në dalje.
  3. histori: historia se kush bëri çfarë. vetëm se nuk do të mund ta përdorni nëse humbni serverin.

Çfarë duhet të bëni?

Infrastruktura si Kod

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Edhe një rast kaq i çuditshëm si Infrastruktura si histori bash mund ta tërhiqni nga veshët Infrastruktura si Kod, por kur duam të bëjmë diçka më të komplikuar se serveri i mirë i vjetër LAMP, do të arrijmë në përfundimin se ky kod duhet disi të modifikohet, ndryshohet, përmirësohet. Më tej do të donim të konsideronim paralelet ndërmjet Infrastruktura si Kod dhe zhvillimin e softuerit.

THATA

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Në një projekt të zhvillimit të sistemit të ruajtjes, kishte një nëndetyrë konfiguroni në mënyrë periodike SDS: ne po nxjerrim një version të ri - ai duhet të dalë për testime të mëtejshme. Detyra është jashtëzakonisht e thjeshtë:

  • hyni këtu nëpërmjet ssh dhe ekzekutoni komandën.
  • kopjoni skedarin atje.
  • korrigjoni konfigurimin këtu.
  • filloni shërbimin atje
  • ...
  • FITIMI!

Për logjikën e përshkruar, bash është më se i mjaftueshëm, veçanërisht në fazat e hershme të projektit, kur ai sapo po fillon. Kjo nuk eshte keq qe perdor bash, por me kalimin e kohës ka kërkesa për të vendosur diçka të ngjashme, por paksa të ndryshme. Gjëja e parë që ju vjen në mendje është copy-paste. Dhe tani ne kemi tashmë dy skenarë shumë të ngjashëm që bëjnë pothuajse të njëjtën gjë. Me kalimin e kohës, numri i skripteve u rrit, dhe ne u përballëm me faktin se ekziston një logjikë e caktuar biznesi për vendosjen e një instalimi që duhet të sinkronizohet midis skripteve të ndryshme, kjo është mjaft e ndërlikuar.

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Rezulton se ekziston një praktikë e tillë si DRY (Mos Përsëritni Veten). Ideja është të ripërdorni kodin ekzistues. Duket e thjeshtë, por ne nuk arritëm menjëherë te kjo. Në rastin tonë, ishte një ide banale: ndarja e konfigurimeve nga skriptet. ato. logjika e biznesit se si instalimi vendoset veçmas, konfigurohet veçmas.

SOLID për CFM

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Me kalimin e kohës projekti u rrit dhe vazhdim i natyrshëm ishte shfaqja e Ansible. Arsyeja kryesore për paraqitjen e tij është se ka ekspertizë në ekip dhe se bash nuk është krijuar për logjikë komplekse. Ansible gjithashtu filloi të përmbajë logjikë komplekse. Për të parandaluar që logjika komplekse të kthehet në kaos, ekzistojnë parime për organizimin e kodit në zhvillimin e softuerit I ngurtë Gjithashtu, për shembull, Grigory Petrov në raportin e tij "Pse i duhet një specialisti i IT një markë personale" shtroi pyetjen se një person është krijuar në atë mënyrë që të jetë më e lehtë për të të operojë me disa subjekte shoqërore, në zhvillimin e softuerit këto janë objekte. Nëse i kombinojmë këto dy ide dhe vazhdojmë t'i zhvillojmë, do të vërejmë se mund t'i përdorim edhe ne I ngurtë për ta bërë më të lehtë ruajtjen dhe modifikimin e kësaj logjike në të ardhmen.

Parimi i Përgjegjësisë së Vetëm

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Çdo klasë kryen vetëm një detyrë.

Nuk ka nevojë të përzieni kodin dhe të bëni monstra monolitike spageti hyjnore. Infrastruktura duhet të përbëhet nga tulla të thjeshta. Rezulton se nëse e ndani librin e lojërave Ansible në pjesë të vogla, lexoni rolet e Ansible, atëherë ato janë më të lehta për t'u ruajtur.

Parimi i hapur i mbyllur

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Parimi i hapur/mbyllur.

  • Open to extension: do të thotë që sjellja e një entiteti mund të zgjerohet duke krijuar lloje të reja entiteti.
  • I mbyllur për ndryshim: Si rezultat i zgjerimit të sjelljes së një njësie ekonomike, nuk duhet të bëhen ndryshime në kodin që përdor ato entitete.

Fillimisht, ne vendosëm infrastrukturën e testimit në makinat virtuale, por për faktin se logjika e biznesit të vendosjes ishte e ndarë nga zbatimi, shtuam pa problem roll out në baremetall.

Parimi i Zëvendësimit të Liskov

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Parimi i zëvendësimit të Barbara Liskov. objektet në një program duhet të zëvendësohen me instancat e nënllojeve të tyre pa ndryshuar ekzekutimin e saktë të programit

Nëse e shikoni më gjerësisht, nuk është veçori e ndonjë projekti të veçantë që mund të aplikohet atje I ngurtë, në përgjithësi bëhet fjalë për CFM, për shembull, në një projekt tjetër është e nevojshme të vendoset një aplikacion Java në kuti mbi Java të ndryshme, serverë aplikacioni, baza të të dhënave, OS, etj. Duke përdorur këtë shembull, unë do të shqyrtoj parime të mëtejshme I ngurtë

Në rastin tonë, ka një marrëveshje brenda ekipit të infrastrukturës që nëse kemi instaluar rolin imbjava ose oraclejava, atëherë kemi një ekzekutues binar java. Kjo është e nevojshme sepse Rolet në rrjedhën e sipërme varen nga kjo sjellje; ata presin java. Në të njëjtën kohë, kjo na lejon të zëvendësojmë një implementim/version java me një tjetër pa ndryshuar logjikën e vendosjes së aplikacionit.

Problemi këtu qëndron në faktin se kjo është e pamundur të zbatohet në Ansible, si rezultat i së cilës shfaqen disa marrëveshje brenda ekipit.

Parimi i ndarjes së ndërfaqes

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Parimi i ndarjes së ndërfaqes: “Shumë ndërfaqe specifike të klientit janë më të mira se një ndërfaqe për qëllime të përgjithshme.

Fillimisht, ne u përpoqëm të vendosnim të gjithë ndryshueshmërinë e vendosjes së aplikacionit në një libër lojërash Ansible, por ishte e vështirë për t'u mbështetur, dhe qasja kur kemi një ndërfaqe të jashtme të specifikuar (klienti pret portin 443), atëherë një infrastrukturë mund të mblidhet nga individi tulla për një zbatim specifik.

Parimi i përmbysjes së varësisë

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Parimi i përmbysjes së varësisë. Modulet në nivele më të larta nuk duhet të varen nga modulet në nivele më të ulëta. Të dy llojet e moduleve duhet të varen nga abstraksionet. Abstraksionet nuk duhet të varen nga detajet. Detajet duhet të varen nga abstraksionet.

Këtu shembulli do të bazohet në një antipattern.

  1. Një nga klientët kishte një re private.
  2. Ne porositëm makina virtuale brenda cloud.
  3. Por për shkak të natyrës së resë kompjuterike, vendosja e aplikacionit ishte e lidhur me cilin hipervizor ishte në VM.

ato. Logjika e vendosjes së aplikacionit të nivelit të lartë rrodhi me varësi në nivelet më të ulëta të hipervizorit, dhe kjo nënkuptonte probleme gjatë ripërdorimit të kësaj logjike. Mos e bëni në këtë mënyrë.

bashkëveprim

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Infrastruktura si kod nuk ka të bëjë vetëm me kodin, por edhe me marrëdhëniet midis kodit dhe njerëzve, me ndërveprimet midis zhvilluesve të infrastrukturës.

Faktori i autobusit

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Le të supozojmë se ju keni Vasya në projektin tuaj. Vasya di gjithçka për infrastrukturën tuaj, çfarë do të ndodhë nëse Vasya zhduket papritmas? Kjo është një situatë shumë reale, sepse ai mund të goditet nga një autobus. Ndonjëherë ndodh. Nëse kjo ndodh dhe njohuritë për kodin, strukturën e tij, mënyrën se si funksionon, paraqitjet dhe fjalëkalimet nuk shpërndahen në ekip, atëherë mund të hasni një sërë situatash të pakëndshme. Për të minimizuar këto rreziqe dhe për të shpërndarë njohuritë brenda ekipit, mund të përdorni qasje të ndryshme

Zhvillimi i çiftit

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Nuk është si si shaka, që administratorët pinin birrë, ndryshuan fjalëkalimet dhe një analog të programimit në çift. ato. dy inxhinierë ulen në një kompjuter, një tastierë dhe fillojnë të konfigurojnë infrastrukturën tuaj së bashku: vendosjen e një serveri, shkrimin e një roli Ansible, etj. Tingëllon bukur, por nuk funksionoi për ne. Por raste të veçanta të kësaj praktike funksionuan. Vjen një punonjës i ri, mentori i tij merr përsipër një detyrë reale së bashku me të, punon dhe transferon njohuritë.

Një rast tjetër i veçantë është një telefonatë incidenti. Gjatë një problemi, mblidhet një grup i atyre që janë në detyrë dhe të përfshirëve, caktohet një drejtues, i cili ndan ekranin e tij dhe shpreh trenin e mendimit. Pjesëmarrësit e tjerë ndjekin mendimet e liderit, spiunojnë truket nga tastiera, kontrollojnë që të mos kenë humbur asnjë rresht në regjistër dhe mësojnë gjëra të reja rreth sistemit. Kjo qasje funksionoi më shpesh sesa jo.

Rishikimi i kodit

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Subjektivisht, ishte më efektive shpërndarja e njohurive rreth infrastrukturës dhe se si funksionon duke përdorur rishikimin e kodit:

  • Infrastruktura përshkruhet me kod në depo.
  • Ndryshimet ndodhin në një degë të veçantë.
  • Gjatë një kërkese për bashkim, mund të shihni deltën e ndryshimeve në infrastrukturë.

Pika kryesore këtu ishte se recensentët u përzgjodhën një nga një, sipas një plani, d.m.th. me një farë probabiliteti do të ngjiteni në një pjesë të re të infrastrukturës.

Stili i kodit

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Me kalimin e kohës, grindjet filluan të shfaqen gjatë rishikimeve, sepse... recensentët kishin stilin e tyre dhe rotacioni i recensuesve i grumbulloi me stile të ndryshme: 2 hapësira ose 4, camelCase ose snake_case. Kjo nuk ishte e mundur të zbatohej menjëherë.

  • Ideja e parë ishte rekomandimi i përdorimit të literit, në fund të fundit, të gjithë janë inxhinierë, të gjithë janë të zgjuar. Por redaktorë të ndryshëm, OS, nuk janë të përshtatshëm
  • Ky evoluoi në një bot që shkroi për çdo angazhim problematik dhe bashkoi daljen e linterit. Por në shumicën e rasteve kishte gjëra më të rëndësishme për të bërë dhe kodi mbeti i parregulluar.

Gjelbër Build Master

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Koha kalon dhe ne kemi arritur në përfundimin se kryerjet që nuk kalojnë teste të caktuara nuk mund të lejohen në master. Voila! Ne shpikëm Green Build Master, i cili është praktikuar në zhvillimin e softuerit për një kohë të gjatë:

  • Zhvillimi është duke u zhvilluar në një degë të veçantë.
  • Testet po zhvillohen në këtë temë.
  • Nëse testet dështojnë, kodi nuk do të hyjë në master.

Marrja e këtij vendimi ishte shumë e dhimbshme, sepse... shkaktoi shumë polemika, por ia vlente, sepse... Shqyrtimet filluan të merrnin kërkesa për bashkime pa dallime në stil, dhe me kalimin e kohës numri i zonave problematike filloi të zvogëlohej.

Testimi IaC

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Përveç kontrollit të stilit, mund të përdorni gjëra të tjera, për shembull, për të kontrolluar nëse infrastruktura juaj mund të vendoset në të vërtetë. Ose kontrolloni që ndryshimet në infrastrukturë nuk do të çojnë në humbje parash. Pse mund të jetë e nevojshme kjo? Pyetja është komplekse dhe filozofike, është më mirë të përgjigjemi me një histori që disi kishte një shkallëzues automatik në Powershell që nuk kontrollonte kushtet kufitare => u krijuan më shumë VM sesa duhej => klienti shpenzoi më shumë para sesa ishte planifikuar. Kjo nuk është shumë e këndshme, por do të ishte mjaft e mundur të kapej ky gabim në fazat e mëparshme.

Dikush mund të pyesë, pse ta bëjmë infrastrukturën komplekse edhe më komplekse? Testet për infrastrukturën, ashtu si për kodin, nuk kanë të bëjnë me thjeshtimin, por për të ditur se si duhet të funksionojë infrastruktura juaj.

Piramida e Testimit IaC

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Testimi IaC: Analiza Statike

Nëse vendosni të gjithë infrastrukturën menjëherë dhe kontrolloni nëse funksionon, mund të zbuloni se kërkon shumë kohë dhe kërkon shumë kohë. Prandaj, baza duhet të jetë diçka që funksionon shpejt, ka shumë, dhe mbulon shumë vende primitive.

Bash është i ndërlikuar

Le të shohim një shembull të parëndësishëm. zgjidhni të gjithë skedarët në drejtorinë aktuale dhe kopjoni në një vend tjetër. Gjëja e parë që ju vjen në mendje:

for i in * ; do 
    cp $i /some/path/$i.bak
done

Po sikur të ketë një hapësirë ​​në emrin e skedarit? Epo, ok, ne jemi të zgjuar, ne dimë të përdorim thonjëza:

for i in * ; do cp "$i" "/some/path/$i.bak" ; done

Te lumte? Jo! Po sikur të mos ketë asgjë në drejtori, d.m.th. globbing nuk do të funksionojë.

find . -type f -exec mv -v {} dst/{}.bak ;

Mirë bëre tani? Jo... Harrove se çfarë mund të jetë në emrin e skedarit n.

touch x
mv x  "$(printf "foonbar")"
find . -type f -print0 | xargs -0 mv -t /path/to/target-dir

Mjetet e analizës statike

Problemi nga hapi i mëparshëm mund të kapej kur harruam thonjëzat, për këtë ka shumë ilaçe në natyrë Shellcheck, në përgjithësi ka shumë prej tyre, dhe ka shumë të ngjarë që ju mund të gjeni një liter për pirgun tuaj nën IDE-në tuaj.

Gjuhe
Mjet

përplas
Shellcheck

rubin
RuboCop

piton
Shtylla

ansible
Ansible Lint

Testimi IaC: Testet e njësisë

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Siç e pamë nga shembulli i mëparshëm, linjat nuk janë të gjithëfuqishëm dhe nuk mund të nxjerrin në pah të gjitha zonat problematike. Më tej, në analogji me testimin në zhvillimin e softuerit, ne mund të kujtojmë testet e njësive. Ajo që ju vjen menjëherë në mendje është shunit, junit, rspec, pestest. Por çfarë të bëni me ansible, kuzhinier, saltstack dhe të tjerë si ata?

Në fillim folëm për I ngurtë dhe se infrastruktura jonë duhet të përbëhet nga tulla të vogla. Ka ardhur koha e tyre.

  1. Infrastruktura është e ndarë në tulla të vogla, për shembull, rolet Ansible.
  2. Një lloj mjedisi është vendosur, qoftë docker ose një VM.
  3. Ne aplikojmë rolin tonë Ansible në këtë mjedis testimi.
  4. Ne kontrollojmë që gjithçka funksionoi siç prisnim (ne kryejmë teste).
  5. Ne vendosim ne rregull ose jo ne rregull.

Testimi IaC: Mjetet e testimit të njësisë

Pyetje, çfarë janë testet për CFM? Ju thjesht mund të ekzekutoni skriptin, ose mund të përdorni zgjidhje të gatshme për këtë:

Cfm
Mjet

Ansible
Testinfra

Shef
Inspektoj

Shef
Serverspec

pirg kripe
Goss

Shembull për testinfra, duke kontrolluar se përdoruesit test1, test2 ekzistojnë dhe janë në një grup sshusers:

def test_default_users(host):
    users = ['test1', 'test2' ]
    for login in users:
        assert host.user(login).exists
        assert 'sshusers' in host.user(login).groups

Çfarë të zgjidhni? Pyetja është komplekse dhe e paqartë, këtu është një shembull i ndryshimeve në projektet në github për 2018-2019:

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Kornizat e testimit të IaC

Shtrohet pyetja: si t'i bashkojmë të gjitha dhe ta lëshojmë atë? Mund merre dhe bëje vetë nëse ka një numër të mjaftueshëm inxhinierësh. Ose mund të merrni zgjidhje të gatshme, megjithëse nuk ka shumë prej tyre:

Cfm
Mjet

Ansible
molekulë

Shef
Kuzhina testuese

Terraform
Terratest

Shembull i ndryshimeve në projektet në github për 2018-2019:

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Molekula vs. Kuzhinë testuese

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Fillimisht ne u përpoq të përdorte kuzhinën testuese:

  1. Krijoni një VM paralelisht.
  2. Aplikoni rolet e Ansible.
  3. Kryeni inspektimin.

Për 25-35 role funksiononte 40-70 minuta, që ishte e gjatë.

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Hapi tjetër ishte kalimi në jenkins/docker/ansible/molekulë. Idiologjikisht gjithçka është e njëjtë

  1. Libra lojërash me lintë.
  2. Rendisni rolet.
  3. Nisja e kontejnerit
  4. Aplikoni rolet e Ansible.
  5. Ekzekutoni testinfra.
  6. Kontrolloni idempotencën.

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Lintimi për 40 role dhe testet për një duzinë filluan të zgjasin rreth 15 minuta.

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Çfarë duhet të zgjidhni varet nga shumë faktorë, si grupi i përdorur, ekspertiza në ekip, etj. këtu secili vendos vetë se si ta mbyllë pyetjen e testimit të njësisë

Testimi IaC: Testet e Integrimit

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Hapi tjetër në piramidën e testimit të infrastrukturës do të jenë testet e integrimit. Ato janë të ngjashme me testet e njësisë:

  1. Infrastruktura është e ndarë në tulla të vogla, për shembull rolet Ansible.
  2. Një lloj mjedisi është vendosur, qoftë docker ose një VM.
  3. Për këtë mjedis testimi aplikoni shumë Role të paparashikueshme.
  4. Ne kontrollojmë që gjithçka funksionoi siç prisnim (ne kryejmë teste).
  5. Ne vendosim ne rregull ose jo ne rregull.

Përafërsisht, ne nuk kontrollojmë performancën e një elementi individual të sistemit si në testet e njësisë, ne kontrollojmë se si është konfiguruar serveri në tërësi.

Testimi IaC: Testet nga fundi në fund

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Në krye të piramidës na presin testet End to End. ato. Ne nuk kontrollojmë performancën e një serveri të veçantë, një skripti të veçantë ose një tullë të veçantë të infrastrukturës sonë. Ne kontrollojmë që shumë serverë të lidhur së bashku, infrastruktura jonë funksionon ashtu siç e presim. Fatkeqësisht, nuk kam parë kurrë zgjidhje të gatshme në kuti, ndoshta sepse... Infrastruktura është shpesh unike dhe e vështirë për t'u modeluar dhe për të krijuar një kornizë për testim. Si rezultat, secili krijon zgjidhjet e veta. Ka një kërkesë, por nuk ka përgjigje. Prandaj, unë do t'ju tregoj se çfarë ka për t'i shtyrë të tjerët të mendojnë ose të fërkojnë hundën time në faktin se gjithçka është shpikur shumë kohë më parë para nesh.

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Një projekt me një histori të pasur. Përdoret në organizata të mëdha dhe me siguri secili prej jush ka kryqëzuar rrugët me të në mënyrë indirekte. Aplikacioni mbështet shumë baza të dhënash, integrime, etj. Të dish se si mund të duket infrastruktura është shumë skedarë të hartuar nga docker dhe të dish se cilat teste të ekzekutohen në cilin mjedis është Jenkins.

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Kjo skemë funksionoi për një kohë mjaft të gjatë, deri sa brenda kornizës hulumtim ne nuk jemi përpjekur ta transferojmë këtë te Openshift. Kontejnerët mbeten të njëjtë, por mjedisi i nisjes ka ndryshuar (përshëndetje DRY përsëri).

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Ideja e kërkimit shkoi më tej, dhe në openshift ata gjetën një gjë të tillë si APB (Ansible Playbook Bundle), e cila ju lejon të paketoni njohuritë se si të vendosni infrastrukturën në një kontejner. Ato. ekziston një pikë e përsëritshme dhe e testueshme e njohurive se si të vendoset infrastruktura.

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

E gjithë kjo dukej mirë derisa u përballëm me një infrastrukturë heterogjene: na duhej Windows për teste. Si rezultat, njohuria se çfarë, ku, si të vendoset dhe testohet është në jenkins.

Përfundim

Çfarë mësova nga testimi i 200 linjave të kodit të infrastrukturës

Infrastruktura siç është Kodi

  • Kodi në depo.
  • Ndërveprimi njerëzor.
  • Testimi i infrastrukturës.

Lidhje

Burimi: www.habr.com

Shto një koment