Funktioiden yksikkötestaus Bats-corella
Rakenna testitiedostot, väitteet ja valmistelu- sekä purkuvaiheet yksittäisten Bash-funktioiden tarkistamista varten.
Funktioiden yksikkötestaus Bats-corella on ilmainen DevOps-bootcamp-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu DevOps-bootcamp-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. DevOps-bootcamp-kurssilla on yhteensä 4 oppituntia.
Mikä Bats-core on ja miksi sitä käytetään?
Bats-core (Bash Automated Testing System) on Bashin de facto -yksikkötestauskehys. Sen avulla voitte kirjoittaa jäsenneltyjä ja toistettavia testejä shell-funktioille ja -skripteille samalla tavalla kuin käyttäisitte JUnitia Javassa tai pythoniin tarkoitettua pytestiä.
- Jokainen testi on
@test-lohko, jolla on ihmiselle helposti luettava kuvaus. - Testi läpäistään, kun jokainen sen sisällä suoritettava komento palauttaa paluuarvon
0. - Testi epäonnistuu ensimmäisen nollasta poikkeavan paluuarvon tai epäonnistuneen väitteen kohdalla.
- Tuloste on TAP-yhteensopiva, joten CI-järjestelmät (GitHub Actions, Jenkins, GitLab CI) ymmärtävät sen suoraan.
Asentakaa se paketinhallinnan avulla tai kloonatkaa repositorio:
# Install via git (recommended — always latest)
git clone https://github.com/bats-core/bats-core.git
cd bats-core && sudo ./install.sh /usr/local
# Or on macOS with Homebrew
brew install bats-core
# Verify installation
bats --version
# bats 1.x.yEnsimmäinen Bats-testitiedostonne
Bats-testitiedoston tiedostopääte on .bats, ja se alkaa erityisellä shebang-rivillä. Keskeinen rakennuspalikka on @test-direktiivi, jota seuraavat kuvausmerkkijono ja komentolohko.
- Shebang
#!/usr/bin/env batskertoo shellille, miten tiedosto suoritetaan. - Jokainen
@test-lohko on itsenäinen testitapaus. - Voitte suorittaa yksittäisen tiedoston komennolla
bats my_tests.batstai kokonaisen hakemiston komennollabats test/.
Alla on Bats-testitiedoston vähimmäisrakenne:
#!/usr/bin/env bats
# File: test/hello.bats
@test "echo outputs the expected string" {
result=$(echo "hello world")
[ "$result" = "hello world" ]
}
@test "false command causes test to fail" {
# Uncommenting the next line would make this test fail:
# false
true
}Testattavan funktion lataaminen load-komennolla
Oikeissa projekteissa Bash-funktiot sijaitsevat kirjastotiedostoissa, eivät itse testitiedostossa. Bats tarjoaa load-apufunktion, jolla ulkoiset tiedostot voidaan lähdekoodata testitiedoston hakemistoon nähden suhteellisella polulla.
load '../lib/math.sh'lähdekoodaa tiedoston ennen jokaisen testin suorittamista.- Lataamisen jälkeen kaikki kyseisessä tiedostossa määritellyt funktiot ovat käytettävissä testilohkoissa.
- Selkeän erottelun vuoksi pitäkää kirjastofunktiot
lib/-hakemistossa ja testittest/-hakemistossa.
Esimerkki projektin rakenteesta ja sitä vastaavasta testistä:
# Project layout:
# lib/math.sh <- functions to test
# test/math.bats <- test file
# lib/math.sh
add() {
echo $(( $1 + $2 ))
}
divide() {
if [ "$2" -eq 0 ]; then
echo "Error: division by zero" >&2
return 1
fi
echo $(( $1 / $2 ))
}
# test/math.bats
#!/usr/bin/env bats
load '../lib/math.sh'
@test "add returns correct sum" {
result=$(add 3 4)
[ "$result" = "7" ]
}Keskeiset väitteet: run, $status, $output
run-komento on Bats-testauksen ydin. Sen sijaan että suorittaisitte komennon suoraan, ympäröikää se run-komennolla. Tällöin sen paluuarvo ja tuloste tallennetaan ilman, että testi epäonnistuu heti.
$status— sisältää viimeisimmänrun-komennon paluuarvon.$output— sisältää viimeisimmänrun-komennon yhdistetyn vakiotulosteen.$lines— taulukko, jonka jokainen alkio on yksi tulosterivi (${lines[0]},${lines[1]}jne.).
Näin voitte tarkistaa sekä onnistuvat että epäonnistuvat tilanteet:
#!/usr/bin/env bats
load '../lib/math.sh'
@test "divide 10 by 2 returns 5" {
run divide 10 2
[ "$status" -eq 0 ]
[ "$output" = "5" ]
}
@test "divide by zero returns exit code 1" {
run divide 10 0
[ "$status" -eq 1 ]
}
@test "divide by zero prints error message" {
run divide 10 0
# $output captures stderr too when redirected inside the function
[[ "$output" == *"division by zero"* ]]
}Ilmaisuvoimaisten väitteiden käyttäminen bats-assert-kirjastolla
Sisäänrakennetut [ ]-väitteet toimivat, mutta niiden virheilmoitukset ovat niukkoja. bats-assert-apukirjasto tarjoaa ilmaisuvoimaisia väitefunktioita, jotka ilmoittavat tarkasti, mikä meni vikaan.
assert_success— varmistaa, että$statuson 0.assert_failure— varmistaa, että$statuspoikkeaa nollasta.assert_output— varmistaa, että$outputvastaa annettua merkkijonoa.assert_output --partial— varmistaa, että tuloste sisältää osamerkkijonon.refute_output --partial— varmistaa, että tuloste EI sisällä osamerkkijonoa.
Asentakaa kirjasto kloonaamalla bats-core/bats-assert test/helpers/-hakemistoon ja lataamalla se sitten:
#!/usr/bin/env bats
# Load bats-assert (cloned into test/helpers/bats-assert)
load 'helpers/bats-assert/load'
load '../lib/math.sh'
@test "add 5 and 3 gives 8" {
run add 5 3
assert_success
assert_output "8"
}
@test "divide by zero fails with descriptive message" {
run divide 9 0
assert_failure
assert_output --partial "division by zero"
}
@test "add does not output an error" {
run add 1 1
refute_output --partial "Error"
}setup ja teardown: testin elinkaarikoukut
Bats tarjoaa kaksi erityistä funktiota — setup ja teardown — jotka suoritetaan automaattisesti jokaisen testin yhteydessä. Käyttäkää niitä jaetun tilan valmistelemiseen ja siivoamiseen, jotta jokainen testi alkaa tunnetusta ympäristöstä.
setup()suoritetaan ennen jokaista yksittäistä@test-lohkoa.teardown()suoritetaan jokaisen yksittäisen@test-lohkon jälkeen, vaikka testi epäonnistuisi.- Yleisiä käyttötarkoituksia ovat väliaikaisten hakemistojen luominen, ympäristömuuttujien asettaminen ja väliaikaisten tiedostojen poistaminen testin jälkeen.
#!/usr/bin/env bats
load '../lib/fileutils.sh'
setup() {
# Create a fresh temp directory before every test
TEST_DIR=$(mktemp -d)
export TEST_DIR
}
teardown() {
# Always clean up, even on test failure
rm -rf "$TEST_DIR"
}
@test "write_file creates a file with correct content" {
run write_file "$TEST_DIR/hello.txt" "hello world"
assert_success
[ -f "$TEST_DIR/hello.txt" ]
[ "$(cat "$TEST_DIR/hello.txt")" = "hello world" ]
}
@test "write_file fails when directory does not exist" {
run write_file "/nonexistent/dir/file.txt" "data"
assert_failure
}setup_file ja teardown_file: testisarjan elinkaarikoukut
Joskus kallis resurssi tarvitsee valmistella vain kerran tiedostoa kohden, ei ennen jokaista testiä. Bats tarjoaa tätä varten funktiot setup_file ja teardown_file.
setup_file()suoritetaan kerran ennen kaikkia tiedoston testejä.teardown_file()suoritetaan kerran kaikkien tiedoston testien jälkeen.- Käyttäkää
BATS_FILE_TMPDIR-muuttujaa (saatavilla automaattisesti) tietojen jakamiseensetup_file-funktion ja testien välillä — tavalliset muuttujat eivät säily alikuorien välillä.
Tyypillinen käyttötapaus on valetun palvelimen käynnistäminen tai binäärin rakentaminen kerran ja sen sulkeminen lopuksi:
#!/usr/bin/env bats
setup_file() {
# Build the project binary once for all tests in this file
make build --silent
export BINARY="$PWD/bin/myapp"
echo "Binary built: $BINARY"
}
teardown_file() {
# Remove the binary after all tests complete
rm -f "$BINARY"
echo "Cleaned up binary"
}
setup() {
# Still runs before each individual test
TEST_TMP=$(mktemp -d)
}
teardown() {
rm -rf "$TEST_TMP"
}
@test "myapp --version outputs version string" {
run "$BINARY" --version
assert_output --partial "1.0"
}Tiedostoja muokkaavien funktioiden testaaminen
Hyvin yleinen toimintamalli on testata Bash-funktioita, jotka lukevat tiedostojärjestelmästä tai kirjoittavat siihen. Keskeinen tekniikka on käyttää väliaikaisia hakemistoja (luomalla ne komennolla mktemp -d setup-funktiossa), jotta testit eivät koskaan käsittele oikeita tiedostoja eivätkä häiritse toisiaan.
- Työskennelkää aina hakemiston
$TEST_DIRsisällä (tai$BATS_TEST_TMPDIR-hakemistossa, joka on saatavilla automaattisesti Batsin uusissa versioissa). - Käyttäkää
bats-file-apukirjastoa selkeisiin tiedostoväitteisiin, kutenassert_file_existsjaassert_file_contains. - Älkää koskaan määrittäkö polkuja kiinteästi, esimerkiksi
/tmp/myfile, sillä rinnakkaiset testiajot törmäävät toisiinsa.
#!/usr/bin/env bats
load 'helpers/bats-assert/load'
load 'helpers/bats-file/load'
load '../lib/fileutils.sh'
setup() {
TEST_DIR="$BATS_TEST_TMPDIR"
}
# lib/fileutils.sh defines:
# append_line() { echo "$2" >> "$1"; }
@test "append_line adds a line to an existing file" {
echo "first line" > "$TEST_DIR/log.txt"
run append_line "$TEST_DIR/log.txt" "second line"
assert_success
assert_file_contains "$TEST_DIR/log.txt" "second line"
}
@test "append_line creates file if it does not exist" {
run append_line "$TEST_DIR/new.txt" "hello"
assert_success
assert_file_exists "$TEST_DIR/new.txt"
}Ulkoisten komentojen valeet
Funktiot kutsuvat usein ulkoisia ohjelmia, kuten curl, aws tai git. Yksikkötesteissä haluatte testata omaa logiikkaanne, ette oikeaa ulkoista komentoa. Selkein tapa toteuttaa mockaus Batsissa on määrittää setup-funktiossa komentoa samanniminen shell-funktio — se ohittaa oikean binäärin.
- Määrittäkää
setup-funktiossa esimerkiksi funktiocurl() { echo 'mocked response'; return 0; }ja viekää se ympäristöön. - Käyttäkää komentoa
export -f curl, jotta funktio näkyy komennonrunluomissa alikuorissa. - Monimutkaisemmissa tilanteissa voitte myös kirjoittaa valeen väliaikaiseen tiedostoon, joka sijaitsee
PATH-muuttujan hakemistossa.
#!/usr/bin/env bats
load 'helpers/bats-assert/load'
load '../lib/network.sh'
# lib/network.sh defines:
# fetch_status() {
# local url="$1"
# local code
# code=$(curl -s -o /dev/null -w "%{http_code}" "$url")
# echo "$code"
# }
setup() {
# Override 'curl' with a mock function
curl() {
# Simulate a 200 OK response
echo "200"
return 0
}
export -f curl
}
@test "fetch_status returns 200 when curl reports 200" {
run fetch_status "https://example.com"
assert_success
assert_output "200"
}Testien ohittaminen ja tagien käyttö
Kaikkia testejä ei aina voi suorittaa — joskus tarvitaan oikea verkkoyhteys, tietty työkalu tai tietty käyttöjärjestelmä. Bats tarjoaa skip-komennon, jolla testin voi ohittaa ehdollisesti ja informatiivisen viestin kera sen sijaan, että testi kommentoitaisiin pois tai testisarja rikottaisiin.
- Kutsukaa
skip "reason"missä tahansa@test-lohkon sisällä ohittaaksenne testin. - Ohitetut testit näkyvät tulosteessa merkintänä
S, eikä niitä lasketa epäonnistumisiksi. - Bats 1.5+ tukee tageja: merkitkää testit annotaatiolla
# bats test_tags=slow,networkja suodattakaa ne komennollabats --filter-tags network test/.
#!/usr/bin/env bats
# bats test_tags=network
@test "API returns valid JSON" {
# Skip if no internet connectivity
if ! ping -c1 -W1 8.8.8.8 &>/dev/null; then
skip "No network connection available"
fi
run curl -s "https://api.example.com/health"
assert_success
assert_output --partial '"status"'
}
# bats test_tags=unit
@test "slug function lowercases and replaces spaces" {
# Always runs — pure function, no external deps
slug() { echo "$1" | tr '[:upper:]' '[:lower:]' | tr ' ' '-'; }
run slug "Hello World"
assert_output "hello-world"
}
# Run only unit tests:
# bats --filter-tags unit test/Kokonaisen testisarjan jäsentäminen
Hyvin järjestetty Bats-projekti noudattaa ennakoitavaa hakemistorakennetta, mikä helpottaa uusien osallistujien perehdyttämistä ja integrointia CI-putkiin.
Suositeltu rakenne:
lib/— tuotannossa käytettävät Bash-funktiot (yksi tiedosto kutakin kokonaisuutta kohti:math.sh,fileutils.sh).test/— yksi.bats-tiedosto kutakin kirjastotiedostoa kohti (math.bats,fileutils.bats).test/helpers/— bats-assert, bats-file ja bats-support Git-alimoduuleina.Makefile—test-kohde, jotta osallistujat voivat suorittaa komennonmake test.
Suorittakaa koko testisarja yhdellä komennolla:
# Makefile
.PHONY: test
test:
bats test/
# Run all tests recursively (Bats 1.5+)
# bats --recursive test/
# Run a specific file
# bats test/math.bats
# Run with verbose (TAP) output for CI
# bats --tap test/
# Example directory tree:
# .
# |-- lib/
# | |-- math.sh
# | `-- fileutils.sh
# |-- test/
# | |-- helpers/
# | | |-- bats-assert/
# | | `-- bats-file/
# | |-- math.bats
# | `-- fileutils.bats
# `-- MakefileTietotesti: Bats-core-väitteet
Testatkaa, kuinka hyvin ymmärrätte Bats-coren keskeisen testausmekanismin.
Kertaus: Bashin yksikkötestaus Bats-corella
Tässä oppitunnissa opitte jäsentämään ja kirjoittamaan yksikkötestejä yksittäisille Bash-funktioille Bats-coren avulla. Tässä ovat tärkeimmät asiat:
- Testitiedoston rakenne — käyttäkää
#!/usr/bin/env bats-shebang-riviä ja kuvaavasti nimettyjä@test-lohkoja. load— lähdekoodatkaa kirjastotiedostonne, jotta funktiot ovat testeissä käytettävissä ilman kopiointia ja liittämistä.run+$status+$output— keskeinen kolmikko; käyttäkää ainarun-komentoa tulosten tallentamiseen ilman, että testi epäonnistuu heti.- bats-assert — suosikaa luettavien virheilmoitusten vuoksi funktioita
assert_success,assert_failurejaassert_outputraakojen[ ]-väitteiden sijaan. setup/teardown— suoritetaan ennen jokaista testiä ja sen jälkeen;setup_file/teardown_filesuoritetaan kerran tiedostoa kohti.- Mockaus — ohittakaa ulkoiset komennot samannimisillä shell-funktioilla, jotka viedään ympäristöön komennolla
export -f. skip— ohittakaa ehdollisesti testit, jotka riippuvat käytettävissä olemattomista resursseista.- Projektin rakenne — pitäkää
lib/-,test/- jatest/helpers/-hakemistot erillään ylläpidettävyyden ja CI-integraation vuoksi.
Näiden toimintamallien ansiosta voitte soveltaa Bash-projekteihinne samaa testauskuria kuin mihin tahansa nykyaikaiseen ohjelmistoprojektiin.
Opi DevOps-bootcamp tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 142
- Oppitunnit
- 568
Usein kysytyt kysymykset
Onko oppitunti ”Funktioiden yksikkötestaus Bats-corella” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa DevOps-bootcamp-oppimispolun 3 oppituntia, myös oppitunnin “Funktioiden yksikkötestaus Bats-corella”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. DevOps-bootcamp-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Funktioiden yksikkötestaus Bats-corella”?
Rakenna testitiedostot, väitteet ja valmistelu- sekä purkuvaiheet yksittäisten Bash-funktioiden tarkistamista varten. Harjoittelet DevOps-bootcamp-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni DevOps-bootcamp-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin DevOps-bootcamp-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”Funktioiden yksikkötestaus Bats-corella”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä DevOps-bootcamp-oppitunnilla?
Kyllä. Jokainen DevOps-bootcamp-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Funktioiden yksikkötestaus Bats-corella
- Komentojen mallintaminen ja ulkoisten työkalujen korvaaminen
- Testiaineistot, väliaikaisympäristöt ja kattavuus
- Shell-testien suorittaminen CI-putkissa