Penguasaan Baris Perintah Linux & Penskripan Bash · Pelajaran

Pengujian Unit Fungsi dengan Bats-core

Susun fail ujian, penegasan dan persediaan/pembersihan untuk mengesahkan fungsi Bash secara individu

Pelajaran 1 daripada 413 langkah

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 @test dengan 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.y

Fail 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 bats memberitahu shell cara melaksanakan fail tersebut.
  • Setiap blok @test ialah kes ujian yang berasingan.
  • Anda boleh menjalankan satu fail dengan bats my_tests.bats atau seluruh direktori dengan bats 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 direktori test/ 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 arahan run terakhir.
  • $output — menyimpan stdout gabungan bagi arahan run terakhir.
  • $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 $status ialah 0.
  • assert_failure — menegaskan bahawa $status bukan sifar.
  • assert_output — menegaskan bahawa $output sama 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 @test individu.
  • teardown() dijalankan selepas setiap blok @test individu, 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 antara setup_file dan 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-file untuk penegasan fail yang kemas seperti assert_file_exists dan assert_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; } dalam setup dan eksportkannya.
  • Gunakan export -f curl supaya fungsi itu boleh dilihat dalam subshell yang dihasilkan oleh run.
  • Anda juga boleh menulis olok-olok itu ke fail sementara dalam PATH untuk 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 @test untuk melangkau ujian tersebut.
  • Ujian yang dilangkau dipaparkan sebagai S dalam output dan tidak dikira sebagai kegagalan.
  • Bats 1.5+ menyokong tag: anotasi ujian dengan # bats test_tags=slow,network dan tapis menggunakan bats --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 .bats bagi setiap fail pustaka (math.bats, fileutils.bats).
  • test/helpers/ — bats-assert, bats-file dan bats-support sebagai submodul git.
  • Makefile — sasaran test supaya penyumbang hanya perlu menjalankan make 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
# `-- Makefile

Semakan 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 bats dan blok @test dengan 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 gunakan run untuk menangkap hasil tanpa menyebabkan ujian gagal serta-merta.
  • bats-assert — utamakan assert_success, assert_failure dan assert_output berbanding [ ] mentah untuk mendapatkan mesej kegagalan yang mudah dibaca.
  • setup / teardown — dijalankan sebelum/selepas setiap ujian; setup_file / teardown_file dijalankan 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/ dan test/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.

Percuma untuk bermula

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 &amp; Penskripan Bash, tingkat taraf kepada CoddyKit PRO. Kursus Penguasaan Baris Perintah Linux &amp; 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 &amp; 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 &amp; Penskripan Bash?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Penguasaan Baris Perintah Linux &amp; 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 &amp; Penskripan Bash ini?

Ya. Setiap pelajaran Penguasaan Baris Perintah Linux &amp; 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

  1. Pengujian Unit Fungsi dengan Bats-core
  2. Meniru Perintah dan Menyediakan Alat Luaran Palsu
  3. Lekapan Ujian, Persekitaran Sementara dan Liputan
  4. Menjalankan Ujian Shell dalam Saluran Paip CI
← Kembali ke Penguasaan Baris Perintah Linux &amp; Penskripan Bash