1960-luvulla ohjelmistotekniikassa pidettiin hyvänä käytäntönä testata koodia sitä kirjoitettaessa. Ohjelmistokehityksen pioneerit tuona aikakautena kannattivat eritasoista testausta; jotkut kannattivat ”yksikkötestausta” ja jotkut eivät, mutta kaikki tunnustivat koodin testaamisen tärkeyden.
Toteutettavat testit otti ehkä ensimmäisenä käyttöön Margaret Hamilton Apollo-projektissa 1960-luvun puolivälissä, jossa hän sai alkunsa eräänlaisesta suoritettavan koodin tarkistamisesta, jota nykyään kutsumme ”staattiseksi koodianalyysiksi”. Hän kutsui sitä ”korkeamman asteen ohjelmistoksi”, jolla hän tarkoitti ohjelmistoa, joka toimii muita ohjelmistoja vastaan eikä suoraan ongelma-aluetta vastaan. Hänen korkeamman asteen ohjelmistonsa tutkivat lähdekoodia etsiäkseen malleja, joiden tiedettiin johtavan integraatio-ongelmiin.
Vuoteen 1970 mennessä ihmiset olivat jo pitkälti unohtaneet suoritettavan koodin testauksen. Toki ihmiset ajoivat sovelluksia ja tökkäsivät niitä siellä täällä käsin, mutta niin kauan kuin rakennus ei palanut heidän ympäriltään, he ajattelivat, että koodi oli ”riittävän hyvä”. Tuloksena on ollut yli 35 vuotta maailmanlaajuisesti tuotannossa olevaa koodia, joka on puutteellisesti testattu ja joka monissa tapauksissa ei toimi täysin tarkoitetulla tavalla tai tavalla, joka tyydyttäisi asiakkaita.
Ajatus ohjelmoijien testaamisesta ohjelmoinnin edetessä teki paluun 1990-luvun puolivälistä alkaen, vaikkakin vielä nykyäänkin suuri enemmistö ohjelmoijista ei tee sitä. Infrastruktuuri-insinöörit ja järjestelmänvalvojat testaavat skriptejään vielä vähemmän ahkerasti kuin ohjelmoijat testaavat sovelluskoodiaan.
Kun siirrymme aikakauteen, jolloin lukuisista itsenäisistä komponenteista koostuvien monimutkaisten ratkaisujen nopeasta käyttöönotosta on tulossa normi ja ”pilvi”-infrastruktuurit vaativat meitä hallitsemaan tuhansia tulevia ja meneviä VM:iä ja konttia mittakaavassa, jota ei voi hallita manuaalisin menetelmin, suoritettavan, automatisoidun testauksen ja tarkastuksen tärkeyttä läpi koko kehittely- ja jakeluprosessin ei voida jättää huomiotta; ei vain sovellusten ohjelmoijien vaan myös kaikkien muidenkin tietotekniseen työhön osallistuvien henkilöiden kannalta.
Devopsin (kehitys- ja käyttötaitojen, -menetelmien ja -työkalujen ristiinpölytys) ja trendien, kuten ”infrastruktuuri koodina” ja ”automatisoi kaikki asiat”, myötä yksikkötestauksesta on tullut perustaito niin ohjelmoijille, testaajille, järjestelmänvalvojille kuin infrastruktuuri-insinööreillekin.
Tässä postaussarjassa esittelemme yksikkötestauksen ajatuksen shell-skripteistä, ja sen jälkeen tutustumme useisiin yksikkötestauskehyksiin, jotka voivat auttaa tekemään tästä tehtävästä käytännöllisen ja kestävän mittakaavassa.
Toinen monille infrastruktuuri-insinööreille ehkä tuntematon käytäntö on versionhallinta. Myöhemmin tässä sarjassa käsittelemme sovelluskehittäjien käyttämiä versionhallintajärjestelmiä ja työnkulkuja, jotka voivat olla tehokkaita ja hyödyllisiä myös infrastruktuuri-insinööreille.
- Skripti testaukseen
- Automaattiset toiminnalliset tarkistukset
- Pass, Fail ja Error
- Mitä meidän pitäisi tarkistaa?
- Mitä meidän ei pitäisi tarkistaa?
- Df-komennon pilkkominen
- Mocking the mail Command
- Malli automatisoitujen tarkistusten suorittamiseen
- Miksi käyttää testikehystä/-kirjastoa?
- Yksikkötestauskehykset skripteille
Skripti testaukseen
Vivek Gite julkaisi esimerkin shell-skriptistä, jolla voidaan valvoa levynkäyttöä ja luoda sähköposti-ilmoitus, kun tietyt tiedostojärjestelmät ylittävät tietyn raja-arvon. Hänen artikkelinsa on täällä: https://www.cyberciti.biz/tips/shell-script-to-watch-the-disk-space.html. Käytetään sitä testikohteena.
Ensimmäinen versio hänen skriptistään, johon on lisätty df-komennon -P-vaihtoehto rivinvaihdon estämiseksi ulostulossa, kuten Per Lindahlin kommentissa ehdotettiin, näyttää tältä:
#!/bin/shdf -HP | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print " " }' | while read output;do usep=$(echo $output | awk '{ print }' | cut -d'%' -f1 ) partition=$(echo $output | awk '{ print }' ) if ; then echo "Running out of space \"$partition ($usep%)\" on $(hostname) as on $(date)" | mail -s "Alert: Almost out of disk space $usep%" [email protected] fidone
Vivek jatkaa skriptin hiomista vielä pidemmälle, mutta tämä versio palvelee tämän postauksen tarkoituksia.
Automaattiset toiminnalliset tarkistukset
Pari nyrkkisääntöä automaattisista toiminnallisista tarkistuksista, riippumatta siitä, tarkistammeko sovelluskoodia, skriptiä tai mitä tahansa muuta ohjelmistoa:
- Tarkistuksen on suorituttava joka kerta identtisesti, eikä manuaalista virittelyä tarvita jokaiseen suoritukseen valmistautumisessa; ja
- tulos ei saa olla haavoittuvainen muutoksille suoritusympäristössä, datassa tai muissa testattavasta ohjelmakoodista riippumattomissa tekijöissä.
Pass, Fail ja Error
Voi huomauttaa, että on mahdollista, että skripti ei toimi ollenkaan. Se on normaalia minkä tahansa sovelluksen yksikkötestauskehyksessä. Kolme lopputulosta kahden sijaan on mahdollista:
- Testattava koodi osoittaa odotettua käyttäytymistä
- Testattava koodi toimii, mutta ei osoita odotettua käyttäytymistä
- Testattava koodi ei toimi
Käytännössä kolmas lopputulos on sama kuin toinenkin; on selvitettävä, mikä meni pieleen ja korjattava se. Ajattelemme siis yleensä näitä asioita binäärisinä: Hyväksytty tai hylätty.
Mitä meidän pitäisi tarkistaa?
Tässä tapauksessa olemme kiinnostuneita tarkistamaan, että komentosarja käyttäytyy odotetulla tavalla erilaisilla syöttöarvoilla. Emme halua saastuttaa yksikkötarkastuksiamme millään muulla todentamisella tämän lisäksi.
Tarkasteltaessa testattavaa koodia näemme, että kun levynkäyttö saavuttaa 90 %:n raja-arvon, skripti kutsuu mailia lähettääkseen ilmoituksen järjestelmänvalvojalle.
Yksikkötarkastuksissa yleisesti hyväksyttyjen hyvien käytäntöjen mukaisesti haluamme määritellä erilliset tapaukset jokaisen odottamamme käyttäytymisen todentamiseksi jokaiselle alkuehtojen joukolle.
Pukeutumalla ”testaajan” hattuun huomaamme, että kyseessä on eräänlainen reunaehto. Meidän ei tarvitse tarkistaa lukuisia eri prosenttiosuuksia levynkäytöstä erikseen. Meidän täytyy vain tarkistaa käyttäytyminen rajoilla. Siksi mielekkään kattavuuden tarjoavien tapausten vähimmäisjoukko on:
- Se lähettää sähköpostia, kun levynkäyttö saavuttaa raja-arvon
- Se ei lähetä sähköpostia, kun levynkäyttö on raja-arvon alapuolella
Mitä meidän ei pitäisi tarkistaa?
Yksikkötestauksen eristämisen yleisesti hyväksyttyjen hyvien toimintatapojen mukaisesti haluamme varmistua siitä, että kukin tapauksestamme voi epäonnistua täsmälleen yhdestä syystä: Odotettu käyttäytyminen ei tapahdu. Siinä määrin kuin se on käytännöllistä, haluamme asettaa tarkistuksemme niin, että muut tekijät eivät aiheuta tapauksen epäonnistumista.
Aina ei välttämättä ole kustannustehokasta (tai edes mahdollista) taata, että ulkoiset tekijät eivät vaikuta automaattisiin tarkistuksiimme. On tilanteita, joissa emme voi kontrolloida jotakin ulkoista tekijää tai joissa sen tekeminen vaatisi enemmän aikaa, vaivaa ja kustannuksia kuin mitä tarkastuksen arvo on, ja/tai joissa on kyse hämärästä ääritapauksesta, jonka esiintymistodennäköisyys on hyvin pieni tai jonka vaikutus on hyvin vähäinen, kun se tapahtuu. Se on ammatillisen harkintakykysi asia. Yleissääntönä kannattaa pyrkiä välttämään riippuvuuksien luomista tekijöistä, jotka eivät kuulu testattavan koodin piiriin.
Meidän ei tarvitse tarkistaa, että df-, grep-, awk-, cut- ja mail-komennot toimivat. Se ei kuulu tarkoituksiimme. Siitä vastaa se, joka ylläpitää apuohjelmia.
Me haluamme tietää, jos df-komennon tulostetta ei käsitellä grep- tai awk-komennolla odotetulla tavalla. Siksi haluamme, että oikeat grep- ja awk-komennot suoritetaan tarkistuksissamme df-komennon tulosteen perusteella, joka vastaa kunkin testitapauksen tarkoitusta. Tämä on soveltamisalaa, koska df:n komentoriviargumentit ovat osa komentosarjaa, ja komentosarja on testattavaa koodia.
Tämä tarkoittaa, että tarvitsemme väärennetyn version df-komennosta käytettäväksi yksikkötarkastuksissamme. Tällaista väärennettyä komponenttia kutsutaan usein mockiksi. Mock korvaa todellisen komponentin ja tarjoaa ennalta määritellyn tuotoksen, jolla ohjataan järjestelmän käyttäytymistä kontrolloidusti, jotta voimme tarkistaa testattavan koodin käyttäytymisen luotettavasti.
Näemme, että skripti lähettää sähköposti-ilmoituksen, kun tiedostojärjestelmä saavuttaa kynnyskäyttötason. Emme halua, että yksikkötarkistuksemme sylkevät ulos kasan turhia sähköposteja, joten haluamme pilkata myös mail-komentoa.
Tämä skripti on hyvä esimerkki havainnollistamaan näiden komentojen pilkkomista, koska teemme sen eri tavalla mailin kuin df:n kohdalla.
Df-komennon pilkkominen
Skripti on rakennettu df-komennon ympärille. Merkityksellinen rivi skriptissä on:
df -HP | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print " " }'
Jos suorittaisit pelkän df -HP-komennon ilman putkitusta grep:iin, näkisit samanlaisen tulosteen kuin tämä:
Filesystem Size Used Avail Use% Mounted onudev 492M 0 492M 0% /devtmpfs 103M 6.0M 97M 6% /run/dev/sda1 20G 9.9G 9.2G 52% /tmpfs 511M 44M 468M 9% /dev/shmtmpfs 5.3M 0 5.3M 0% /run/locktmpfs 511M 0 511M 0% /sys/fs/cgrouptmpfs 103M 8.2k 103M 1% /run/user/1000
Grep- ja awk-komennot riisuvat tulosteen tällaiseksi:
0% udev52% /dev/sda1
Meidän on hallittava df:stä tulevaa tulostetta, jotta voisimme ohjata testitapauksia. Emme halua, että tarkistuksen tulos vaihtelee sen järjestelmän todellisen levynkäytön mukaan, jossa suoritamme testisarjan. Emme tarkista levynkäyttöä, vaan skriptin logiikkaa. Kun komentosarja suoritetaan tuotannossa, se tarkistaa levyn käytön. Se, mitä teemme tässä, on validointia, ei tuotantotoimintoja varten. Siksi tarvitsemme väärennetyn tai ”mock” df-komennon, jolla voimme tuottaa ”testidataa” jokaista tapausta varten.
*nix-alustalla on mahdollista ohittaa oikea df-komento määrittelemällä alias. Haluamme alias-komennon tuottavan testiarvot samassa muodossa kuin df -HP:n tuloste. Tässä on yksi tapa tehdä se (tämä kaikki on yhtä riviä; se on pilkottu alempana luettavuuden vuoksi):
alias df="shift;echo -e 'Filesystem Size Used Avail Use% Mounted on'; echo -e 'tempfs 511M 31M 481M 6% /dev/shm'; echo -e '/dev/sda1 20G 9.9G 9.2G 52% /'"
Vuoro ohittaa ’-HP’-argumentin, kun skripti ajetaan, jotta järjestelmä ei valittaisi, että -HP on tuntematon komento. Alias df-komento antaa tulosteen samassa muodossa kuin df -HP.
Testiarvot putkitetaan grep:iin ja sen jälkeen awk:iin, kun skripti suoritetaan, joten pilkistämme vain sen vähimmäismäärän, joka on tarpeen testitapauksiemme hallitsemiseksi. Haluamme testitapauksemme olevan mahdollisimman lähellä ”oikeaa asiaa”, jotta emme saa vääriä positiivisia tuloksia.
Mocking-kirjaston avulla luodut mockit voivat kutsuttaessa palauttaa ennalta määritetyn arvon. Lähestymistapamme df-komennon pilkkomiseen peilaa tätä mockin toimintaa; määrittelemme ennalta määritellyn tulosteen, joka palautetaan aina, kun testattava koodi kutsuu df:ää.
Mocking the mail Command
Haluamme tietää, yrittääkö skripti lähettää sähköpostia oikeissa olosuhteissa, mutta emme halua sen lähettävän oikeaa sähköpostia mihinkään. Siksi haluamme aliasoida mail-komennon, kuten teimme aiemmin df-komennolle. Meidän on määritettävä jotain, jonka voimme tarkistaa jokaisen testitapauksen jälkeen. Yksi mahdollisuus on kirjoittaa arvo tiedostoon, kun mail-komentoa kutsutaan, ja tarkistaa arvo sitten testitapauksessamme. Tämä on esitetty alla olevassa esimerkissä. Myös muut menetelmät ovat mahdollisia.
Mocking-kirjaston avulla luodut mockit voivat laskea, kuinka monta kertaa testattava koodi kutsuu niitä, ja voimme vakuuttaa odotetun määrän kutsuja. Lähestymistapamme mail-komennon pilkkomiseen peilaa tätä mockin toimintaa; jos tiedostossa mailsent on teksti ”mail” sen jälkeen, kun diskusage.sh-skripti on ajettu, se tarkoittaa, että skripti todella kutsui mail-komentoa.
Malli automatisoitujen tarkistusten suorittamiseen
Automatisoidut tai suoritettavat tarkistukset millä tahansa abstraktiotasolla, minkä tahansa sovelluksen tai komentosarjan, millä tahansa kielellä tahansa käsikirjoitettuna koostuvat tyypillisesti kolmesta vaiheesta. Nämä kulkevat yleensä nimillä:
- Arrange
- Act
- Assert
Syy tähän on luultavasti se, että kaikki rakastavat allitteraatiota, erityisesti A-kirjaimella, sillä sana ”allitteraatio” itsessäänkin alkaa A-kirjaimella.
Syystä riippumatta, askeleessa arrange asetamme testitapauksemme ennakkoehdot. Vaiheessa act kutsumme testattavan koodin. Assert-vaiheessa ilmoitamme tuloksen, jonka odotamme näkevämme.
Kun käytämme testikehystä tai -kirjastoa, työkalu hoitaa assert-vaiheen hienosti puolestamme, joten meidän ei tarvitse koodata paljon hankalaa if/else-logiikkaa testisarjoihimme. Tässä alkuperäisessä esimerkissämme emme käytä testikehystä tai -kirjastoa, joten tarkistamme jokaisen tapauksen tulokset if/else-lohkolla. Seuraavassa osassa leikimme yksikkötestauskehyksillä komentosarjakielille ja katsomme, miltä se näyttää.
Tässä on karkea mutta tehokas testiskriptimme, jolla testaamme Vivekin komentosarjakomentosarjaa, jonka olemme nimenneet diskusage.sh:
#!/bin/bashshopt -s expand_aliases# Before allalias mail="echo 'mail' > mailsent;false"echo 'Test results for diskusage.sh' > test_resultstcnt=0# It does nothing when disk usage is below 90%# Before (arrange)alias df="echo 'Filesystem Size Used Avail Use% Mounted on';echo '/dev/sda2 100G 89.0G 11.0G 89% /'"echo 'no mail' > mailsent# Run code under test (act). ./diskusage.sh# Check result (assert)((tcnt=tcnt+1))if ]; then echo "$tcnt. FAIL: Expected no mail to be sent for disk usage under 90%" >> test_resultselse echo "$tcnt. PASS: No action taken for disk usage under 90%" >> test_resultsfi # It sends an email notification when disk usage is at 90%alias df="echo 'Filesystem Size Used Avail Use% Mounted on';echo '/dev/sda1 100G 90.0G 10.0G 90% /'"echo 'no mail' > mailsent. ./diskusage.sh((tcnt=tcnt+1))if ]; then echo "$tcnt. PASS: Notification was sent for disk usage of 90%" >> test_resultselse echo "$tcnt. FAIL: Disk usage was 90% but no notification was sent" >> test_resultsfi # After allunalias dfunalias mail# Display test results cat test_results
Tässä on testiskriptin läpikäynti.
Ensiksi huomaat, että testaamme tavallista vanhaa .sh-tiedostoa bashin avulla. Se on täysin kunnossa. Se ei ole välttämätöntä, mutta se on hyvä.
Seuraavaksi näet shopt-komennon. Se saa komentotulkin laajentamaan testiemme aliakset, kun subshelliä kutsutaan ajamaan diskusage.sh-skriptiä. Useimmissa käyttötapauksissa emme välittäisi aliaksia alikuoriin, mutta yksikkötestaus on poikkeus.
Kommentti ”Ennen kaikkea” on tarkoitettu ihmisille, jotka tuntevat yksikkötestauskehykset, joissa on set up- ja tear down -komennot. Nämä on usein nimetty jotenkin kuten ”ennen” ja ”jälkeen”, ja yleensä on yksi pari, joka sulkee koko testisarjan, ja toinen pari, joka suoritetaan erikseen jokaisen testitapauksen kohdalla.
Halusimme näyttää, että postin aliaksen määrittely, testitulostiedoston alustaminen ja testitapauslaskurin alustaminen tehdään kaikki täsmälleen kerran, testisarjan alussa. Tällainen on normaalia suoritettavissa testisarjoissa. Se, että testaamme komentosarjakomentosarjaa sovellusohjelman sijasta, ei muuta tätä.
Seuraava kommentti ”It does nothing…” osoittaa, että ensimmäinen yksittäinen testitapauksemme alkaa. Useimmat yksikkötestauskehykset tarjoavat tavan antaa jokaiselle tapaukselle nimi, jotta voimme pitää kirjaa siitä, mitä tapahtuu, ja jotta muut työkalut voivat etsiä, suodattaa ja poimia testitapauksia eri syistä.
Seuraavana on kommentti, jossa lukee: ”Ennen (järjestää)”. Tämä edustaa asetusta, joka koskee vain yhtä testitapausta. Asetamme df-aliasin tuottamaan tulosteen, jota tarvitsemme tätä tiettyä tapausta varten. Kirjoitamme myös tekstin ”no mail” tiedostoon. Näin pystymme kertomaan, yrittikö diskusage.sh-skripti lähettää ilmoitussähköpostia.
Seuraavaksi tulee tekovaihe, jossa harjoitamme testattavaa koodia. Tässä tapauksessa se tarkoittaa itse diskusage.sh-skriptin suorittamista. Lähdemme sen lähdekoodiin sen sijaan, että suorittaisimme sen suoraan.
Siitä seuraa assert-vaihe, jonka teemme tässä esimerkissä vaikealla tavalla, koska emme ole vielä ottaneet käyttöön testikehystä. Kasvatamme testilaskuria, jotta voimme numeroida testitapaukset tulostiedostossa. Muuten, jos tapauksia olisi suuri määrä, voisi olla vaikeaa selvittää, mitkä tapaukset ovat epäonnistuneet. Testauskehykset hoitavat tämän puolestamme.
Mail-komennolle määrittelemämme alias kirjoittaa tekstin ’mail’ mailsent-tiedostoon. Jos diskusage.sh kutsuu komentoa mail, mailsent-tiedosto sisältää ’mail’ alkuarvon ’no mail’ sijasta. Voit nähdä, mitkä ovat läpäisy- ja hylkäysehdot lukemalla testitulostiedostoon kaikuvat merkkijonot.
Alkaen kommentista ”Se lähettää sähköposti-ilmoituksen…” toistamme arrange, act, assert -vaiheet toiselle testitapaukselle. Laitamme väärennetyn df-komentomme lähettämään tällä kertaa erilaista dataa, jotta testattava koodi käyttäytyisi eri tavalla.
Koska kommentti ”After all” ilmestyy, siivoamme jälkemme poistamalla määrittelyt, jotka loimme ”Before all” -asetuksessa lähellä testiskriptin yläosaa.
Lopuksi tyhjennämme test_results-tiedoston sisällön, jotta voimme nähdä, mitä saimme. Se näyttää tältä:
Test results for diskusage.sh1. PASS: No action taken for disk usage under 90%2. PASS: Notification was sent for disk usage of 90%
Miksi käyttää testikehystä/-kirjastoa?
Kirjoitimme juuri pari yksikkötestitapausta komentosarjakomentosarjalle käyttämättä testikehystä, mocking-kirjastoa tai assertion-kirjastoa. Huomasimme, että järjestelmäkomentoja voidaan pilkata määrittelemällä aliaksia (ainakin *nix-järjestelmissä), että väittämät voidaan toteuttaa ehdollisina lausekkeina ja että yksikkötestin perusrakenne on helppo asettaa käsin.
Ei ollut vaikeaa tehdä tätä ilman kehystä tai kirjastoa. Mitä hyötyä siitä sitten on?
Testikehykset ja -kirjastot yksinkertaistavat ja standardoivat testikoodia ja mahdollistavat paljon luettavammat testisarjat kuin käsin tehdyt skriptit, jotka sisältävät paljon ehdollisia lauseita. Jotkin kirjastot sisältävät hyödyllisiä lisäominaisuuksia, kuten mahdollisuuden loukata poikkeuksia tai mahdollisuuden kirjoittaa taulukko- ja datapohjaisia testitapauksia. Jotkut on räätälöity tukemaan tiettyjä infrastruktuuri-insinöörejä kiinnostavia tuotteita, kuten Chef ja Puppet. Ja joihinkin sisältyy toimintoja koodin kattavuuden seuraamiseksi ja/tai testitulosten muotoilemiseksi CI/CD-putken työkalujen tai ainakin web-selaimen käyttämään muotoon.
Yksikkötestauskehykset skripteille
Tässä sarjassa tutustumme useisiin yksikkötestauskehyksiin komentosarjakomentosarjoille ja skriptikielille. Tässä on yleiskatsaus:
- shunit2 on erittäin vankka avoimen lähdekoodin projekti, jolla on kymmenen vuoden historia. Sen on alun perin kehittänyt Kate Ward, Googlen Zürichissä toimiva Site Reliability Engineer ja Manager, ja sitä kehittää ja tukee aktiivisesti kuuden hengen tiimi. Nöyrästä alusta, joka oli pistemäinen ratkaisu komentosarjakomentosarjojen lokikirjaston testaamiseen, sitä on tarkoituksella kehitetty yleiskäyttöiseksi yksikkötestauskehykseksi, joka tukee useita komentosarjakieliä ja käyttöjärjestelmiä. Se sisältää useita hyödyllisiä ominaisuuksia yksinkertaisten väitteiden lisäksi, kuten tuen data- ja taulukkopohjaisille testeille. Se käyttää perinteistä ”assertThat”-tyyliä väitteissä. Projektin sivustolla on erinomainen dokumentaatio. Shell-skriptien yleiskäyttöiseen yksikkötestaukseen tämä on ykkössuositukseni.
- BATS (Bash Automated Testing System) on yksikkötestauskehys bashille. Sen loi Sam Stephenson noin seitsemän vuotta sitten, ja sillä on ollut kymmenkunta tekijää. Viimeisin päivitys oli neljä vuotta sitten, mutta tästä ei ole syytä huoleen, sillä tämäntyyppiset työkalut eivät vaadi usein päivityksiä tai ylläpitoa. BATS perustuu TAP-protokollaan (Test Anything Protocol), joka määrittelee johdonmukaisen tekstipohjaisen rajapinnan minkä tahansa testivalikoiman moduulien välillä. Se mahdollistaa puhtaan ja johdonmukaisen syntaksin testitapauksissa, vaikka se ei näytä lisäävän paljon muuta syntaktista hienoutta kuin suorat bash-lausekkeet. Esimerkiksi väitteille ei ole erityistä syntaksia; testituloksia varten kirjoitetaan bash-komentoja. Näin ollen sen tärkein arvo saattaa olla testisarjojen ja -tapausten järjestämisessä loogisella tavalla. Huomaa myös, että testiskriptien kirjoittaminen bashilla ei estä meitä testaamasta muita kuin bash-skriptejä; teimme sen aiemmin tässä viestissä. Se, että BATS-syntaksi on niin lähellä tavallista bash-syntaksia, antaa meille paljon joustavuutta käsitellä erilaisia komentotulkkikieliä testisarjoissamme, vaikka se mahdollisesti heikentää luettavuutta (riippuen siitä, mitä pidät ”luettavana”; tämän postauksen kohdeyleisö pitää luultavasti tavallista komentotulkkikielen syntaksia melko luettavana). Yksi erityisen mielenkiintoinen ominaisuus (mielestäni) on se, että voit asettaa tekstieditorillesi BATSin syntaksin korostuksen, kuten projektin wikissä on dokumentoitu. Emacs, Sublime Text 2, TextMate, Vim ja Atom olivat tuettuja tämän postauksen päivämääränä.
- zunit (ei se IBM:n, vaan se toinen) on James Dinsdalen kehittämä yksikkötestauskehys zsh:lle. Projektisivuston mukaan zunit on saanut inspiraationsa BATSista, ja se sisältää erittäin hyödylliset muuttujat $state, $output ja $lines. Mutta siinä on myös selkeä väittämien syntaksi, joka noudattaa mallia ”assert actual matches expected”. Jokaisella näistä kehyksistä on joitakin ainutlaatuisia ominaisuuksia. ZUnitin mielenkiintoinen ominaisuus on mielestäni se, että se merkitsee kaikki testitapaukset, jotka eivät sisällä väittämää, ”riskialttiiksi”. Voit ohittaa tämän ja pakottaa tapaukset ajettaviksi, mutta oletusarvoisesti kehys auttaa sinua muistamaan sisällyttää väitteen jokaiseen testitapaukseen.
- bash-spec on käyttäytymistyylinen testikehys, joka tukee vain bashia (tai ainakin sitä on testattu vain bash-skripteillä). Se on vaatimaton sivuprojektini, joka on ollut olemassa yli neljä vuotta ja jolla on muutama ”oikea” käyttäjä. Sitä ei juurikaan päivitetä, koska se tekee tällä hetkellä sen, mitä sen oli tarkoitus tehdä. Yksi projektin tavoitteista oli käyttää bash-funktioita ”sujuvaan” tyyliin. Funktioita kutsutaan peräkkäin, ja kukin välittää koko argumenttilistan seuraavalle sen jälkeen, kun se on kuluttanut niin monta argumenttia kuin se tarvitsee tehtävänsä suorittamiseen. Tuloksena on luettava testisarja, jossa on lauseita kuten ”expect package-name to_be_installed” ja ”expect arrayname not to_contain value”. Kun sitä käytetään ohjaamaan skriptien kehittämistä testit ensin -periaatteella, sen suunnittelulla on taipumus johtaa kehittäjää kirjoittamaan funktioita, jotka tukevat ”modulaarisuuden” tai ”yhden vastuun” tai ”huolenaiheiden erottamisen” ajatusta (kutsu sitä miksi haluat), mikä johtaa helppoon ylläpitoon ja helposti uudelleenkäytettäviin funktioihin. ”Käyttäytymistyyli” tarkoittaa, että väitteet ovat muotoa ”odota, että tämä vastaa tuota.”
- korn-spec on bash-specin portti korn-kuorelle.
- Pester on Powershellin yksikkötestauskehys. Powershell näyttää ja tuntuu enemmän sovellusohjelmointikieleltä kuin puhtaasti skriptikieleltä, ja Pester tarjoaa täysin yhtenäisen kehittäjäkokemuksen. Pester toimitetaan Windows 10:n mukana, ja se voidaan asentaa mihin tahansa muuhun Powershelliä tukevaan järjestelmään. Siinä on vankka väittämäkirjasto, sisäänrakennettu tuki mockingille ja se kerää koodin kattavuusmittareita.
- ChefSpec perustuu rspeciin tarjotakseen käyttäytymistyylisen testikehyksen Chef-resepteille. Chef on Ruby-sovellus, ja ChefSpec hyödyntää täysin rspecin ominaisuuksia sekä sisäänrakennettua tukea Chef-spesifisille toiminnoille.
- rspec-puppet on käyttäytymistyylinen kehys Puppetille, toiminnallisesti samanlainen kuin ChefSpec.