Pengujian Unit Fungsi dengan Bats-core
Susun fail ujian, penegasan dan persediaan/pembersihan untuk mengesahkan fungsi Bash secara individu
Pengujian Unit Fungsi dengan Bats-core ialah pelajaran Penguasaan Baris Perintah Linux & Penskripan Bash percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Penguasaan Baris Perintah Linux & Penskripan Bash, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Penguasaan Baris Perintah Linux & Penskripan Bash merangkumi sejumlah 4 pelajaran.
Apakah Bats-core dan Mengapa Menggunakannya?
Bats-core (Bash Automated Testing System) ialah rangka kerja ujian unit de facto untuk Bash. Ia membolehkan anda menulis ujian yang berstruktur dan boleh diulang untuk fungsi serta skrip shell anda — sama seperti anda menggunakan JUnit untuk Java atau pytest untuk Python.
- Setiap ujian ialah blok
@testdengan keterangan yang mudah difahami. - Ujian lulus apabila setiap arahan di dalamnya mengembalikan kod keluar
0. - Ujian gagal pada kod keluar bukan sifar yang pertama atau apabila penegasan gagal.
- Output serasi dengan TAP, jadi sistem CI (GitHub Actions, Jenkins, GitLab CI) boleh memahaminya secara natif.
Pasang melalui pengurus pakej anda atau klon repositori:
# 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.yFail Ujian Bats Pertama Anda
Fail ujian Bats mempunyai sambungan .bats dan bermula dengan shebang khas. Blok binaan utamanya ialah arahan @test yang diikuti rentetan keterangan dan blok arahan.
- Shebang
#!/usr/bin/env batsmemberitahu shell cara melaksanakan fail tersebut. - Setiap blok
@testialah kes ujian yang berasingan. - Anda boleh menjalankan satu fail dengan
bats my_tests.batsatau seluruh direktori denganbats test/.
Berikut ialah struktur minimum untuk fail ujian Bats:
#!/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
}Memuatkan Fungsi yang Diuji dengan 'load'
Dalam projek sebenar, fungsi Bash anda berada dalam fail pustaka, bukan di dalam fail ujian itu sendiri. Bats menyediakan pembantu load untuk mendapatkan sumber fail luaran secara relatif kepada direktori fail ujian.
load '../lib/math.sh'mendapatkan sumber fail tersebut sebelum setiap ujian dijalankan.- Selepas dimuatkan, semua fungsi yang ditakrifkan dalam fail itu tersedia dalam blok ujian anda.
- Simpan fungsi pustaka anda dalam direktori
lib/dan ujian dalam direktoritest/untuk pengasingan yang kemas.
Contoh susun atur projek dan ujian yang sepadan:
# 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" ]
}Penegasan Teras: run, $status, $output
Arahan run ialah teras ujian Bats. Daripada melaksanakan arahan secara terus, membungkusnya dengan run menangkap kod keluar dan outputnya tanpa menyebabkan ujian gagal serta-merta.
$status— menyimpan kod keluar bagi arahanrunterakhir.$output— menyimpan stdout gabungan bagi arahanrunterakhir.$lines— tatasusunan yang setiap elemennya ialah satu baris output (${lines[0]},${lines[1]}, dan sebagainya).
Ini membolehkan anda membuat penegasan bagi kes berjaya dan kes gagal:
#!/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"* ]]
}Menggunakan bats-assert untuk Penegasan yang Ekspresif
Penegasan terbina dalam [ ] boleh digunakan, tetapi mesej kegagalannya kurang bermakna. Pustaka pembantu bats-assert menyediakan fungsi penegasan yang ekspresif dan memaparkan perkara yang sebenarnya berlaku.
assert_success— menegaskan bahawa$statusialah 0.assert_failure— menegaskan bahawa$statusbukan sifar.assert_output— menegaskan bahawa$outputsama dengan rentetan yang diberikan.assert_output --partial— menegaskan bahawa output mengandungi subrentetan tersebut.refute_output --partial— menegaskan bahawa output TIDAK mengandungi subrentetan tersebut.
Pasang dengan mengklon bats-core/bats-assert ke dalam folder test/helpers/, kemudian muatkannya:
#!/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 dan teardown: Cangkuk Kitar Hayat Ujian
Bats menyediakan dua fungsi khas — setup dan teardown — yang dijalankan secara automatik sebelum dan selepas setiap ujian. Gunakannya untuk menyediakan serta membersihkan keadaan dikongsi supaya setiap ujian bermula dalam persekitaran yang diketahui.
setup()dijalankan sebelum setiap blok@testindividu.teardown()dijalankan selepas setiap blok@testindividu, walaupun ujian gagal.- Kegunaan biasa: mencipta direktori sementara, menetapkan pemboleh ubah persekitaran dan membuang fail sementara selepas ujian.
#!/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 dan teardown_file: Cangkuk Peringkat Suit
Kadangkala anda hanya perlu menyediakan sumber yang mahal sekali bagi setiap fail — bukan sebelum setiap ujian. Bats menyediakan setup_file dan teardown_file untuk tujuan ini.
setup_file()dijalankan sekali sebelum semua ujian dalam fail.teardown_file()dijalankan sekali selepas semua ujian dalam fail.- Gunakan
BATS_FILE_TMPDIR(tersedia secara automatik) untuk berkongsi data antarasetup_filedan ujian anda — pemboleh ubah biasa tidak kekal merentasi subshell.
Kes penggunaan biasa: memulakan pelayan olok-olok atau membina binari sekali, kemudian menghentikannya pada akhir:
#!/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"
}Menguji Fungsi yang Mengubah Suai Fail
Corak yang sangat biasa ialah menguji fungsi Bash yang membaca daripada atau menulis ke sistem fail. Teknik utamanya ialah menggunakan direktori sementara (melalui mktemp -d dalam setup) supaya ujian tidak pernah menyentuh fail sebenar dan tidak pernah mengganggu satu sama lain.
- Sentiasa bekerja dalam
$TEST_DIR(atau$BATS_TEST_TMPDIR— tersedia secara automatik dalam Bats versi terkini). - Gunakan pustaka pembantu
bats-fileuntuk penegasan fail yang kemas sepertiassert_file_existsdanassert_file_contains. - Jangan pernah menetapkan laluan secara terus seperti
/tmp/myfile— pelaksanaan ujian selari akan bertembung.
#!/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"
}Membuat Olok-olok Arahan Luaran
Fungsi sering memanggil program luaran seperti curl, aws atau git. Dalam ujian unit, anda mahu menguji logik anda, bukan arahan luaran sebenar. Teknik olok-olok Bats yang paling kemas ialah mentakrifkan fungsi shell dengan nama yang sama seperti arahan tersebut di dalam setup — fungsi itu akan diutamakan berbanding binari sebenar.
- Takrifkan fungsi seperti
curl() { echo 'mocked response'; return 0; }dalamsetupdan eksportkannya. - Gunakan
export -f curlsupaya fungsi itu boleh dilihat dalam subshell yang dihasilkan olehrun. - Anda juga boleh menulis olok-olok itu ke fail sementara dalam
PATHuntuk senario yang lebih kompleks.
#!/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"
}Melangkau Ujian dan Menambah Tag
Tidak semua ujian boleh dijalankan pada setiap masa — kadangkala anda memerlukan sambungan rangkaian sebenar, alat tertentu atau OS tertentu. Bats menyediakan skip untuk melangkau ujian secara bersyarat dengan mesej bermaklumat, bukannya mengulasnya atau menyebabkan suit gagal.
- Panggil
skip "reason"di mana-mana sahaja dalam blok@testuntuk melangkau ujian tersebut. - Ujian yang dilangkau dipaparkan sebagai
Sdalam output dan tidak dikira sebagai kegagalan. - Bats 1.5+ menyokong tag: anotasi ujian dengan
# bats test_tags=slow,networkdan tapis menggunakanbats --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/Menstrukturkan Suit Ujian Lengkap
Projek Bats yang tersusun rapi mengikut susun atur direktori yang boleh dijangka, menjadikannya mudah untuk menerima penyumbang baharu dan disepadukan dengan saluran paip CI.
Struktur yang disyorkan:
lib/— fungsi Bash pengeluaran (satu fail bagi setiap perkara:math.sh,fileutils.sh).test/— satu fail.batsbagi setiap fail pustaka (math.bats,fileutils.bats).test/helpers/— bats-assert, bats-file dan bats-support sebagai submodul git.Makefile— sasarantestsupaya penyumbang hanya perlu menjalankanmake test.
Jalankan seluruh suit dengan satu arahan:
# 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
# `-- MakefileSemakan Pengetahuan: Penegasan Bats-core
Uji pemahaman anda tentang mekanisme ujian teras Bats-core.
Imbas Kembali: Menguji Unit Bash dengan Bats-core
Dalam pelajaran ini, anda telah mempelajari cara menstruktur dan menulis ujian unit untuk fungsi Bash individu menggunakan Bats-core. Berikut ialah perkara penting yang perlu diingati:
- Struktur fail ujian — gunakan shebang
#!/usr/bin/env batsdan blok@testdengan nama yang deskriptif. load— dapatkan sumber fail pustaka anda supaya fungsi tersedia dalam ujian tanpa menyalin dan menampal.run+$status+$output— tiga serangkai teras; sentiasa gunakanrununtuk menangkap hasil tanpa menyebabkan ujian gagal serta-merta.- bats-assert — utamakan
assert_success,assert_failuredanassert_outputberbanding[ ]mentah untuk mendapatkan mesej kegagalan yang mudah dibaca. setup/teardown— dijalankan sebelum/selepas setiap ujian;setup_file/teardown_filedijalankan sekali bagi setiap fail.- Olok-olok — lindungi arahan luaran dengan fungsi shell yang mempunyai nama sama dan dieksport menggunakan
export -f. skip— langkau secara bersyarat ujian yang bergantung pada sumber yang tidak tersedia.- Susun atur projek — asingkan
lib/,test/dantest/helpers/untuk memudahkan penyelenggaraan dan penyepaduan CI.
Corak ini memberikan projek Bash anda disiplin pengujian yang sama seperti yang anda gunakan pada mana-mana projek perisian moden.
Pelajari Bash dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 22
- Pelajaran
- 88
Soalan Lazim
Adakah pelajaran “Pengujian Unit Fungsi dengan Bats-core” percuma?
Ya — teks penuh “Pengujian Unit Fungsi dengan Bats-core” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Penguasaan Baris Perintah Linux & Penskripan Bash, tingkat taraf kepada CoddyKit PRO. Kursus Penguasaan Baris Perintah Linux & Penskripan Bash merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Pengujian Unit Fungsi dengan Bats-core”?
Susun fail ujian, penegasan dan persediaan/pembersihan untuk mengesahkan fungsi Bash secara individu Anda berlatih Penguasaan Baris Perintah Linux & Penskripan Bash menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Penguasaan Baris Perintah Linux & Penskripan Bash?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Penguasaan Baris Perintah Linux & Penskripan Bash di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.
Berapa lamakah pelajaran “Pengujian Unit Fungsi dengan Bats-core” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Penguasaan Baris Perintah Linux & Penskripan Bash ini?
Ya. Setiap pelajaran Penguasaan Baris Perintah Linux & Penskripan Bash menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Pengujian Unit Fungsi dengan Bats-core
- Meniru Perintah dan Menyediakan Alat Luaran Palsu
- Lekapan Ujian, Persekitaran Sementara dan Liputan
- Menjalankan Ujian Shell dalam Saluran Paip CI