ฟิกซ์เจอร์ สภาพแวดล้อมชั่วคราว และความครอบคลุม
สร้างฟิกซ์เจอร์ทดสอบที่แยกจากกัน และวัดว่าแบบทดสอบของคุณครอบคลุมแขนงใดของสคริปต์จริง
ฟิกซ์เจอร์ สภาพแวดล้อมชั่วคราว และความครอบคลุม เป็นบทเรียน DevOps Bootcamp ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน DevOps Bootcamp และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดฟิกซ์เจอร์และการแยกสภาพแวดล้อมจึงสำคัญ
เมื่อทดสอบสคริปต์ Bash ความเสี่ยงที่ใหญ่ที่สุดคือผลข้างเคียง: การทดสอบของคุณอาจแก้ไขไฟล์จริง ฐานข้อมูลจริง หรือสถานะของระบบจริงโดยไม่ได้ตั้งใจ การทดสอบที่ผ่านบนเครื่องของคุณแต่ทำให้ข้อมูลในระบบจริงเสียหาย ย่อมแย่กว่าการไม่มีการทดสอบเลย
วิธีแก้คือฟิกซ์เจอร์การทดสอบ ซึ่งเป็นสภาพแวดล้อมที่ควบคุมได้และทิ้งได้ ออกแบบให้เลียนแบบเงื่อนไขจริงโดยไม่แตะต้องสิ่งใดที่เป็นของจริง ฟิกซ์เจอร์ที่ดีช่วยให้คุณได้:
- ทำซ้ำได้ — การทดสอบให้ผลลัพธ์เดิมทุกครั้ง
- แยกจากกัน — การทดสอบไม่รบกวนกันเองหรือโฮสต์
- ปลอดภัย — การดำเนินการที่ทำลายข้อมูลจะกระทบเฉพาะข้อมูลที่ทิ้งได้
- รวดเร็ว — ไม่มีการเรียกเครือข่ายหรือการรับส่งข้อมูลปริมาณมาก เว้นแต่จำเป็นอย่างยิ่ง
ในการทดสอบ Bash ฟิกซ์เจอร์มักเป็นไดเรกทอรีชั่วคราวที่เติมด้วยไฟล์ที่ทราบแน่ชัด ไฟล์ปฏิบัติการจำลองที่วางไว้ช่วงต้นของ $PATH และตัวแปรสภาพแวดล้อมที่มีขอบเขตอยู่ในกระบวนการทดสอบ
การสร้างและล้างไดเรกทอรีชั่วคราว
รูปแบบมาตรฐานสำหรับไดเรกทอรีชั่วคราวแยกต่อการทดสอบ ใช้ mktemp -d ซึ่งจะสร้างไดเรกทอรีที่มีชื่อไม่ซ้ำกันใน /tmp และแสดงเส้นทางออกมา คุณเก็บเส้นทางนั้นไว้และลงทะเบียน trap เพื่อลบไดเรกทอรีโดยอัตโนมัติเมื่อเชลล์จบการทำงาน แม้จะจบลงเพราะข้อผิดพลาดก็ตาม
สำนวนสองบรรทัดนี้ควรปรากฏในทุกไฟล์การทดสอบที่แตะต้องระบบไฟล์:
#!/usr/bin/env bash
set -euo pipefail
# Create an isolated temp directory
TMPDIR=$(mktemp -d)
# Always clean up, even if the script exits early or errors out
trap 'rm -rf "$TMPDIR"' EXIT
echo "Working in: $TMPDIR"
# Simulate creating fixture files
mkdir -p "$TMPDIR/project/{src,tests,logs}"
echo 'version=1.2.3' > "$TMPDIR/project/.env"
echo 'Hello fixture' > "$TMPDIR/project/src/main.sh"
ls -R "$TMPDIR/project"
echo 'Temp dir will be removed automatically on exit'การจัดโครงสร้างต้นไม้ไดเรกทอรีฟิกซ์เจอร์
ฟิกซ์เจอร์ที่จัดโครงสร้างดีจะจำลองผังไดเรกทอรีที่สคริปต์ที่กำลังทดสอบคาดหวังจริง ๆ ให้มองว่าฟิกซ์เจอร์เป็นรากโครงการจำลองขนาดเล็ก ฟังก์ชันเตรียมฟิกซ์เจอร์จะสร้างผังนี้ก่อนการทดสอบแต่ละครั้ง และการล้างข้อมูลจะลบผังดังกล่าว
แนวปฏิบัติสำคัญ:
- ใช้ฟังก์ชัน
setup()ที่เฟรมเวิร์กการทดสอบเรียกก่อนการทดสอบแต่ละครั้ง - ใช้
teardown()หรือcleanup()ที่ทำงานหลังการทดสอบแต่ละครั้ง แม้การทดสอบจะล้มเหลว - ทำให้ไฟล์ฟิกซ์เจอร์มีขนาดเล็กที่สุด — มีเฉพาะสิ่งที่สคริปต์อ่านจริง ๆ
- ตั้งชื่อไฟล์ฟิกซ์เจอร์ให้สื่อความหมาย เพื่อให้วินิจฉัยความล้มเหลวได้ง่าย
#!/usr/bin/env bash
# fixture_helpers.bash — source this from your test files
FIXTURE_ROOT=''
setup_fixture() {
FIXTURE_ROOT=$(mktemp -d)
# Build the directory tree the deploy script expects
mkdir -p "$FIXTURE_ROOT"/{dist,config,logs}
echo '{"version":"2.0"}' > "$FIXTURE_ROOT/config/app.json"
echo 'console.log("app")' > "$FIXTURE_ROOT/dist/index.js"
touch "$FIXTURE_ROOT/logs/.gitkeep"
export FIXTURE_ROOT
echo "[setup] Fixture ready at $FIXTURE_ROOT"
}
teardown_fixture() {
if [[ -n "$FIXTURE_ROOT" && -d "$FIXTURE_ROOT" ]]; then
rm -rf "$FIXTURE_ROOT"
echo '[teardown] Fixture removed'
fi
}
# Self-test
setup_fixture
ls "$FIXTURE_ROOT"
teardown_fixtureการจำลองไฟล์ปฏิบัติการด้วย PATH ปลอม
สคริปต์ Bash จำนวนมากเรียกใช้เครื่องมือภายนอก เช่น curl, aws, docker หรือ git ในการทดสอบ คุณไม่ต้องการเชื่อมต่อบริการจริง จึงแทนที่เครื่องมือเหล่านั้นด้วยไฟล์ปฏิบัติการปลอม
เทคนิคนี้ทำได้ง่าย:
- สร้างไดเรกทอรีชั่วคราว
bin/ภายในฟิกซ์เจอร์ - เขียนสคริปต์เชลล์ขนาดเล็กที่มีชื่อเดียวกับเครื่องมือจริงไว้ในไดเรกทอรีนั้น
- เพิ่มไดเรกทอรีดังกล่าวไว้หน้าสุดของ
$PATHก่อนเรียกใช้สคริปต์ที่กำลังทดสอบ
เนื่องจากระบบค้นหา $PATH จากซ้ายไปขวา ไฟล์ปลอมจึงถูกเลือกใช้ และไบนารีจริงจะไม่ถูกเรียกใช้
#!/usr/bin/env bash
set -euo pipefail
FIXTURE=$(mktemp -d)
trap 'rm -rf "$FIXTURE"' EXIT
# Create a fake 'curl' that records calls and returns canned data
FAKE_BIN="$FIXTURE/bin"
mkdir -p "$FAKE_BIN"
cat > "$FAKE_BIN/curl" << 'SCRIPT'
#!/usr/bin/env bash
# Log every argument for later inspection
echo "curl $*" >> "$FIXTURE_BIN_LOG"
# Return a canned HTTP 200 response body
echo '{"status":"ok","id":42}'
SCRIPT
chmod +x "$FAKE_BIN/curl"
# Export the log path so the fake can find it
export FIXTURE_BIN_LOG="$FIXTURE/curl_calls.log"
# Prepend fake bin directory to PATH
export PATH="$FAKE_BIN:$PATH"
# Now any call to 'curl' hits our fake
curl -s https://api.example.com/health
curl -X POST https://api.example.com/deploy
echo '--- Recorded curl calls ---'
cat "$FIXTURE_BIN_LOG"การเก็บและตรวจสอบผลลัพธ์ของคำสั่ง
ฟิกซ์เจอร์จะมีประโยชน์ก็ต่อเมื่อคุณสามารถตรวจสอบสิ่งที่สคริปต์ทำได้ รูปแบบมาตรฐานมีดังนี้:
- เก็บ stdout/stderr ลงในตัวแปรด้วย
$()หรือการแทนที่กระบวนการ - ตรวจสอบไฟล์บันทึกที่ไบนารีปลอมเขียนไว้
- ตรวจสอบรหัสจบการทำงานอย่างชัดเจนด้วย
$?หรือตรรกะเงื่อนไข - ตรวจสอบว่าไฟล์บางไฟล์ถูกสร้าง แก้ไข หรือไม่มีการแตะต้อง
การเขียนตัวช่วยตรวจสอบขนาดเล็กที่มุ่งเน้นเฉพาะเรื่องจะทำให้การทดสอบอ่านง่าย และให้ข้อความความล้มเหลวที่แม่นยำเมื่อเกิดข้อผิดพลาด
#!/usr/bin/env bash
set -euo pipefail
# Minimal assertion helpers
assert_eq() {
local desc="$1" expected="$2" actual="$3"
if [[ "$expected" == "$actual" ]]; then
echo "PASS: $desc"
else
echo "FAIL: $desc"
echo " expected: $expected"
echo " actual: $actual"
return 1
fi
}
assert_file_exists() {
local desc="$1" file="$2"
if [[ -f "$file" ]]; then
echo "PASS: $desc"
else
echo "FAIL: $desc — file not found: $file"
return 1
fi
}
assert_contains() {
local desc="$1" needle="$2" haystack="$3"
if [[ "$haystack" == *"$needle"* ]]; then
echo "PASS: $desc"
else
echo "FAIL: $desc — '$needle' not found in output"
return 1
fi
}
# Demo usage
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
echo 'hello world' > "$TMPDIR/greeting.txt"
OUT=$(cat "$TMPDIR/greeting.txt")
assert_eq 'file content matches' 'hello world' "$OUT"
assert_file_exists 'greeting file created' "$TMPDIR/greeting.txt"
assert_contains 'output has hello' 'hello' "$OUT"การกำหนดขอบเขตตัวแปรสภาพแวดล้อมในการทดสอบ
สคริปต์มักอ่านค่าจากตัวแปรสภาพแวดล้อม เช่น $HOME, $CONFIG_PATH หรือ $DATABASE_URL ในการทดสอบ คุณต้องแทนที่ค่าเหล่านี้โดยไม่ทำให้สภาพแวดล้อมจริงปนเปื้อน
แนวทางที่ปลอดภัยที่สุดคือเรียกใช้สคริปต์ที่กำลังทดสอบในเชลล์ย่อย โดยมีเฉพาะตัวแปรที่คุณกำหนดไว้อย่างชัดเจน คำสั่ง env ช่วยให้คุณล้างตัวแปรสภาพแวดล้อมทั้งหมดแล้วเพิ่มกลับเฉพาะค่าที่ต้องการได้:
env -i VAR=val ./script.sh— สภาพแวดล้อมที่สะอาดทั้งหมด(export VAR=val; ./script.sh)— เชลล์ย่อยสืบทอดสภาพแวดล้อมของกระบวนการแม่ พร้อมค่าที่คุณแทนที่
การใช้เชลล์ย่อยยังหมายความว่า หากสคริปต์เปลี่ยนค่า $IFS, $PWD หรือสถานะส่วนกลางอื่น ๆ การเปลี่ยนแปลงเหล่านั้นจะไม่รั่วไหลกลับไปยังตัวเรียกใช้การทดสอบ
#!/usr/bin/env bash
set -euo pipefail
FIXTURE=$(mktemp -d)
trap 'rm -rf "$FIXTURE"' EXIT
# Write a tiny script under test that reads env vars
cat > "$FIXTURE/deploy.sh" << 'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail
ENV_NAME=${DEPLOY_ENV:-unknown}
CFG=${CONFIG_DIR:-/etc/app}
echo "Deploying to $ENV_NAME using config from $CFG"
SCRIPT
chmod +x "$FIXTURE/deploy.sh"
echo '--- Test 1: staging env ---'
# Run in a clean subshell with explicit vars
(
export DEPLOY_ENV=staging
export CONFIG_DIR="$FIXTURE/config"
"$FIXTURE/deploy.sh"
)
echo '--- Test 2: production env ---'
(
export DEPLOY_ENV=production
export CONFIG_DIR=/etc/prod-config
"$FIXTURE/deploy.sh"
)
echo '--- Test 3: defaults ---'
# No env vars set — script should use its own defaults
env -i PATH="$PATH" "$FIXTURE/deploy.sh"บทนำสู่ kcov สำหรับการวัดความครอบคลุมของ Bash
ความครอบคลุมตอบคำถามว่า การทดสอบเรียกใช้บรรทัด (และแขนง) ใดของสคริปต์จริงบ้าง ตัวเลขความครอบคลุมสูงไม่ได้รับประกันความถูกต้อง แต่ค่าต่ำจะเผยให้เห็นเส้นทางที่ยังไม่ได้ทดสอบและอาจมีข้อบกพร่องซ่อนอยู่
เครื่องมือหลักสำหรับวัดความครอบคลุมของ Bash คือ kcov เครื่องมือนี้ทำงานโดยติดตั้งเครื่องมือวัดในสคริปต์ระดับ OS ด้วย PTRACE (Linux) หรือ dtrace (macOS) จึงไม่จำเป็นต้องแก้ไขซอร์สโค้ด และจะสร้างรายงาน HTML ที่แสดงบรรทัดสีแดง (ยังไม่ครอบคลุม) และสีเขียว (ครอบคลุมแล้ว)
การใช้งานพื้นฐาน:
kcov --include-path=./src coverage-out/ ./src/myscript.sh- เปิด
coverage-out/index.htmlในเบราว์เซอร์เพื่อตรวจสอบผลลัพธ์ - ใน CI ให้วิเคราะห์
coverage-out/myscript.sh/coverage.jsonเพื่ออ่านเปอร์เซ็นต์ในรูปแบบที่เครื่องอ่านได้
หมายเหตุ: ต้องติดตั้ง kcov แยกต่างหาก (brew install kcov บน macOS และ apt install kcov บน Ubuntu 20.04 ขึ้นไป)
การเรียกใช้ kcov กับสคริปต์จริง
ตัวอย่างแบบครบตั้งแต่ต้นจนจบนี้แสดงสคริปต์ที่พร้อมนำไปใช้งาน การทดสอบที่เรียกใช้สคริปต์นั้น และการเรียกใช้ kcov เพื่อวัดความครอบคลุม โปรดสังเกตว่าไดเรกทอรีผลลัพธ์แยกตามการทดสอบ เพื่อให้คุณรวมผลจากการทดสอบหลายครั้งได้ในภายหลัง
#!/usr/bin/env bash
# This demo shows the *structure* of a kcov workflow.
# It will not run kcov itself (not guaranteed to be installed),
# but the script under test and test runner are fully runnable.
set -euo pipefail
FIXTURE=$(mktemp -d)
trap 'rm -rf "$FIXTURE"' EXIT
# 1. Script under test
cat > "$FIXTURE/process.sh" << 'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail
INPUT="$1"
if [[ ! -f "$INPUT" ]]; then
echo "ERROR: file not found" >&2
exit 1
fi
LINE_COUNT=$(wc -l < "$INPUT")
if (( LINE_COUNT == 0 )); then
echo "WARNING: file is empty"
else
echo "Processed $LINE_COUNT lines"
fi
SCRIPT
chmod +x "$FIXTURE/process.sh"
# 2. Happy path test (exercises line 6 and 11)
echo -e 'one\ntwo\nthree' > "$FIXTURE/data.txt"
OUT=$("$FIXTURE/process.sh" "$FIXTURE/data.txt")
echo "Happy path: $OUT"
# 3. Empty file test (exercises line 9)
touch "$FIXTURE/empty.txt"
OUT=$("$FIXTURE/process.sh" "$FIXTURE/empty.txt")
echo "Empty file: $OUT"
# 4. Missing file test (exercises line 5-6)
if ! OUT=$("$FIXTURE/process.sh" "$FIXTURE/missing.txt" 2>&1); then
echo "Missing file (expected error): $OUT"
fi
# To measure coverage, wrap each call with kcov:
# kcov --include-path="$FIXTURE" "$FIXTURE/cov/happy" "$FIXTURE/process.sh" ...
# kcov --merge "$FIXTURE/cov/all" "$FIXTURE/cov/happy" "$FIXTURE/cov/empty"การรวมความครอบคลุมจากการทดสอบหลายครั้ง
การทดสอบเพียงครั้งเดียวแทบไม่ครอบคลุมทุกแขนง คุณจึงเรียกใช้การทดสอบหลายครั้ง โดยแต่ละครั้งใช้ไดเรกทอรีผลลัพธ์ความครอบคลุมของตนเอง แล้วจึงรวมผลเข้าด้วยกัน แฟล็ก --merge ของ kcov จะรวมการเรียกใช้หลายครั้งเป็นรายงานแบบรวมหนึ่งเดียว
รูปแบบทั่วไปในไปป์ไลน์ CI:
- เรียกใช้การทดสอบ A → ส่งผลลัพธ์ไปที่
cov/test_a/ - เรียกใช้การทดสอบ B → ส่งผลลัพธ์ไปที่
cov/test_b/ - รวมผล →
kcov --merge cov/all/ cov/test_a/ cov/test_b/ - วิเคราะห์
cov/all/<script>/coverage.jsonเพื่อรับเปอร์เซ็นต์สุดท้าย
คุณยังสามารถกำหนดเกณฑ์ขั้นต่ำและทำให้การสร้าง CI ล้มเหลวหากความครอบคลุมลดต่ำกว่าเกณฑ์ดังกล่าวได้:
#!/usr/bin/env bash
# extract_coverage.sh — parse kcov JSON and fail below threshold
set -euo pipefail
MIN_COVERAGE=80 # percent
COV_JSON="${1:-coverage-out/myscript.sh/coverage.json}"
if [[ ! -f "$COV_JSON" ]]; then
echo "ERROR: coverage JSON not found at $COV_JSON" >&2
exit 1
fi
# kcov JSON contains a key like: "percent_covered": "87.50"
PERCENT=$(grep -oP '"percent_covered":\s*"\K[0-9.]+' "$COV_JSON")
PERCENT_INT=${PERCENT%%.*} # truncate decimal
echo "Coverage: ${PERCENT}% (minimum: ${MIN_COVERAGE}%)"
if (( PERCENT_INT < MIN_COVERAGE )); then
echo "FAIL: coverage ${PERCENT}% is below threshold ${MIN_COVERAGE}%" >&2
exit 1
fi
echo "PASS: coverage threshold met"ความครอบคลุมแขนงเทียบกับความครอบคลุมบรรทัด
คุณจะพบตัวชี้วัดความครอบคลุมหลักอยู่สองประเภท:
- ความครอบคลุมบรรทัด — บรรทัดนี้ถูกเรียกใช้หรือไม่ ง่ายต่อการทำให้ตัวเลขดูดีเกินจริง: การทดสอบเพียงครั้งเดียวอาจแตะต้องหลายบรรทัด แต่พลาดเส้นทางเงื่อนไขที่สำคัญ
- ความครอบคลุมแขนง — แต่ละแขนงของ
if,caseและ&&/||ถูกเลือกใช้หรือไม่ ตัวชี้วัดนี้สะท้อนผลได้ดีกว่ามาก และต้องมีการทดสอบทั้งด้านจริงและด้านเท็จของทุกการตัดสินใจ
kcov รายงานทั้งสองค่า ข้อสังเกตสำคัญคือ ความครอบคลุมบรรทัด 100% ไม่ได้หมายความว่าความครอบคลุมแขนงจะเป็น 100% ลองพิจารณาสคริปต์นี้ การทดสอบเพียงครั้งเดียวที่ใช้ไฟล์ไม่ว่างจะครอบคลุมทุกบรรทัด แต่จะไม่เคยเข้าถึงแขนงไฟล์ว่าง (บรรทัดที่ 9 ด้านล่าง):
#!/usr/bin/env bash
# Illustrates line vs branch coverage gap
set -euo pipefail
check_file() {
local f="$1"
if [[ -f "$f" ]]; then # branch A (true) OR branch B (false)
local lines
lines=$(wc -l < "$f")
if (( lines > 0 )); then # branch C (true) OR branch D (false)
echo "File has $lines lines"
else
echo "File is empty" # branch D — unreached if only tested with non-empty file
fi
else
echo "File missing" # branch B — unreached if only tested with existing file
fi
}
# Only one test: covers lines 5-10 (4 of 6 branches)
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
echo 'data' > "$TMPDIR/sample.txt"
check_file "$TMPDIR/sample.txt"
# To reach 100% branch coverage you also need:
# check_file "/nonexistent/path"
# check_file "$TMPDIR/empty.txt" (after: touch "$TMPDIR/empty.txt")ผสาน Fixture และ Coverage ใน CI
เมื่อนำทุกอย่างมารวมกัน: pipeline CI ที่มีความทนทานสำหรับโครงการ Bash จะรวมการตั้งค่า fixture การเรียกใช้ test ภายใต้ kcov การผสานผล และการตรวจสอบค่าขั้นต่ำไว้ในสคริปต์เดียว สคริปต์นี้จะเป็นจุดเริ่มต้นของ CI — ใช้คำสั่งเดียวเพื่อเรียกใช้ทุกอย่าง
หลักการออกแบบสำหรับตัวเรียกใช้ test ของ CI:
- test แต่ละกรณีเรียกใช้
setup_fixtureและลงทะเบียนteardown_fixtureผ่านtrap - เรียกใช้สคริปต์ที่กำลังทดสอบด้วย
$PATHจำลองและตัวแปรสภาพแวดล้อมที่จำกัดขอบเขต - kcov ครอบการเรียกใช้แต่ละครั้งและเขียนผลลงในไดเรกทอรีย่อยที่มีหมายเลขกำกับ
- หลังจาก test ทั้งหมดเสร็จสิ้น kcov จะผสานผล และสคริปต์ตรวจสอบค่าขั้นต่ำจะเป็นตัวตัดสินว่าจะให้ build ผ่านหรือไม่
- ตัวเรียกใช้ CI จะจบการทำงานด้วยค่าที่ไม่ใช่ศูนย์ หาก test ใด ๆ หรือตัวตรวจสอบ coverage ล้มเหลว
#!/usr/bin/env bash
# ci_runner.sh — full fixture + coverage pipeline entry point
set -euo pipefail
SRC="./src/deploy.sh"
COV_ROOT="$(mktemp -d)/coverage"
trap 'rm -rf "$COV_ROOT"' EXIT
mkdir -p "$COV_ROOT"
PASS=0
FAIL=0
RUN_NUM=0
run_test() {
local name="$1" test_fn="$2"
local fixture
fixture=$(mktemp -d)
local cov_out="$COV_ROOT/run_$((++RUN_NUM))"
if (
trap 'rm -rf "$fixture"' EXIT
export FIXTURE="$fixture"
# Fake bin directory shadowing real tools
mkdir -p "$fixture/bin"
export PATH="$fixture/bin:$PATH"
"$test_fn" "$fixture"
); then
echo "PASS: $name"
(( PASS++ )) || true
else
echo "FAIL: $name"
(( FAIL++ )) || true
fi
}
# Example test function
test_happy_path() {
local fx="$1"
mkdir -p "$fx/dist"
echo 'app.js' > "$fx/dist/index.js"
# Would normally run: kcov "$cov_out" "$SRC" --env=staging "$fx"
echo "[test] happy path executed in $fx"
}
run_test 'happy_path' test_happy_path
echo "Results: $PASS passed, $FAIL failed"
(( FAIL == 0 ))ตรวจสอบความรู้: เทคนิค PATH จำลอง
ทดสอบความเข้าใจของคุณเกี่ยวกับเทคนิค PATH จำลองที่ใช้ใน fixture สำหรับ test ของ Bash
ทบทวน: Fixture สภาพแวดล้อมชั่วคราว และ Coverage
บทเรียนนี้ครอบคลุมชุดเครื่องมือทั้งหมดสำหรับการทดสอบ Bash ที่น่าเชื่อถือและแยกออกจากกัน:
- ไดเรกทอรีชั่วคราว —
mktemp -dร่วมกับtrap ... EXITรับประกันการล้างข้อมูลโดยอัตโนมัติ ไม่ว่า test จะจบลงอย่างไร - โครงสร้าง Fixture — คู่
setup_fixture/teardown_fixtureจะสร้างและลบทรีไดเรกทอรีขนาดเล็กที่จำลองอินพุตจริงของสคริปต์ - PATH จำลอง — วางโปรแกรมปฏิบัติการจำลองไว้ใน
$FIXTURE/bin/และเพิ่มไว้หน้าสุดของ$PATHเพื่อดักการเรียกใช้curl,aws,dockerหรือเครื่องมือภายนอกใด ๆ โดยไม่แตะต้องไบนารีของระบบ - การจำกัดขอบเขตสภาพแวดล้อม — เรียกใช้สคริปต์ที่กำลังทดสอบใน subshell (
()หรือenv -i) เพื่อไม่ให้ตัวแปรที่เปลี่ยนแปลงรั่วไหลกลับไปยังตัวเรียกใช้ test - การยืนยันผล — ฟังก์ชันตัวช่วยขนาดเล็ก (
assert_eq,assert_file_exists,assert_contains) จะแสดงผลผ่าน/ไม่ผ่านที่เข้าใจง่ายและข้อความแสดงข้อผิดพลาดที่มีความหมาย - Coverage ด้วย kcov — ครอบการเรียกใช้สคริปต์โดยไม่ต้องแก้ไขซอร์ส และสร้างรายงาน HTML กับ JSON สำหรับ coverage ระดับบรรทัดและสาขา
- การผสานและค่าขั้นต่ำ — รวมการเรียกใช้ kcov หลายครั้งด้วย
--mergeแยกวิเคราะห์ JSON และทำให้ CI ไม่ผ่านหาก coverage ลดลงต่ำกว่าค่าขั้นต่ำที่กำหนด - Coverage ระดับสาขากับระดับบรรทัด — ควรตั้งเป้า coverage ระดับสาขาเสมอ เพราะ coverage ระดับบรรทัดเพียงอย่างเดียวอาจพลาดเส้นทางเงื่อนไขทั้งหมดบางเส้นทางและทำให้เกิดความมั่นใจที่ผิดพลาด
ด้วยเทคนิคเหล่านี้ test ของ Bash จะเข้มงวดไม่แพ้ test ของภาษาแบบคอมไพล์ใด ๆ
คำถามที่พบบ่อย
บทเรียน “ฟิกซ์เจอร์ สภาพแวดล้อมชั่วคราว และความครอบคลุม” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ฟิกซ์เจอร์ สภาพแวดล้อมชั่วคราว และความครอบคลุม” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส DevOps Bootcamp ให้อัปเกรดเป็น CoddyKit PRO คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ฟิกซ์เจอร์ สภาพแวดล้อมชั่วคราว และความครอบคลุม”
สร้างฟิกซ์เจอร์ทดสอบที่แยกจากกัน และวัดว่าแบบทดสอบของคุณครอบคลุมแขนงใดของสคริปต์จริง คุณปฏิบัติ DevOps Bootcamp ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน DevOps Bootcamp หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน DevOps Bootcamp บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ฟิกซ์เจอร์ สภาพแวดล้อมชั่วคราว และความครอบคลุม” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน DevOps Bootcamp นี้ได้ไหม
ได้ บทเรียน DevOps Bootcamp ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การทดสอบฟังก์ชันแบบยูนิตด้วย Bats-core
- การจำลองคำสั่งและการทำเครื่องมือภายนอกเป็นสตับ
- ฟิกซ์เจอร์ สภาพแวดล้อมชั่วคราว และความครอบคลุม
- การเรียกใช้การทดสอบ Shell ในไปป์ไลน์ CI