0Pricing
DevOps Bootcamp · Ders

Bats-core ile Fonksiyonları Birim Testine Tabi Tutma

Tek tek Bash fonksiyonlarını doğrulamak için test dosyalarını, doğrulamaları ve kurulum/temizleme adımlarını yapılandırın.

Bats-core ile Fonksiyonları Birim Testine Tabi Tutma, CoddyKit'te ücretsiz bir DevOps Bootcamp dersidir. Bu, 4 dersinin 1. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, DevOps Bootcamp öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. DevOps Bootcamp kursu toplamda 4 dersten oluşur.

Bats-core Nedir ve Neden Kullanılır?

Bats-core (Bash Otomatik Test Sistemi), Bash için fiilî birim testi çatısıdır. Kabuk işlevleriniz ve betikleriniz için, Java ile JUnit veya Python ile pytest kullanırken olduğu gibi, düzenli ve tekrarlanabilir testler yazmanızı sağlar.

  • Her test, insanların okuyabileceği bir açıklamaya sahip bir @test bloğudur.
  • İçindeki her komut 0 çıkış kodunu döndürdüğünde test başarılı olur.
  • İlk sıfır olmayan çıkış kodunda veya başarısız bir doğrulamada test başarısız olur.
  • Çıktı TAP ile uyumludur; bu nedenle sürekli tümleştirme sistemleri (GitHub Actions, Jenkins, GitLab CI) bunu doğrudan anlayabilir.

Paket yöneticiniz aracılığıyla kurun veya depoyu kopyalayın:

# 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

İlk Bats Test Dosyanız

Bir Bats test dosyasının uzantısı .bats olur ve özel bir shebang ile başlar. Temel yapı taşı, bir açıklama metninin ve komut bloklarının izlediği @test yönergesidir.

  • #!/usr/bin/env bats shebang'i, kabuğa dosyanın nasıl çalıştırılacağını bildirir.
  • Her @test bloğu bağımsız bir test durumudur.
  • Tek bir dosyayı bats my_tests.bats ile veya bir dizinin tamamını bats test/ ile çalıştırabilirsiniz.

Aşağıda bir Bats test dosyasının en temel yapısı gösterilmiştir:

#!/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
}

'load' ile Test Edilen İşlevi Yükleme

Gerçek projelerde Bash işlevleriniz test dosyasının içinde değil, kitaplık dosyalarında bulunur. Bats, test dosyasının dizinine göre dış dosyaları kaynak olarak eklemek için load yardımcı işlevini sağlar.

  • load '../lib/math.sh', her test çalıştırılmadan önce dosyayı kaynak olarak ekler.
  • Yüklendikten sonra, bu dosyada tanımlanan tüm işlevler test bloklarınızda kullanılabilir.
  • Temiz bir ayrım sağlamak için kitaplık işlevlerinizi lib/ dizininde, testlerinizi ise test/ dizininde tutun.

Örnek proje düzeni ve buna karşılık gelen test:

# 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" ]
}

Temel Doğrulamalar: run, $status, $output

run komutu, Bats testlerinin merkezinde yer alır. Bir komutu doğrudan çalıştırmak yerine run ile sarmaladığınızda, testin hemen başarısız olmasına neden olmadan çıkış kodunu ve çıktısını yakalarsınız.

  • $status — son run komutunun çıkış kodunu tutar.
  • $output — son run komutunun birleştirilmiş standart çıktısını tutar.
  • $lines — her öğesinin bir çıktı satırı olduğu bir dizidir (${lines[0]}, ${lines[1]} vb.).

Bu sayede hem başarılı hem de başarısız durumları doğrulayabilirsiniz:

#!/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"* ]]
}

Anlatım Gücü Yüksek Doğrulamalar için bats-assert Kullanımı

Yerleşik [ ] doğrulamaları çalışır, ancak başarısızlık mesajları yetersizdir. bats-assert yardımcı kitaplığı, tam olarak neyin yanlış gittiğini yazdıran, açıklayıcı doğrulama işlevleri sağlar.

  • assert_success — $status değerinin 0 olduğunu doğrular.
  • assert_failure — $status değerinin sıfır olmadığını doğrular.
  • assert_output — $output değerinin verilen metne eşit olduğunu doğrular.
  • assert_output --partial — çıktının alt dizeyi içerdiğini doğrular.
  • refute_output --partial — çıktının alt dizeyi içermediğini doğrular.

bats-core/bats-assert öğesini bir test/helpers/ klasörüne kopyalayarak kurun, ardından yükleyin:

#!/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 ve teardown: Test Yaşam Döngüsü Kancaları

Bats, her testin çevresinde otomatik olarak çalışan iki özel işlev ( setup ve teardown ) sağlar. Her testin bilinen bir ortamda başlaması için paylaşılan durumu hazırlamak ve temizlemek amacıyla bunları kullanın.

  • setup(), her bir @test bloğundan önce çalışır.
  • teardown(), test başarısız olsa bile her bir @test bloğundan sonra çalışır.
  • Yaygın kullanımlar: geçici dizinler oluşturmak, ortam değişkenlerini ayarlamak ve testten sonra geçici dosyaları kaldırmak.
#!/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 ve teardown_file: Test Paketi Düzeyi Kancaları

Bazen maliyetli kaynakları her bir testten önce değil, dosya başına yalnızca bir kez hazırlamanız gerekir. Bats bu amaçla setup_file ve teardown_file işlevlerini sağlar.

  • setup_file(), dosyadaki tüm testlerden önce bir kez çalışır.
  • teardown_file(), dosyadaki tüm testlerden sonra bir kez çalışır.
  • setup_file ile testleriniz arasında veri paylaşmak için otomatik olarak kullanılabilen BATS_FILE_TMPDIR değişkenini kullanın; normal değişkenler alt kabuklar arasında kalıcı olmaz.

Tipik kullanım: bir sahte sunucuyu başlatmak veya bir ikili dosyayı bir kez oluşturmak, ardından en sonda durdurmak:

#!/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"
}

Dosyaları Değiştiren İşlevleri Test Etme

Çok yaygın bir yaklaşım, dosya sisteminden okuyan veya dosya sistemine yazan Bash işlevlerini test etmektir. Temel teknik, geçici dizinler kullanmaktır (setup içinde mktemp -d aracılığıyla); böylece testler gerçek dosyalara hiçbir zaman dokunmaz ve birbirlerini etkilemez.

  • Her zaman $TEST_DIR içinde (veya yeni Bats sürümlerinde otomatik olarak kullanılabilen $BATS_TEST_TMPDIR içinde) çalışın.
  • assert_file_exists ve assert_file_contains gibi temiz dosya doğrulamaları için bats-file yardımcı kitaplığını kullanın.
  • /tmp/myfile gibi yolları asla sabit kodlamayın; paralel test çalıştırmaları çakışır.
#!/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"
}

Harici Komutları Taklit Etme

İşlevler genellikle curl, aws veya git gibi harici programları çağırır. Birim testlerinde gerçek harici komutu değil, kendi mantığınızı test etmek istersiniz. Bats'te taklit etmenin en temiz yolu, setup içinde komutla aynı ada sahip bir kabuk işlevi tanımlamaktır; bu işlev gerçek ikili dosyaya öncelik kazanır.

  • setup içinde curl() { echo 'mocked response'; return 0; } gibi bir işlev tanımlayın ve dışa aktarın.
  • run tarafından oluşturulan alt kabuklarda işlevin görülebilmesi için export -f curl kullanın.
  • Daha karmaşık durumlarda taklidi PATH üzerindeki geçici bir dosyaya da yazabilirsiniz.
#!/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"
}

Testleri Atlama ve Etiketleme

Her test her zaman çalıştırılamaz; bazen gerçek bir ağ bağlantısına, belirli bir araca veya belirli bir işletim sistemine ihtiyaç duyarsınız. Bats, testi yorum satırına dönüştürmek veya test paketini bozmak yerine, bilgilendirici bir mesajla koşullu olarak atlamak için skip sağlar.

  • Bir testi atlamak için @test bloğunun içinde herhangi bir yerde skip "reason" çağrısını yapın.
  • Atlanan testler çıktıda S olarak görünür ve başarısızlık sayılmaz.
  • Bats 1.5 ve sonraki sürümler etiketleri destekler: testlere # bats test_tags=slow,network ile açıklama ekleyin ve bats --filter-tags network test/ ile filtreleyin.
#!/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/

Eksiksiz Bir Test Paketi Yapılandırma

İyi düzenlenmiş bir Bats projesi, öngörülebilir bir dizin düzenini izler; bu da yeni katkıcıların projeye dahil olmasını ve sürekli tümleştirme işlem hatlarıyla tümleştirmeyi kolaylaştırır.

Önerilen yapı:

  • lib/ — üretim Bash işlevleri (her amaç için bir dosya: math.sh, fileutils.sh).
  • test/ — her kitaplık dosyası için bir .bats dosyası (math.bats, fileutils.bats).
  • test/helpers/ — git alt modülleri olarak bats-assert, bats-file ve bats-support.
  • Makefile — katkıcıların yalnızca make test çalıştırabilmesi için bir test hedefi.

Tüm test paketini tek komutla çalıştırın:

# 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

Bilgi Kontrolü: Bats-core Doğrulamaları

Temel Bats-core test mekanizmasını anlayıp anlamadığınızı test edin.

Özet: Bats-core ile Bash Birim Testleri

Bu derste Bats-core kullanarak tek tek Bash işlevleri için birim testlerini nasıl yapılandıracağınızı ve yazacağınızı öğrendiniz. Temel çıkarımlar şunlardır:

  • Test dosyası yapısı — #!/usr/bin/env bats shebang'ini ve açıklayıcı adlara sahip @test bloklarını kullanın.
  • load — kopyala-yapıştır yapmadan işlevlerin testlerde kullanılabilmesi için kitaplık dosyalarınızı kaynak olarak ekleyin.
  • run + $status + $output — temel üçlüdür; sonuçları testin hemen başarısız olmasına neden olmadan yakalamak için her zaman run kullanın.
  • bats-assert — okunabilir başarısızlık mesajları için ham [ ] yerine assert_success, assert_failure ve assert_output kullanmayı tercih edin.
  • setup / teardown — her testten önce/sonra çalışır; setup_file / teardown_file dosya başına bir kez çalışır.
  • Taklit etme — harici komutları, export -f ile dışa aktarılan aynı adlı kabuk işlevleriyle gölgeleyin.
  • skip — kullanılamayan kaynaklara bağlı testleri koşullu olarak atlayın.
  • Proje düzeni — sürdürülebilirlik ve sürekli tümleştirme için lib/, test/ ve test/helpers/ dizinlerini ayrı tutun.

Bu kalıplar, Bash projelerinize her modern yazılım projesine uygulayacağınız aynı test disiplinini kazandırır.

Sıkça Sorulan Sorular

“Bats-core ile Fonksiyonları Birim Testine Tabi Tutma” dersi ücretsiz mi?

Evet — “Bats-core ile Fonksiyonları Birim Testine Tabi Tutma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve DevOps Bootcamp kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. DevOps Bootcamp kursu toplamda 4 dersten oluşur.

“Bats-core ile Fonksiyonları Birim Testine Tabi Tutma” dersinde ne öğreneceğim?

Tek tek Bash fonksiyonlarını doğrulamak için test dosyalarını, doğrulamaları ve kurulum/temizleme adımlarını yapılandırın. DevOps Bootcamp ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

DevOps Bootcamp öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te DevOps Bootcamp, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 1. dersidir.

“Bats-core ile Fonksiyonları Birim Testine Tabi Tutma” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu DevOps Bootcamp dersinde kod yazıp çalıştırabilir miyim?

Evet. Her DevOps Bootcamp dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Bats-core ile Fonksiyonları Birim Testine Tabi Tutma
  2. Komutları Taklit Etme ve Dış Araçlar için Saplama Oluşturma
  3. Test Düzenekleri, Geçici Ortamlar ve Kapsam
  4. Kabuk Testlerini CI Pipeline'larında Çalıştırma
← DevOps Bootcamp Sayfasına Dön